mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
4.5 KiB

  1. /*
  2. TODO:
  3. get rid of the compiler warnings:
  4. fl_wrapper.c: In function '_Exit':
  5. fl_wrapper.c:1100: warning: 'noreturn' function does return
  6. fl_wrapper.c: In function '_exit':
  7. fl_wrapper.c:1075: warning: 'noreturn' function does return
  8. fl_wrapper.c: In function 'exit':
  9. fl_wrapper.c:1050: warning: 'noreturn' function does return
  10. maybe TODO:
  11. wrape clone(); catch termination of child process created with clone()
  12. */
  13. # if FD_TRACKER == 1
  14. /*
  15. Whenever a new file descriptor is opened, it will/should be added to the
  16. fl_wrapper-internal register, together with its current file status.
  17. Accordingly, when a file descriptor is closed, it will be removed from this
  18. register, and handle_file_access_after() will be called with the stored
  19. filename and status.
  20. */
  21. struct pid_reg
  22. {
  23. pid_t id;
  24. int executed;
  25. struct fd_reg *fd_head;
  26. struct pid_reg *next;
  27. };
  28. struct pid_reg *pid_head = 0;
  29. struct fd_reg
  30. {
  31. int fd;
  32. int closed;
  33. struct status_t status;
  34. char *filename;
  35. struct fd_reg *next;
  36. };
  37. void add_pid(pid_t pid)
  38. {
  39. struct pid_reg *newpid = malloc(sizeof(struct pid_reg));
  40. newpid->id = pid;
  41. newpid->fd_head = 0;
  42. newpid->executed = 0;
  43. newpid->next = pid_head;
  44. pid_head = newpid;
  45. # if DEBUG == 1
  46. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID %d added.\n",
  47. getpid(), pid);
  48. # endif
  49. }
  50. void add_fd(struct pid_reg *pid, int fd, const char *filename, struct status_t *status)
  51. {
  52. struct fd_reg *newfd = malloc(sizeof(struct fd_reg));
  53. newfd->fd = fd;
  54. newfd->closed = 0;
  55. newfd->status = *status;
  56. newfd->filename = strdup(filename);
  57. newfd->next = pid->fd_head;
  58. pid->fd_head = newfd;
  59. # if DEBUG == 1
  60. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d (%s) added.\n",
  61. getpid(), fd, filename);
  62. # endif
  63. }
  64. void remove_fd(struct fd_reg **fd);
  65. void remove_pid(struct pid_reg **pid)
  66. {
  67. struct pid_reg *tmp = *pid;
  68. struct fd_reg **fd_iter = &(*pid)->fd_head;
  69. # if DEBUG == 1
  70. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID %d removed.\n",
  71. getpid(), (*pid)->id);
  72. # endif
  73. while (*fd_iter) remove_fd(fd_iter);
  74. *pid = (*pid)->next;
  75. free(tmp);
  76. }
  77. void remove_fd(struct fd_reg **fd)
  78. {
  79. struct fd_reg *tmp = *fd;
  80. # if DEBUG == 1
  81. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d (%s) removed.\n",
  82. getpid(), (*fd)->fd, (*fd)->filename);
  83. # endif
  84. free((*fd)->filename);
  85. *fd = (*fd)->next;
  86. free(tmp);
  87. }
  88. void deregister_fd(int fd);
  89. struct pid_reg **find_pid(pid_t pid)
  90. {
  91. struct pid_reg **pid_iter = &pid_head;
  92. while (*pid_iter)
  93. {
  94. if ((*pid_iter)->executed)
  95. {
  96. struct fd_reg **fd_iter = &(*pid_iter)->fd_head;
  97. while (*fd_iter)
  98. {
  99. if ((*fd_iter)->closed)
  100. {
  101. handle_file_access_after("exec*", (*fd_iter)->filename, &(*fd_iter)->status);
  102. deregister_fd((*fd_iter)->fd);
  103. }
  104. else fd_iter = &(*fd_iter)->next;
  105. }
  106. }
  107. if ((*pid_iter)->fd_head == 0) remove_pid(pid_iter);
  108. else pid_iter = &(*pid_iter)->next;
  109. }
  110. pid_iter = &pid_head;
  111. while (*pid_iter)
  112. {
  113. if ((*pid_iter)->id == pid) break;
  114. pid_iter = &(*pid_iter)->next;
  115. }
  116. return pid_iter;
  117. }
  118. struct fd_reg **find_fd(struct pid_reg *pid, int fd)
  119. {
  120. struct fd_reg **fd_iter = &pid->fd_head;
  121. while (*fd_iter)
  122. {
  123. if ((*fd_iter)->fd == fd) break;
  124. fd_iter = &(*fd_iter)->next;
  125. }
  126. return fd_iter;
  127. }
  128. void register_fd(int fd, const char *filename, struct status_t *status)
  129. {
  130. struct pid_reg *pid_iter = *find_pid(getpid());
  131. if (pid_iter == 0)
  132. {
  133. add_pid(getpid());
  134. pid_iter = pid_head;
  135. }
  136. struct fd_reg *fd_iter = *find_fd(pid_iter, fd);
  137. if (fd_iter == 0)
  138. {
  139. add_fd(pid_iter, fd, filename, status);
  140. } else {
  141. # if DEBUG == 1
  142. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d already registered (is %s, was %s).\n",
  143. getpid(), fd, filename, fd_iter->filename);
  144. # endif
  145. free(fd_iter->filename);
  146. fd_iter->filename = strdup(filename);
  147. fd_iter->status = *status;
  148. }
  149. }
  150. /* removes fd from register, returning its filename and status via filename
  151. and status arguments.
  152. */
  153. void deregister_fd(int fd)
  154. {
  155. struct pid_reg **pid_iter = find_pid(getpid());
  156. if (*pid_iter)
  157. {
  158. struct fd_reg **fd_iter = find_fd(*pid_iter, fd);
  159. if (*fd_iter)
  160. {
  161. remove_fd(fd_iter);
  162. if ((*pid_iter)->fd_head == 0) remove_pid(pid_iter);
  163. }
  164. }
  165. }
  166. void copy_fds(pid_t parent, pid_t child)
  167. {
  168. struct pid_reg *pid_iter = *find_pid(parent);
  169. if (pid_iter)
  170. {
  171. struct fd_reg *fd_iter = pid_iter->fd_head;
  172. add_pid(child);
  173. struct fd_reg **nextfd = &pid_head->fd_head;
  174. while (fd_iter)
  175. {
  176. *nextfd = malloc(sizeof(struct fd_reg));
  177. **nextfd = *fd_iter;
  178. nextfd = &(*nextfd)->next;
  179. fd_iter = fd_iter->next;
  180. }
  181. }
  182. }
  183. # endif