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.

1870 lines
42 KiB

  1. /* ROCK Linux Wrapper for getting a list of created files
  2. *
  3. * --- ROCK-COPYRIGHT-NOTE-BEGIN ---
  4. *
  5. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  6. * Please add additional copyright information _after_ the line containing
  7. * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
  8. * the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
  9. *
  10. * ROCK Linux: rock-src/misc/tools-source/fl_wrapper.c.sh
  11. * ROCK Linux is Copyright (C) 1998 - 2006 Clifford Wolf
  12. *
  13. * This program is free software; you can redistribute it and/or modify
  14. * it under the terms of the GNU General Public License as published by
  15. * the Free Software Foundation; either version 2 of the License, or
  16. * (at your option) any later version. A copy of the GNU General Public
  17. * License can be found at Documentation/COPYING.
  18. *
  19. * Many people helped and are helping developing ROCK Linux. Please
  20. * have a look at http://www.rocklinux.org/ and the Documentation/TEAM
  21. * file for details.
  22. *
  23. * --- ROCK-COPYRIGHT-NOTE-END ---
  24. *
  25. * Copyright (C) 2004-2005 The T2 SDE Project
  26. *
  27. * gcc -Wall -O2 -ldl -shared -o fl_wrapper.so fl_wrapper.c
  28. *
  29. * !!! THIS FILE IS AUTO-GENERATED BY fl_wrapper.c.sh !!!
  30. *
  31. * ELF Dynamic Loading Documentation:
  32. * - http://www.linuxdoc.org/HOWTO/GCC-HOWTO-7.html
  33. * - http://www.educ.umu.se/~bjorn/mhonarc-files/linux-gcc/msg00576.html
  34. * - /usr/include/dlfcn.h
  35. */
  36. /* Headers and prototypes */
  37. #define DEBUG 0
  38. #define DLOPEN_LIBC 1
  39. #define FD_TRACKER 1
  40. #define _GNU_SOURCE
  41. #define _REENTRANT
  42. #define open xxx_open
  43. #define open64 xxx_open64
  44. #define mknod xxx_mknod
  45. #define _LARGEFILE_SOURCE
  46. #define _LARGEFILE64_SOURCE
  47. # include <dlfcn.h>
  48. # include <errno.h>
  49. # include <fcntl.h>
  50. # include <stdio.h>
  51. # include <stdlib.h>
  52. # include <string.h>
  53. # include <sys/stat.h>
  54. # include <sys/types.h>
  55. # include <unistd.h>
  56. # include <utime.h>
  57. # include <stdarg.h>
  58. # include <sched.h>
  59. #undef _LARGEFILE64_SOURCE
  60. #undef _LARGEFILE_SOURCE
  61. #undef mknod
  62. #undef open
  63. #undef open64
  64. static void * get_dl_symbol(char *);
  65. struct status_t {
  66. ino_t inode;
  67. off_t size;
  68. time_t mtime;
  69. time_t ctime;
  70. };
  71. static void handle_file_access_before(const char *, const char *, struct status_t *);
  72. static void handle_file_access_after(const char *, const char *, struct status_t *);
  73. char *wlog = 0, *rlog = 0, *cmdname = "unkown";
  74. # if DEBUG == 1
  75. int debug = 0;
  76. # endif
  77. /* Wrapper Functions */
  78. /*
  79. TODO:
  80. get rid of the compiler warnings:
  81. fl_wrapper.c: In function '_Exit':
  82. fl_wrapper.c:1100: warning: 'noreturn' function does return
  83. fl_wrapper.c: In function '_exit':
  84. fl_wrapper.c:1075: warning: 'noreturn' function does return
  85. fl_wrapper.c: In function 'exit':
  86. fl_wrapper.c:1050: warning: 'noreturn' function does return
  87. maybe TODO:
  88. wrape clone(); catch termination of child process created with clone()
  89. */
  90. # if FD_TRACKER == 1
  91. /*
  92. Whenever a new file descriptor is opened, it will/should be added to the
  93. fl_wrapper-internal register, together with its current file status.
  94. Accordingly, when a file descriptor is closed, it will be removed from this
  95. register, and handle_file_access_after() will be called with the stored
  96. filename and status.
  97. */
  98. struct pid_reg
  99. {
  100. pid_t id;
  101. int executed;
  102. struct fd_reg *fd_head;
  103. struct pid_reg *next;
  104. };
  105. struct pid_reg *pid_head = 0;
  106. struct fd_reg
  107. {
  108. int fd;
  109. int closed;
  110. struct status_t status;
  111. char *filename;
  112. struct fd_reg *next;
  113. };
  114. void add_pid(pid_t pid)
  115. {
  116. struct pid_reg *newpid = malloc(sizeof(struct pid_reg));
  117. newpid->id = pid;
  118. newpid->fd_head = 0;
  119. newpid->executed = 0;
  120. newpid->next = pid_head;
  121. pid_head = newpid;
  122. # if DEBUG == 1
  123. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID %d added.\n",
  124. getpid(), pid);
  125. # endif
  126. }
  127. void add_fd(struct pid_reg *pid, int fd, const char *filename, struct status_t *status)
  128. {
  129. struct fd_reg *newfd = malloc(sizeof(struct fd_reg));
  130. newfd->fd = fd;
  131. newfd->closed = 0;
  132. newfd->status = *status;
  133. newfd->filename = strdup(filename);
  134. newfd->next = pid->fd_head;
  135. pid->fd_head = newfd;
  136. # if DEBUG == 1
  137. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d (%s) added.\n",
  138. getpid(), fd, filename);
  139. # endif
  140. }
  141. void remove_fd(struct fd_reg **fd);
  142. void remove_pid(struct pid_reg **pid)
  143. {
  144. struct pid_reg *tmp = *pid;
  145. struct fd_reg **fd_iter = &(*pid)->fd_head;
  146. # if DEBUG == 1
  147. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID %d removed.\n",
  148. getpid(), (*pid)->id);
  149. # endif
  150. while (*fd_iter) remove_fd(fd_iter);
  151. *pid = (*pid)->next;
  152. free(tmp);
  153. }
  154. void remove_fd(struct fd_reg **fd)
  155. {
  156. struct fd_reg *tmp = *fd;
  157. # if DEBUG == 1
  158. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d (%s) removed.\n",
  159. getpid(), (*fd)->fd, (*fd)->filename);
  160. # endif
  161. free((*fd)->filename);
  162. *fd = (*fd)->next;
  163. free(tmp);
  164. }
  165. void deregister_fd(int fd);
  166. struct pid_reg **find_pid(pid_t pid)
  167. {
  168. struct pid_reg **pid_iter = &pid_head;
  169. while (*pid_iter)
  170. {
  171. if ((*pid_iter)->executed)
  172. {
  173. struct fd_reg **fd_iter = &(*pid_iter)->fd_head;
  174. while (*fd_iter)
  175. {
  176. if ((*fd_iter)->closed)
  177. {
  178. handle_file_access_after("exec*", (*fd_iter)->filename, &(*fd_iter)->status);
  179. deregister_fd((*fd_iter)->fd);
  180. }
  181. else fd_iter = &(*fd_iter)->next;
  182. }
  183. }
  184. if ((*pid_iter)->fd_head == 0) remove_pid(pid_iter);
  185. else pid_iter = &(*pid_iter)->next;
  186. }
  187. pid_iter = &pid_head;
  188. while (*pid_iter)
  189. {
  190. if ((*pid_iter)->id == pid) break;
  191. pid_iter = &(*pid_iter)->next;
  192. }
  193. return pid_iter;
  194. }
  195. struct fd_reg **find_fd(struct pid_reg *pid, int fd)
  196. {
  197. struct fd_reg **fd_iter = &pid->fd_head;
  198. while (*fd_iter)
  199. {
  200. if ((*fd_iter)->fd == fd) break;
  201. fd_iter = &(*fd_iter)->next;
  202. }
  203. return fd_iter;
  204. }
  205. void register_fd(int fd, const char *filename, struct status_t *status)
  206. {
  207. struct pid_reg *pid_iter = *find_pid(getpid());
  208. if (pid_iter == 0)
  209. {
  210. add_pid(getpid());
  211. pid_iter = pid_head;
  212. }
  213. struct fd_reg *fd_iter = *find_fd(pid_iter, fd);
  214. if (fd_iter == 0)
  215. {
  216. add_fd(pid_iter, fd, filename, status);
  217. } else {
  218. # if DEBUG == 1
  219. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fd %d already registered (is %s, was %s).\n",
  220. getpid(), fd, filename, fd_iter->filename);
  221. # endif
  222. free(fd_iter->filename);
  223. fd_iter->filename = strdup(filename);
  224. fd_iter->status = *status;
  225. }
  226. }
  227. /* removes fd from register, returning its filename and status via filename
  228. and status arguments.
  229. */
  230. void deregister_fd(int fd)
  231. {
  232. struct pid_reg **pid_iter = find_pid(getpid());
  233. if (*pid_iter)
  234. {
  235. struct fd_reg **fd_iter = find_fd(*pid_iter, fd);
  236. if (*fd_iter)
  237. {
  238. remove_fd(fd_iter);
  239. if ((*pid_iter)->fd_head == 0) remove_pid(pid_iter);
  240. }
  241. }
  242. }
  243. void copy_fds(pid_t parent, pid_t child)
  244. {
  245. struct pid_reg *pid_iter = *find_pid(parent);
  246. if (pid_iter)
  247. {
  248. struct fd_reg *fd_iter = pid_iter->fd_head;
  249. add_pid(child);
  250. struct fd_reg **nextfd = &pid_head->fd_head;
  251. while (fd_iter)
  252. {
  253. *nextfd = malloc(sizeof(struct fd_reg));
  254. **nextfd = *fd_iter;
  255. nextfd = &(*nextfd)->next;
  256. fd_iter = fd_iter->next;
  257. }
  258. }
  259. }
  260. # endif
  261. /*
  262. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  263. * This file is part of the GNU C Library.
  264. *
  265. * --- NO-ROCK-COPYRIGHT-NOTE ---
  266. *
  267. * glibc-2.2.5/posix/execl.c
  268. */
  269. /* Execute PATH with all arguments after PATH until
  270. a NULL pointer and environment from `environ'. */
  271. int
  272. execl (const char *path, const char *arg, ...)
  273. {
  274. size_t argv_max = 1024;
  275. const char **argv = alloca (argv_max * sizeof (const char *));
  276. unsigned int i;
  277. va_list args;
  278. argv[0] = arg;
  279. va_start (args, arg);
  280. i = 0;
  281. while (argv[i++] != NULL)
  282. {
  283. if (i == argv_max)
  284. {
  285. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  286. #ifndef _STACK_GROWS_UP
  287. if ((char *) nptr + argv_max == (char *) argv)
  288. {
  289. /* Stack grows down. */
  290. argv = (const char **) memcpy (nptr, argv,
  291. i * sizeof (const char *));
  292. argv_max += i;
  293. }
  294. else
  295. #endif
  296. #ifndef _STACK_GROWS_DOWN
  297. if ((char *) argv + i == (char *) nptr)
  298. /* Stack grows up. */
  299. argv_max += i;
  300. else
  301. #endif
  302. /* We have a hole in the stack. */
  303. argv = (const char **) memcpy (nptr, argv,
  304. i * sizeof (const char *));
  305. }
  306. argv[i] = va_arg (args, const char *);
  307. }
  308. va_end (args);
  309. return execve (path, (char *const *) argv, __environ);
  310. }
  311. /*
  312. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  313. * This file is part of the GNU C Library.
  314. *
  315. * glibc-2.2.5/posix/execle.c
  316. */
  317. /* Execute PATH with all arguments after PATH until a NULL pointer,
  318. and the argument after that for environment. */
  319. int
  320. execle (const char *path, const char *arg, ...)
  321. {
  322. size_t argv_max = 1024;
  323. const char **argv = alloca (argv_max * sizeof (const char *));
  324. const char *const *envp;
  325. unsigned int i;
  326. va_list args;
  327. argv[0] = arg;
  328. va_start (args, arg);
  329. i = 0;
  330. while (argv[i++] != NULL)
  331. {
  332. if (i == argv_max)
  333. {
  334. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  335. #ifndef _STACK_GROWS_UP
  336. if ((char *) nptr + argv_max == (char *) argv)
  337. {
  338. /* Stack grows down. */
  339. argv = (const char **) memcpy (nptr, argv,
  340. i * sizeof (const char *));
  341. argv_max += i;
  342. }
  343. else
  344. #endif
  345. #ifndef _STACK_GROWS_DOWN
  346. if ((char *) argv + i == (char *) nptr)
  347. /* Stack grows up. */
  348. argv_max += i;
  349. else
  350. #endif
  351. /* We have a hole in the stack. */
  352. argv = (const char **) memcpy (nptr, argv,
  353. i * sizeof (const char *));
  354. }
  355. argv[i] = va_arg (args, const char *);
  356. }
  357. envp = va_arg (args, const char *const *);
  358. va_end (args);
  359. return execve (path, (char *const *) argv, (char *const *) envp);
  360. }
  361. /*
  362. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  363. * This file is part of the GNU C Library.
  364. *
  365. * glibc-2.2.5/posix/execlp.c
  366. */
  367. /* Execute FILE, searching in the `PATH' environment variable if
  368. it contains no slashes, with all arguments after FILE until a
  369. NULL pointer and environment from `environ'. */
  370. int
  371. execlp (const char *file, const char *arg, ...)
  372. {
  373. size_t argv_max = 1024;
  374. const char **argv = alloca (argv_max * sizeof (const char *));
  375. unsigned int i;
  376. va_list args;
  377. argv[0] = arg;
  378. va_start (args, arg);
  379. i = 0;
  380. while (argv[i++] != NULL)
  381. {
  382. if (i == argv_max)
  383. {
  384. const char **nptr = alloca ((argv_max *= 2) * sizeof (const char *));
  385. #ifndef _STACK_GROWS_UP
  386. if ((char *) nptr + argv_max == (char *) argv)
  387. {
  388. /* Stack grows down. */
  389. argv = (const char **) memcpy (nptr, argv,
  390. i * sizeof (const char *));
  391. argv_max += i;
  392. }
  393. else
  394. #endif
  395. #ifndef _STACK_GROWS_DOWN
  396. if ((char *) argv + i == (char *) nptr)
  397. /* Stack grows up. */
  398. argv_max += i;
  399. else
  400. #endif
  401. /* We have a hole in the stack. */
  402. argv = (const char **) memcpy (nptr, argv,
  403. i * sizeof (const char *));
  404. }
  405. argv[i] = va_arg (args, const char *);
  406. }
  407. va_end (args);
  408. return execvp (file, (char *const *) argv);
  409. }
  410. /*
  411. * Copyright (C) 1991, 92, 94, 97, 98, 99 Free Software Foundation, Inc.
  412. * This file is part of the GNU C Library.
  413. *
  414. * glibc-2.2.5/posix/execvp.c
  415. */
  416. /* The file is accessible but it is not an executable file. Invoke
  417. the shell to interpret it as a script. */
  418. static void
  419. script_execute (const char *file, char *const argv[])
  420. {
  421. /* Count the arguments. */
  422. int argc = 0;
  423. while (argv[argc++])
  424. ;
  425. /* Construct an argument list for the shell. */
  426. {
  427. char *new_argv[argc + 1];
  428. new_argv[0] = (char *) "/bin/sh";
  429. new_argv[1] = (char *) file;
  430. while (argc > 1)
  431. {
  432. new_argv[argc] = argv[argc - 1];
  433. --argc;
  434. }
  435. /* Execute the shell. */
  436. execve (new_argv[0], new_argv, __environ);
  437. }
  438. }
  439. /* Execute FILE, searching in the `PATH' environment variable if it contains
  440. no slashes, with arguments ARGV and environment from `environ'. */
  441. int
  442. execvp (file, argv)
  443. const char *file;
  444. char *const argv[];
  445. {
  446. if (*file == '\0')
  447. {
  448. /* We check the simple case first. */
  449. errno = ENOENT;
  450. return -1;
  451. }
  452. if (strchr (file, '/') != NULL)
  453. {
  454. /* Don't search when it contains a slash. */
  455. execve (file, argv, __environ);
  456. if (errno == ENOEXEC)
  457. script_execute (file, argv);
  458. }
  459. else
  460. {
  461. int got_eacces = 0;
  462. char *path, *p, *name;
  463. size_t len;
  464. size_t pathlen;
  465. path = getenv ("PATH");
  466. if (path == NULL)
  467. {
  468. /* There is no `PATH' in the environment.
  469. The default search path is the current directory
  470. followed by the path `confstr' returns for `_CS_PATH'. */
  471. len = confstr (_CS_PATH, (char *) NULL, 0);
  472. path = (char *) alloca (1 + len);
  473. path[0] = ':';
  474. (void) confstr (_CS_PATH, path + 1, len);
  475. }
  476. len = strlen (file) + 1;
  477. pathlen = strlen (path);
  478. name = alloca (pathlen + len + 1);
  479. /* Copy the file name at the top. */
  480. name = (char *) memcpy (name + pathlen + 1, file, len);
  481. /* And add the slash. */
  482. *--name = '/';
  483. p = path;
  484. do
  485. {
  486. char *startp;
  487. path = p;
  488. p = strchrnul (path, ':');
  489. if (p == path)
  490. /* Two adjacent colons, or a colon at the beginning or the end
  491. of `PATH' means to search the current directory. */
  492. startp = name + 1;
  493. else
  494. startp = (char *) memcpy (name - (p - path), path, p - path);
  495. /* Try to execute this name. If it works, execv will not return. */
  496. execve (startp, argv, __environ);
  497. if (errno == ENOEXEC)
  498. script_execute (startp, argv);
  499. switch (errno)
  500. {
  501. case EACCES:
  502. /* Record the we got a `Permission denied' error. If we end
  503. up finding no executable we can use, we want to diagnose
  504. that we did find one but were denied access. */
  505. got_eacces = 1;
  506. case ENOENT:
  507. case ESTALE:
  508. case ENOTDIR:
  509. /* Those errors indicate the file is missing or not executable
  510. by us, in which case we want to just try the next path
  511. directory. */
  512. break;
  513. default:
  514. /* Some other error means we found an executable file, but
  515. something went wrong executing it; return the error to our
  516. caller. */
  517. return -1;
  518. }
  519. }
  520. while (*p++ != '\0');
  521. /* We tried every element and none of them worked. */
  522. if (got_eacces)
  523. /* At least one failure was due to permissions, so report that
  524. error. */
  525. errno = EACCES;
  526. }
  527. /* Return the error from the last attempt (probably ENOENT). */
  528. return -1;
  529. }
  530. /* ROCK Linux Wrapper for getting a list of created files
  531. *
  532. * --- ROCK-COPYRIGHT-NOTE-BEGIN ---
  533. *
  534. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  535. * Please add additional copyright information _after_ the line containing
  536. * the ROCK-COPYRIGHT-NOTE-END tag. Otherwise it might get removed by
  537. * the ./scripts/Create-CopyPatch script. Do not edit this copyright text!
  538. *
  539. * ROCK Linux: rock-src/misc/tools-source/fl_wrapper_open.c
  540. * ROCK Linux is Copyright (C) 1998 - 2006 Clifford Wolf
  541. *
  542. * This program is free software; you can redistribute it and/or modify
  543. * it under the terms of the GNU General Public License as published by
  544. * the Free Software Foundation; either version 2 of the License, or
  545. * (at your option) any later version. A copy of the GNU General Public
  546. * License can be found at Documentation/COPYING.
  547. *
  548. * Many people helped and are helping developing ROCK Linux. Please
  549. * have a look at http://www.rocklinux.org/ and the Documentation/TEAM
  550. * file for details.
  551. *
  552. * --- ROCK-COPYRIGHT-NOTE-END ---
  553. */
  554. extern int open(const char* f, int a, ...);
  555. int (*orig_open)(const char* f, int a, ...) = 0;
  556. int open(const char* f, int a, ...)
  557. {
  558. struct status_t status;
  559. int old_errno=errno;
  560. int rc;
  561. handle_file_access_before("open", f, &status);
  562. if (!orig_open) orig_open = get_dl_symbol("open");
  563. errno=old_errno;
  564. # if DEBUG == 1
  565. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open(\"%s\", ...) at %p (wrapper is at %p).\n",
  566. getpid(), f, orig_open, open);
  567. # endif
  568. if (a & O_CREAT)
  569. {
  570. va_list ap;
  571. mode_t b = 0;
  572. va_start(ap, a);
  573. b = va_arg(ap, mode_t);
  574. va_end(ap);
  575. rc = orig_open(f, a, b);
  576. }
  577. else
  578. rc = orig_open(f, a);
  579. old_errno=errno;
  580. # if FD_TRACKER == 1
  581. if (rc != -1)
  582. {
  583. char *buf = 0;
  584. int free_buf = 0;
  585. if (f[0] != '/')
  586. {
  587. char *buf2 = get_current_dir_name();
  588. if (asprintf(&buf,"%s%s%s", buf2,
  589. strcmp(buf2,"/") ? "/" : "", f) != -1)
  590. {
  591. f = buf; free_buf = 1;
  592. }
  593. free(buf2);
  594. }
  595. register_fd(rc, f, &status);
  596. if (free_buf) free(buf);
  597. }
  598. # else
  599. handle_file_access_after("open", f, &status);
  600. # endif
  601. errno=old_errno;
  602. return rc;
  603. }
  604. extern int open64(const char* f, int a, ...);
  605. int (*orig_open64)(const char* f, int a, ...) = 0;
  606. int open64(const char* f, int a, ...)
  607. {
  608. struct status_t status;
  609. int old_errno=errno;
  610. int rc;
  611. handle_file_access_before("open64", f, &status);
  612. if (!orig_open64) orig_open64 = get_dl_symbol("open64");
  613. errno=old_errno;
  614. # if DEBUG == 1
  615. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original open64(\"%s\", ...) at %p (wrapper is at %p).\n",
  616. getpid(), f, orig_open64, open64);
  617. # endif
  618. if (a & O_CREAT)
  619. {
  620. va_list ap;
  621. mode_t b = 0;
  622. va_start(ap, a);
  623. b = va_arg(ap, mode_t);
  624. va_end(ap);
  625. rc = orig_open64(f, a, b);
  626. }
  627. else
  628. rc = orig_open64(f, a);
  629. old_errno=errno;
  630. # if FD_TRACKER == 1
  631. if (rc != -1)
  632. {
  633. char *buf = 0;
  634. int free_buf = 0;
  635. if (f[0] != '/')
  636. {
  637. char *buf2 = get_current_dir_name();
  638. if (asprintf(&buf,"%s%s%s", buf2,
  639. strcmp(buf2,"/") ? "/" : "", f) != -1)
  640. {
  641. f = buf; free_buf = 1;
  642. }
  643. free(buf2);
  644. }
  645. register_fd(rc, f, &status);
  646. if (free_buf) free(buf);
  647. }
  648. # else
  649. handle_file_access_after("open64", f, &status);
  650. # endif
  651. errno=old_errno;
  652. return rc;
  653. }
  654. extern int creat(const char* f, mode_t m);
  655. int (*orig_creat)(const char* f, mode_t m) = 0;
  656. int creat(const char* f, mode_t m)
  657. {
  658. struct status_t status;
  659. int old_errno=errno;
  660. int rc;
  661. handle_file_access_before("creat", f, &status);
  662. if (!orig_creat) orig_creat = get_dl_symbol("creat");
  663. # if DEBUG == 1
  664. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat(\"%s\", ...) at %p (wrapper is at %p).\n",
  665. getpid(), f, orig_creat, creat);
  666. # endif
  667. errno=old_errno;
  668. rc = orig_creat(f, m);
  669. old_errno=errno;
  670. # if FD_TRACKER == 1
  671. if (rc != -1)
  672. {
  673. char *buf = 0;
  674. int free_buf = 0;
  675. if (f[0] != '/')
  676. {
  677. char *buf2 = get_current_dir_name();
  678. if (asprintf(&buf,"%s%s%s", buf2,
  679. strcmp(buf2,"/") ? "/" : "", f) != -1)
  680. {
  681. f = buf; free_buf = 1;
  682. }
  683. free(buf2);
  684. }
  685. register_fd(rc, f, &status);
  686. if (free_buf) free(buf);
  687. }
  688. # else
  689. handle_file_access_after("creat", f, &status);
  690. # endif
  691. errno=old_errno;
  692. return rc;
  693. }
  694. extern int creat64(const char* f, mode_t m);
  695. int (*orig_creat64)(const char* f, mode_t m) = 0;
  696. int creat64(const char* f, mode_t m)
  697. {
  698. struct status_t status;
  699. int old_errno=errno;
  700. int rc;
  701. handle_file_access_before("creat64", f, &status);
  702. if (!orig_creat64) orig_creat64 = get_dl_symbol("creat64");
  703. # if DEBUG == 1
  704. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original creat64(%s, ...) at %p (wrapper is at %p).\n",
  705. getpid(), f, orig_creat64, creat64);
  706. # endif
  707. errno=old_errno;
  708. rc = orig_creat64(f, m);
  709. old_errno=errno;
  710. # if FD_TRACKER == 1
  711. if (rc != -1)
  712. {
  713. char *buf = 0;
  714. int free_buf = 0;
  715. if (f[0] != '/')
  716. {
  717. char *buf2 = get_current_dir_name();
  718. if (asprintf(&buf,"%s%s%s", buf2,
  719. strcmp(buf2,"/") ? "/" : "", f) != -1)
  720. {
  721. f = buf; free_buf = 1;
  722. }
  723. free(buf2);
  724. }
  725. register_fd(rc, f, &status);
  726. if (free_buf) free(buf);
  727. }
  728. # else
  729. handle_file_access_after("creat64", f, &status);
  730. # endif
  731. errno=old_errno;
  732. return rc;
  733. }
  734. extern FILE* fopen(const char* f, const char* g);
  735. FILE* (*orig_fopen)(const char* f, const char* g) = 0;
  736. FILE* fopen(const char* f, const char* g)
  737. {
  738. struct status_t status;
  739. int old_errno=errno;
  740. FILE* rc;
  741. handle_file_access_before("fopen", f, &status);
  742. if (!orig_fopen) orig_fopen = get_dl_symbol("fopen");
  743. # if DEBUG == 1
  744. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen() at %p (wrapper is at %p).\n",
  745. getpid(), orig_fopen, fopen);
  746. # endif
  747. errno=old_errno;
  748. rc = orig_fopen(f, g);
  749. old_errno=errno;
  750. # if FD_TRACKER == 1
  751. if (rc != 0)
  752. {
  753. char *buf = 0;
  754. int free_buf = 0;
  755. if (f[0] != '/')
  756. {
  757. char *buf2 = get_current_dir_name();
  758. if (asprintf(&buf,"%s%s%s", buf2,
  759. strcmp(buf2,"/") ? "/" : "", f) != -1)
  760. {
  761. f = buf; free_buf = 1;
  762. }
  763. free(buf2);
  764. }
  765. register_fd(fileno(rc), f, &status);
  766. if (free_buf) free(buf);
  767. }
  768. # else
  769. handle_file_access_after("fopen", f, &status);
  770. # endif
  771. errno=old_errno;
  772. return rc;
  773. }
  774. extern FILE* fopen64(const char* f, const char* g);
  775. FILE* (*orig_fopen64)(const char* f, const char* g) = 0;
  776. FILE* fopen64(const char* f, const char* g)
  777. {
  778. struct status_t status;
  779. int old_errno=errno;
  780. FILE* rc;
  781. handle_file_access_before("fopen64", f, &status);
  782. if (!orig_fopen64) orig_fopen64 = get_dl_symbol("fopen64");
  783. # if DEBUG == 1
  784. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fopen64() at %p (wrapper is at %p).\n",
  785. getpid(), orig_fopen64, fopen64);
  786. # endif
  787. errno=old_errno;
  788. rc = orig_fopen64(f, g);
  789. old_errno=errno;
  790. # if FD_TRACKER == 1
  791. if (rc != 0)
  792. {
  793. char *buf = 0;
  794. int free_buf = 0;
  795. if (f[0] != '/')
  796. {
  797. char *buf2 = get_current_dir_name();
  798. if (asprintf(&buf,"%s%s%s", buf2,
  799. strcmp(buf2,"/") ? "/" : "", f) != -1)
  800. {
  801. f = buf; free_buf = 1;
  802. }
  803. free(buf2);
  804. }
  805. register_fd(fileno(rc), f, &status);
  806. if (free_buf) free(buf);
  807. }
  808. # else
  809. handle_file_access_after("fopen64", f, &status);
  810. # endif
  811. errno=old_errno;
  812. return rc;
  813. }
  814. extern int dup(int fd);
  815. int (*orig_dup)(int fd) = 0;
  816. int dup(int fd)
  817. {
  818. int old_errno = errno;
  819. int rc;
  820. if (!orig_dup) orig_dup = get_dl_symbol("dup");
  821. # if DEBUG == 1
  822. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original dup(%d) at %p (wrapper is at %p).\n",
  823. getpid(), fd, orig_dup, dup);
  824. # endif
  825. errno=old_errno;
  826. rc = orig_dup(fd);
  827. old_errno = errno;
  828. # if FD_TRACKER == 1
  829. if (rc != -1)
  830. {
  831. struct pid_reg *pid = *find_pid(getpid());
  832. if (pid)
  833. {
  834. struct fd_reg *oldfd = *find_fd(pid, fd);
  835. if (oldfd) register_fd(rc, oldfd->filename, &oldfd->status);
  836. }
  837. }
  838. # endif
  839. errno=old_errno;
  840. return rc;
  841. }
  842. extern int dup2(int fd, int fd2);
  843. int (*orig_dup2)(int fd, int fd2) = 0;
  844. int dup2(int oldfd, int newfd)
  845. {
  846. int old_errno = errno;
  847. int rc;
  848. if (!orig_dup2) orig_dup2 = get_dl_symbol("dup2");
  849. # if DEBUG == 1
  850. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original dup2(%d, %d) at %p (wrapper is at %p).\n",
  851. getpid(), oldfd, newfd, orig_dup2, dup2);
  852. # endif
  853. errno=old_errno;
  854. rc = orig_dup2(oldfd, newfd);
  855. old_errno = errno;
  856. # if FD_TRACKER == 1
  857. if (rc != -1)
  858. {
  859. struct pid_reg *pid = *find_pid(getpid());
  860. if (pid)
  861. {
  862. struct fd_reg *fd = *find_fd(pid, newfd);
  863. if (fd && oldfd != newfd)
  864. {
  865. handle_file_access_after("dup2", fd->filename, &fd->status);
  866. deregister_fd(newfd);
  867. }
  868. fd = *find_fd(pid, oldfd);
  869. if (fd) register_fd(rc, fd->filename, &fd->status);
  870. }
  871. }
  872. # endif
  873. errno=old_errno;
  874. return rc;
  875. }
  876. extern int fcntl(int fd, int cmd, ...);
  877. int (*orig_fcntl)(int fd, int cmd, ...) = 0;
  878. int fcntl(int fd, int cmd, ...)
  879. {
  880. int old_errno = errno;
  881. int rc;
  882. int fd2 = -1;
  883. if (!orig_fcntl) orig_fcntl = get_dl_symbol("fcntl");
  884. # if DEBUG == 1
  885. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fcntl(%d, %d, ...) at %p (wrapper is at %p).\n",
  886. getpid(), fd, cmd, orig_fcntl, fcntl);
  887. # endif
  888. errno=old_errno;
  889. if (cmd & F_GETLK || cmd & F_SETLK || cmd & F_SETLKW)
  890. {
  891. va_list ap;
  892. struct flock *b = 0;
  893. va_start(ap, cmd);
  894. b = va_arg(ap, struct flock*);
  895. va_end(ap);
  896. rc = orig_fcntl(fd, cmd, b);
  897. } else {
  898. va_list ap;
  899. long b = 0;
  900. va_start(ap, cmd);
  901. b = va_arg(ap, long);
  902. va_end(ap);
  903. rc = orig_fcntl(fd, cmd, b);
  904. fd2 = (int) b;
  905. }
  906. old_errno = errno;
  907. # if FD_TRACKER == 1
  908. if (rc != -1 && cmd == F_DUPFD)
  909. {
  910. struct pid_reg *pid = *find_pid(getpid());
  911. if (pid)
  912. {
  913. struct fd_reg *oldfd = *find_fd(pid, fd);
  914. if (oldfd) register_fd(rc, oldfd->filename, &oldfd->status);
  915. }
  916. }
  917. # endif
  918. errno=old_errno;
  919. return rc;
  920. }
  921. extern int close(int fd);
  922. int (*orig_close)(int fd) = 0;
  923. int close(int fd)
  924. {
  925. int old_errno=errno;
  926. int rc;
  927. if (!orig_close) orig_close = get_dl_symbol("close");
  928. # if DEBUG == 1
  929. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original close(%d) at %p (wrapper is at %p).\n",
  930. getpid(), fd, orig_close, close);
  931. # endif
  932. errno=old_errno;
  933. rc = orig_close(fd);
  934. old_errno=errno;
  935. # if FD_TRACKER == 1
  936. if (rc == 0 || errno == EBADF)
  937. {
  938. struct pid_reg *pidreg = *find_pid(getpid());
  939. if (pidreg)
  940. {
  941. struct fd_reg *fdreg = *find_fd(pidreg, fd);
  942. if (fdreg)
  943. {
  944. handle_file_access_after("close", fdreg->filename, &fdreg->status);
  945. deregister_fd(fd);
  946. }
  947. }
  948. }
  949. # endif
  950. errno=old_errno;
  951. return rc;
  952. }
  953. extern int fclose(FILE* f);
  954. int (*orig_fclose)(FILE* f) = 0;
  955. int fclose(FILE* f)
  956. {
  957. int old_errno=errno;
  958. int rc;
  959. int fd=fileno(f);
  960. if (!orig_fclose) orig_fclose = get_dl_symbol("fclose");
  961. # if DEBUG == 1
  962. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fclose(%d) at %p (wrapper is at %p).\n",
  963. getpid(), fd, orig_fclose, fclose);
  964. # endif
  965. errno=old_errno;
  966. rc = orig_fclose(f);
  967. old_errno=errno;
  968. # if FD_TRACKER == 1
  969. if (rc == 0)
  970. {
  971. struct pid_reg *pidreg = *find_pid(getpid());
  972. if (pidreg)
  973. {
  974. struct fd_reg *fdreg = *find_fd(pidreg, fd);
  975. if (fdreg)
  976. {
  977. handle_file_access_after("fclose", fdreg->filename, &fdreg->status);
  978. deregister_fd(fd);
  979. }
  980. }
  981. }
  982. # endif
  983. errno=old_errno;
  984. return rc;
  985. }
  986. /*
  987. extern int fcloseall();
  988. int (*orig_fcloseall)() = 0;
  989. int fcloseall()
  990. {
  991. int old_errno=errno;
  992. int rc;
  993. if (!orig_fcloseall) orig_fcloseall = get_dl_symbol("fcloseall");
  994. # if DEBUG == 1
  995. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fcloseall() at %p (wrapper is at %p).\n",
  996. getpid(), orig_fcloseall, fcloseall);
  997. # endif
  998. errno=old_errno;
  999. rc = orig_fcloseall();
  1000. return rc;
  1001. }
  1002. */
  1003. extern int fork();
  1004. int (*orig_fork)() = 0;
  1005. int fork()
  1006. {
  1007. int old_errno = errno;
  1008. int rc;
  1009. # if FD_TRACKER == 1
  1010. int caller_pid = getpid();
  1011. # endif
  1012. if (!orig_fork) orig_fork = get_dl_symbol("fork");
  1013. # if DEBUG == 1
  1014. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original fork() at %p (wrapper is at %p).\n",
  1015. getpid(), orig_fork, fork);
  1016. # endif
  1017. errno = old_errno;
  1018. rc = orig_fork();
  1019. old_errno = errno;
  1020. # if FD_TRACKER == 1
  1021. if ( rc == 0) copy_fds(caller_pid, getpid());
  1022. # endif
  1023. # if DEBUG == 1
  1024. struct pid_reg *pid = pid_head;
  1025. while (pid)
  1026. {
  1027. struct fd_reg *fd = pid->fd_head;
  1028. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fork: found PID %d.\n",
  1029. getpid(), pid->id);
  1030. while (fd)
  1031. {
  1032. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fork: found fd %d (%s).\n",
  1033. getpid(), fd->fd, fd->filename);
  1034. fd = fd->next;
  1035. }
  1036. pid = pid->next;
  1037. }
  1038. # endif
  1039. errno=old_errno;
  1040. return rc;
  1041. }
  1042. extern void exit(int status) __attribute__ ((noreturn));
  1043. void (*orig_exit)(int status) = 0;
  1044. void exit(int status)
  1045. {
  1046. int old_errno = errno;
  1047. if (!orig_exit) orig_exit = get_dl_symbol("exit");
  1048. # if DEBUG == 1
  1049. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original exit(%d) at %p (wrapper is at %p).\n",
  1050. getpid(), status, orig_exit, exit);
  1051. # endif
  1052. # if FD_TRACKER == 1
  1053. struct pid_reg *pid = *find_pid(getpid());
  1054. if (pid)
  1055. {
  1056. struct fd_reg **fd_iter = &pid->fd_head;
  1057. while (*fd_iter)
  1058. {
  1059. handle_file_access_after("exit", (*fd_iter)->filename, &(*fd_iter)->status);
  1060. deregister_fd((*fd_iter)->fd);
  1061. }
  1062. }
  1063. # endif
  1064. errno=old_errno;
  1065. orig_exit(status);
  1066. }
  1067. extern void _exit(int status) __attribute__ ((noreturn));
  1068. void (*orig__exit)(int status) = 0;
  1069. void _exit(int status)
  1070. {
  1071. int old_errno = errno;
  1072. if (!orig__exit) orig__exit = get_dl_symbol("_exit");
  1073. # if DEBUG == 1
  1074. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original _exit(%d) at %p (wrapper is at %p).\n",
  1075. getpid(), status, orig__exit, _exit);
  1076. # endif
  1077. # if FD_TRACKER == 1
  1078. struct pid_reg *pid = *find_pid(getpid());
  1079. if (pid)
  1080. {
  1081. struct fd_reg **fd_iter = &pid->fd_head;
  1082. while (*fd_iter)
  1083. {
  1084. handle_file_access_after("_exit", (*fd_iter)->filename, &(*fd_iter)->status);
  1085. deregister_fd((*fd_iter)->fd);
  1086. }
  1087. }
  1088. # endif
  1089. errno=old_errno;
  1090. orig__exit(status);
  1091. }
  1092. extern void _Exit(int status) __attribute__ ((noreturn));
  1093. void (*orig__Exit)(int status) = 0;
  1094. void _Exit(int status)
  1095. {
  1096. int old_errno = errno;
  1097. if (!orig__Exit) orig__Exit = get_dl_symbol("_Exit");
  1098. # if DEBUG == 1
  1099. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original _Exit(%d) at %p (wrapper is at %p).\n",
  1100. getpid(), status, orig__Exit, _Exit);
  1101. # endif
  1102. # if FD_TRACKER == 1
  1103. struct pid_reg *pid = *find_pid(getpid());
  1104. if (pid)
  1105. {
  1106. struct fd_reg **fd_iter = &pid->fd_head;
  1107. while (*fd_iter)
  1108. {
  1109. handle_file_access_after("_Exit", (*fd_iter)->filename, &(*fd_iter)->status);
  1110. deregister_fd((*fd_iter)->fd);
  1111. }
  1112. }
  1113. # endif
  1114. errno=old_errno;
  1115. orig__Exit(status);
  1116. }
  1117. extern int mkdir(const char* f, mode_t m);
  1118. int (*orig_mkdir)(const char* f, mode_t m) = 0;
  1119. int mkdir(const char* f, mode_t m)
  1120. {
  1121. struct status_t status;
  1122. int old_errno=errno;
  1123. int rc;
  1124. handle_file_access_before("mkdir", f, &status);
  1125. if (!orig_mkdir) orig_mkdir = get_dl_symbol("mkdir");
  1126. # if DEBUG == 1
  1127. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original mkdir() at %p (wrapper is at %p).\n",
  1128. getpid(), orig_mkdir, mkdir);
  1129. # endif
  1130. errno=old_errno;
  1131. rc = orig_mkdir(f, m);
  1132. old_errno=errno;
  1133. handle_file_access_after("mkdir", f, &status);
  1134. errno=old_errno;
  1135. return rc;
  1136. }
  1137. extern int mknod(const char* f, mode_t m, dev_t d);
  1138. int (*orig_mknod)(const char* f, mode_t m, dev_t d) = 0;
  1139. int mknod(const char* f, mode_t m, dev_t d)
  1140. {
  1141. struct status_t status;
  1142. int old_errno=errno;
  1143. int rc;
  1144. handle_file_access_before("mknod", f, &status);
  1145. if (!orig_mknod) orig_mknod = get_dl_symbol("mknod");
  1146. # if DEBUG == 1
  1147. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original mknod() at %p (wrapper is at %p).\n",
  1148. getpid(), orig_mknod, mknod);
  1149. # endif
  1150. errno=old_errno;
  1151. rc = orig_mknod(f, m, d);
  1152. old_errno=errno;
  1153. handle_file_access_after("mknod", f, &status);
  1154. errno=old_errno;
  1155. return rc;
  1156. }
  1157. extern int link(const char* s, const char* f);
  1158. int (*orig_link)(const char* s, const char* f) = 0;
  1159. int link(const char* s, const char* f)
  1160. {
  1161. struct status_t status;
  1162. int old_errno=errno;
  1163. int rc;
  1164. handle_file_access_before("link", f, &status);
  1165. if (!orig_link) orig_link = get_dl_symbol("link");
  1166. # if DEBUG == 1
  1167. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original link() at %p (wrapper is at %p).\n",
  1168. getpid(), orig_link, link);
  1169. # endif
  1170. errno=old_errno;
  1171. rc = orig_link(s, f);
  1172. old_errno=errno;
  1173. handle_file_access_after("link", f, &status);
  1174. errno=old_errno;
  1175. return rc;
  1176. }
  1177. extern int symlink(const char* s, const char* f);
  1178. int (*orig_symlink)(const char* s, const char* f) = 0;
  1179. int symlink(const char* s, const char* f)
  1180. {
  1181. struct status_t status;
  1182. int old_errno=errno;
  1183. int rc;
  1184. handle_file_access_before("symlink", f, &status);
  1185. if (!orig_symlink) orig_symlink = get_dl_symbol("symlink");
  1186. # if DEBUG == 1
  1187. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original symlink() at %p (wrapper is at %p).\n",
  1188. getpid(), orig_symlink, symlink);
  1189. # endif
  1190. errno=old_errno;
  1191. rc = orig_symlink(s, f);
  1192. old_errno=errno;
  1193. handle_file_access_after("symlink", f, &status);
  1194. errno=old_errno;
  1195. return rc;
  1196. }
  1197. extern int rename(const char* s, const char* f);
  1198. int (*orig_rename)(const char* s, const char* f) = 0;
  1199. int rename(const char* s, const char* f)
  1200. {
  1201. struct status_t status;
  1202. int old_errno=errno;
  1203. int rc;
  1204. handle_file_access_before("rename", f, &status);
  1205. if (!orig_rename) orig_rename = get_dl_symbol("rename");
  1206. # if DEBUG == 1
  1207. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original rename() at %p (wrapper is at %p).\n",
  1208. getpid(), orig_rename, rename);
  1209. # endif
  1210. errno=old_errno;
  1211. rc = orig_rename(s, f);
  1212. old_errno=errno;
  1213. handle_file_access_after("rename", f, &status);
  1214. errno=old_errno;
  1215. return rc;
  1216. }
  1217. extern int utime(const char* f, const struct utimbuf* t);
  1218. int (*orig_utime)(const char* f, const struct utimbuf* t) = 0;
  1219. int utime(const char* f, const struct utimbuf* t)
  1220. {
  1221. struct status_t status;
  1222. int old_errno=errno;
  1223. int rc;
  1224. handle_file_access_before("utime", f, &status);
  1225. if (!orig_utime) orig_utime = get_dl_symbol("utime");
  1226. # if DEBUG == 1
  1227. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original utime() at %p (wrapper is at %p).\n",
  1228. getpid(), orig_utime, utime);
  1229. # endif
  1230. errno=old_errno;
  1231. rc = orig_utime(f, t);
  1232. old_errno=errno;
  1233. handle_file_access_after("utime", f, &status);
  1234. errno=old_errno;
  1235. return rc;
  1236. }
  1237. extern int utimes(const char* f, struct timeval* t);
  1238. int (*orig_utimes)(const char* f, struct timeval* t) = 0;
  1239. int utimes(const char* f, struct timeval* t)
  1240. {
  1241. struct status_t status;
  1242. int old_errno=errno;
  1243. int rc;
  1244. handle_file_access_before("utimes", f, &status);
  1245. if (!orig_utimes) orig_utimes = get_dl_symbol("utimes");
  1246. # if DEBUG == 1
  1247. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original utimes() at %p (wrapper is at %p).\n",
  1248. getpid(), orig_utimes, utimes);
  1249. # endif
  1250. errno=old_errno;
  1251. rc = orig_utimes(f, t);
  1252. old_errno=errno;
  1253. handle_file_access_after("utimes", f, &status);
  1254. errno=old_errno;
  1255. return rc;
  1256. }
  1257. extern int execv(const char* f, char* const a[]);
  1258. int (*orig_execv)(const char* f, char* const a[]) = 0;
  1259. int execv(const char* f, char* const a[])
  1260. {
  1261. int old_errno=errno;
  1262. int rc;
  1263. handle_file_access_after("execv", f, 0);
  1264. if (!orig_execv) orig_execv = get_dl_symbol("execv");
  1265. # if FD_TRACKER == 1
  1266. struct pid_reg *pid = *find_pid(getpid());
  1267. struct fd_reg ** fd_iter;
  1268. if (pid)
  1269. {
  1270. fd_iter = &pid->fd_head;
  1271. while (*fd_iter != 0)
  1272. {
  1273. (*fd_iter)->closed = fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC;
  1274. fd_iter = &(*fd_iter)->next;
  1275. }
  1276. pid->executed = 1;
  1277. }
  1278. # endif
  1279. # if DEBUG == 1
  1280. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original execv() at %p (wrapper is at %p).\n",
  1281. getpid(), orig_execv, execv);
  1282. # endif
  1283. errno=old_errno;
  1284. rc = orig_execv(f, a);
  1285. old_errno=errno;
  1286. # if FD_TRACKER == 1
  1287. if (pid)
  1288. {
  1289. fd_iter = &pid->fd_head;
  1290. while (*fd_iter != 0)
  1291. {
  1292. (*fd_iter)->closed = 0;
  1293. fd_iter = &(*fd_iter)->next;
  1294. }
  1295. pid->executed = 0;
  1296. }
  1297. # endif
  1298. errno=old_errno;
  1299. return rc;
  1300. }
  1301. extern int execve(const char* f, char* const a[], char* const e[]);
  1302. int (*orig_execve)(const char* f, char* const a[], char* const e[]) = 0;
  1303. int execve(const char* f, char* const a[], char* const e[])
  1304. {
  1305. int old_errno=errno;
  1306. int rc;
  1307. handle_file_access_after("execve", f, 0);
  1308. if (!orig_execve) orig_execve = get_dl_symbol("execve");
  1309. # if FD_TRACKER == 1
  1310. struct pid_reg *pid = *find_pid(getpid());
  1311. struct fd_reg ** fd_iter;
  1312. if (pid)
  1313. {
  1314. fd_iter = &pid->fd_head;
  1315. while (*fd_iter != 0)
  1316. {
  1317. (*fd_iter)->closed = fcntl((*fd_iter)->fd, F_GETFD) & FD_CLOEXEC;
  1318. fd_iter = &(*fd_iter)->next;
  1319. }
  1320. pid->executed = 1;
  1321. }
  1322. # endif
  1323. # if DEBUG == 1
  1324. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: going to run original execve() at %p (wrapper is at %p).\n",
  1325. getpid(), orig_execve, execve);
  1326. # endif
  1327. errno=old_errno;
  1328. rc = orig_execve(f, a, e);
  1329. old_errno=errno;
  1330. # if FD_TRACKER == 1
  1331. if (pid)
  1332. {
  1333. fd_iter = &pid->fd_head;
  1334. while (*fd_iter != 0)
  1335. {
  1336. (*fd_iter)->closed = 0;
  1337. fd_iter = &(*fd_iter)->next;
  1338. }
  1339. pid->executed = 0;
  1340. }
  1341. # endif
  1342. errno=old_errno;
  1343. return rc;
  1344. }
  1345. /* Internal Functions */
  1346. static void * get_dl_symbol(char * symname)
  1347. {
  1348. void * rc;
  1349. #if DLOPEN_LIBC
  1350. static void * libc_handle = 0;
  1351. if (!libc_handle) libc_handle=dlopen("libc.so.6", RTLD_LAZY);
  1352. if (!libc_handle) {
  1353. printf("fl_wrapper.so: Can't dlopen libc: %s\n", dlerror());
  1354. abort();
  1355. }
  1356. rc = dlsym(libc_handle, symname);
  1357. # if DEBUG == 1
  1358. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' in libc (%p) has been resolved to %p.\n",
  1359. getpid(), symname, libc_handle, rc);
  1360. # endif
  1361. #else
  1362. rc = dlsym(RTLD_NEXT, symname);
  1363. # if DEBUG == 1
  1364. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: Symbol '%s' (RTLD_NEXT) has been resolved to %p.\n",
  1365. getpid(), symname, rc);
  1366. # endif
  1367. #endif
  1368. if (!rc) {
  1369. printf("fl_wrapper.so: Can't resolve %s: %s\n",
  1370. symname, dlerror());
  1371. abort();
  1372. }
  1373. return rc;
  1374. }
  1375. static int pid2ppid(int pid)
  1376. {
  1377. char buffer[100];
  1378. int fd, rc, ppid = 0;
  1379. sprintf(buffer, "/proc/%d/stat", pid);
  1380. if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return 0;
  1381. if ( (rc = read(fd, buffer, 99)) > 0) {
  1382. buffer[rc] = 0;
  1383. /* format: 27910 (bash) S 27315 ... */
  1384. sscanf(buffer, "%*[^ ] %*[^ ] %*[^ ] %d", &ppid);
  1385. }
  1386. close(fd);
  1387. return ppid;
  1388. }
  1389. /* this is only called from fl_wrapper_init(). so it doesn't need to be
  1390. * reentrant. */
  1391. static char *getpname(int pid)
  1392. {
  1393. static char p[512];
  1394. char buffer[513]="";
  1395. char *arg=0, *b;
  1396. int i, fd, rc;
  1397. sprintf(buffer, "/proc/%d/cmdline", pid);
  1398. if ( (fd = open(buffer, O_RDONLY, 0)) < 0 ) return "unkown";
  1399. if ( (rc = read(fd, buffer, 512)) > 0) {
  1400. buffer[rc--] = 0;
  1401. for (i=0; i<rc; i++)
  1402. if (buffer[i] == 0 && buffer[i+1] != '-')
  1403. { arg = buffer+i+1; break; }
  1404. }
  1405. close(fd);
  1406. b = basename(buffer);
  1407. snprintf(p, 512, "%s", b);
  1408. if ( !strcmp(b, "bash") || !strcmp(b, "sh") ||
  1409. !strcmp(b, "perl") || !strcmp(b, "python") )
  1410. if ( arg && *arg &&
  1411. strlen(arg) < 100 && !strchr(arg, '\n') &&
  1412. !strchr(arg, ' ') && !strchr(arg, ';') )
  1413. snprintf(p, 512, "%s(%s)", b, basename(arg));
  1414. return p;
  1415. }
  1416. /* invert the order by recursion. there will be only one recursion tree
  1417. * so we can use a static var for managing the last ent */
  1418. static void addptree(int *txtpos, char *cmdtxt, int pid, int basepid)
  1419. {
  1420. static char l[512] = "";
  1421. char *p;
  1422. if (!pid || pid == basepid) return;
  1423. addptree(txtpos, cmdtxt, pid2ppid(pid), basepid);
  1424. p = getpname(pid);
  1425. if (*txtpos < 4000)
  1426. {
  1427. if ( strcmp(l, p) )
  1428. *txtpos += snprintf(cmdtxt+*txtpos, 4096-*txtpos, "%s%s",
  1429. *txtpos ? "." : "", getpname(pid));
  1430. else
  1431. *txtpos += snprintf(cmdtxt+*txtpos, 4096-*txtpos, "*");
  1432. }
  1433. strcpy(l, p);
  1434. }
  1435. void __attribute__ ((constructor)) fl_wrapper_init()
  1436. {
  1437. # if DEBUG == 1
  1438. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fl_wrapper_init()\n", getpid());
  1439. # endif
  1440. char cmdtxt[4096] = "";
  1441. char *basepid_txt = getenv("FLWRAPPER_BASEPID");
  1442. int basepid = 0, txtpos=0;
  1443. if (basepid_txt)
  1444. basepid = atoi(basepid_txt);
  1445. addptree(&txtpos, cmdtxt, getpid(), basepid);
  1446. cmdname = strdup(cmdtxt);
  1447. wlog = getenv("FLWRAPPER_WLOG");
  1448. rlog = getenv("FLWRAPPER_RLOG");
  1449. # if DEBUG == 1
  1450. char *debugwrapper = getenv("FLWRAPPER_DEBUG");
  1451. if (debugwrapper) debug = atoi(debugwrapper);
  1452. # endif
  1453. }
  1454. /*
  1455. Clean up file descriptors still registered for this pid, if any.
  1456. */
  1457. void __attribute__ ((destructor)) fl_wrapper_finish()
  1458. {
  1459. # if DEBUG == 1
  1460. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: fl_wrapper_finish()\n", getpid());
  1461. # endif
  1462. struct pid_reg **pid = find_pid(getpid());
  1463. if (*pid)
  1464. {
  1465. # if DEBUG == 1
  1466. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: PID still registered!\n", getpid());
  1467. # endif
  1468. struct fd_reg **fd = &(*pid)->fd_head;
  1469. while (*fd)
  1470. {
  1471. handle_file_access_after("fl_wrapper_finish", (*fd)->filename, &(*fd)->status);
  1472. remove_fd(fd);
  1473. }
  1474. remove_pid(pid);
  1475. }
  1476. }
  1477. static void handle_file_access_before(const char * func, const char * file,
  1478. struct status_t * status)
  1479. {
  1480. struct stat st;
  1481. # if DEBUG == 1
  1482. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  1483. getpid(), func, file);
  1484. # endif
  1485. if ( lstat(file,&st) ) {
  1486. status->inode=0; status->size=0;
  1487. status->mtime=0; status->ctime=0;
  1488. } else {
  1489. status->inode=st.st_ino; status->size=st.st_size;
  1490. status->mtime=st.st_mtime; status->ctime=st.st_ctime;
  1491. }
  1492. # if DEBUG == 1
  1493. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_before(\"%s\", \"%s\", xxx)\n",
  1494. getpid(), func, file);
  1495. # endif
  1496. }
  1497. /*
  1498. Declared in fl_wrapper_open.c and fl_wrapper_close.c,
  1499. reused here since logging access to the log files eventually
  1500. overwrites close'd but not yet deregistered file descriptors.
  1501. int (*orig_open)(const char* f, int a, ...) = 0;
  1502. int (*orig_open64)(const char* f, int a, ...) = 0;
  1503. int (*orig_close)(int fd) = 0;
  1504. */
  1505. static void handle_file_access_after(const char * func, const char * file,
  1506. struct status_t * status)
  1507. {
  1508. char buf[512], *buf2, *logfile;
  1509. int fd; struct stat st;
  1510. #ifdef __USE_LARGEFILE
  1511. if (!orig_open64) orig_open64 = get_dl_symbol("open64");
  1512. #else
  1513. if (!orig_open) orig_open = get_dl_symbol("open");
  1514. #endif
  1515. if (!orig_close) orig_close = get_dl_symbol("close");
  1516. # if DEBUG == 1
  1517. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: begin of handle_file_access_after(\"%s\", \"%s\", xxx), %d, %s, %s\n",
  1518. getpid(), func, file, status != 0, wlog, rlog);
  1519. # endif
  1520. if ( lstat(file, &st) )
  1521. {
  1522. # if DEBUG == 1
  1523. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: lstat(%s, ...) failed\n",
  1524. getpid(), file);
  1525. # endif
  1526. return;
  1527. }
  1528. if ( (status != 0) && (status->inode != st.st_ino ||
  1529. status->size != st.st_size || status->mtime != st.st_mtime ||
  1530. status->ctime != st.st_ctime) ) { logfile = wlog; }
  1531. else { logfile = rlog; }
  1532. if ( logfile == 0 )
  1533. {
  1534. # if DEBUG == 1
  1535. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: no log file\n",
  1536. getpid());
  1537. # endif
  1538. return;
  1539. }
  1540. #ifdef __USE_LARGEFILE
  1541. fd=orig_open64(logfile,O_APPEND|O_WRONLY|O_LARGEFILE,0);
  1542. #else
  1543. #warning "The wrapper library will not work properly for large logs!"
  1544. fd=orig_open(logfile,O_APPEND|O_WRONLY,0);
  1545. #endif
  1546. if (fd == -1)
  1547. {
  1548. # if DEBUG == 1
  1549. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: log open failed (%s)\n",
  1550. getpid(), strerror(errno));
  1551. # endif
  1552. return;
  1553. }
  1554. if (file[0] == '/') {
  1555. sprintf(buf,"%s.%s:\t%s\n",
  1556. cmdname, func, file);
  1557. } else {
  1558. buf2=get_current_dir_name();
  1559. sprintf(buf,"%s.%s:\t%s%s%s\n",
  1560. cmdname, func, buf2,
  1561. strcmp(buf2,"/") ? "/" : "", file);
  1562. free(buf2);
  1563. }
  1564. write(fd,buf,strlen(buf));
  1565. orig_close(fd);
  1566. # if DEBUG == 1
  1567. if (debug) fprintf(stderr, "fl_wrapper.so debug [%d]: end of handle_file_access_after(\"%s\", \"%s\", xxx)\n",
  1568. getpid(), func, file);
  1569. # endif
  1570. }