diff options
Diffstat (limited to '')
-rw-r--r-- | src/common.h | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/common.h b/src/common.h index 68d465e..187723e 100644 --- a/src/common.h +++ b/src/common.h @@ -47,6 +47,43 @@ static const char *failed__ = NULL; /** + * A queued job. + */ +struct job { + /** + * The job number. + */ + size_t no; + + /** + * The number of “argv” elements in `payload`. + */ + int argc; + + /** + * The clock in which `ts` is measured. + */ + clockid_t clk; + + /** + * The time when the job shall be executed. + */ + struct timespec ts; + + /** + * The number of bytes in `payload`. + */ + size_t n; + + /** + * “argv” followed by “envp”. + */ + char payload[]; +}; + + + +/** * Defines the function `void usage(void)` * that prints usage information. * @@ -132,3 +169,49 @@ fail: \ free(msg); \ return 1; + +/** + * This block of code allows us to compile with DEBUG=valgrind + * or DEBUG=strace and have all exec:s be wrapped in + * valgrind --leak-check=full --show-leak-kinds=all or + * strace, respectively. Very useful for debugging. However, + * children do not inherit strace, so between forking and + * exec:ing we do not have strace. + */ +#if 1 && defined(DEBUG) +# if ((DEBUG == 2) || (DEBUG == 3)) +# ifdef __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wdiscarded-qualifiers" +__attribute__((__used__)) +# endif +# if DEBUG == 2 +# define DEBUGPROG "strace" +# else +# define DEBUGPROG "valgrind" +# endif +# define execl(path, _, ...) (execl)("/usr/bin/" DEBUGPROG, "/usr/bin/" DEBUGPROG, path, __VA_ARGS__) +# define execve(...) execve_(__VA_ARGS__) +static int +execve_(const char *path, char *const argv[], char *const envp[]) +{ + size_t n = 0; + char **new_argv = NULL; + int x = (DEBUG - 2) * 2, saved_errno; + while (argv[n++]); + t (!(new_argv = malloc((n + 1 + (size_t)x) * sizeof(char *)))); + new_argv[x] = "--show-leak-kinds=all"; + new_argv[1] = "--leak-check=full"; + new_argv[0] = "/usr/bin/" DEBUGPROG; + new_argv[1 + x] = path; + memcpy(new_argv + 2 + x, argv + 1, (n - 1) * sizeof(char *)); + (execve)(*new_argv, new_argv, envp); +fail: + return saved_errno = errno, free(new_argv), errno = saved_errno, -1; +} +# ifdef __GNUC__ +# pragma GCC diagnostic pop +# endif +# endif +#endif + |