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.

213 lines
4.2 KiB

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