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.

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