From 1c1a74f4e2668dd6d27b0a322a66c19da8ecd14d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 2 Jul 2009 13:02:39 +0930 Subject: [PATCH] More junkcode! --- junkcode/fork0@users.sf.net-bitmaps/bitmaps.h | 78 ++++++++ junkcode/fork0@users.sf.net-timeout/timeout.c | 173 ++++++++++++++++++ 2 files changed, 251 insertions(+) create mode 100644 junkcode/fork0@users.sf.net-bitmaps/bitmaps.h create mode 100644 junkcode/fork0@users.sf.net-timeout/timeout.c diff --git a/junkcode/fork0@users.sf.net-bitmaps/bitmaps.h b/junkcode/fork0@users.sf.net-bitmaps/bitmaps.h new file mode 100644 index 00000000..05ecd962 --- /dev/null +++ b/junkcode/fork0@users.sf.net-bitmaps/bitmaps.h @@ -0,0 +1,78 @@ +/* bitmaps and bitmap operations */ +#ifndef _BITMAPS_H_ +#define _BITMAPS_H_ + +/* + * Bitmaps are arrays of unsigned ints, filled with bits in most- + * significant-first order. So bitmap[0] shall contain the bits from + * 0 to 31 on a 32bit architecture, bitmap[1] - 32-63, and so forth. + * + * The callers are responsible to do all the bounds-checking. + */ +enum { BITS_PER_BITMAP_ELEM = 8 * sizeof(unsigned) }; + +typedef unsigned bitmap_elem_t; + +/* returned is the unshifted bit state. IOW: NOT 0 or 1, but something + * like 0x00001000 or 0x40000000 */ +static inline +bitmap_elem_t bitmap_test_bit(const bitmap_elem_t* bits, unsigned bit) +{ + if ( sizeof(*bits) == 4 ) + return bits[bit >> 5] & (0x80000000 >> (bit & 0x1f)); + else if ( sizeof(*bits) == 8 ) + return bits[bit >> 6] & (0x8000000000000000ull >> (bit & 0x3f)); + else + { + return bits[bit / BITS_PER_BITMAP_ELEM] & + 1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1); + } +} + +static inline +bitmap_elem_t bitmap_set_bit(bitmap_elem_t* bits, unsigned bit) +{ + if ( sizeof(*bits) == 4 ) + return bits[bit >> 5] |= (0x80000000 >> (bit & 0x1f)); + else if ( sizeof(*bits) == 8 ) + return bits[bit >> 6] |= (0x8000000000000000ull >> (bit & 0x3f)); + else + { + return bits[bit / BITS_PER_BITMAP_ELEM] |= + 1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1); + } +} + +/* pos must position the bits inside of a bitmap element, otherwise + * the index shift puts the bits in the wrong word (for simplicity). + * Only low 8 bits of b8 shall be used */ +static inline +void bitmap_set_8bits_fast(bitmap_elem_t* bits, unsigned pos, unsigned b8) +{ + if ( sizeof(*bits) == 4 ) + bits[pos >> 5] |= b8 << (24 - (pos & 0x1f)); + else if ( sizeof(*bits) == 8 ) + bits[pos >> 6] |= b8 << (56 - (pos & 0x3f)); + else + { + bits[pos / BITS_PER_BITMAP_ELEM] |= + b8 << (BITS_PER_BITMAP_ELEM - 8 - pos % BITS_PER_BITMAP_ELEM); + } +} + +static inline +bitmap_elem_t bitmap_clear_bit(bitmap_elem_t* bits, unsigned bit) +{ + if ( sizeof(*bits) == 4 ) + return bits[bit >> 5] &= ~(0x80000000 >> (bit & 0x1f)); + else if ( sizeof(*bits) == 8 ) + return bits[bit >> 6] &= ~(0x8000000000000000ull >> (bit & 0x3f)); + else + { + return bits[bit / BITS_PER_BITMAP_ELEM] &= + ~(1 << ((BITS_PER_BITMAP_ELEM - bit % BITS_PER_BITMAP_ELEM) - 1)); + } +} + +#endif /* _BITMAPS_H_ */ + diff --git a/junkcode/fork0@users.sf.net-timeout/timeout.c b/junkcode/fork0@users.sf.net-timeout/timeout.c new file mode 100644 index 00000000..290e4276 --- /dev/null +++ b/junkcode/fork0@users.sf.net-timeout/timeout.c @@ -0,0 +1,173 @@ +/* execute a program with a timeout by alarm(2) */ +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include + +static const char *argv0; +static char **prgargv; +static pid_t pid; +static int signo; +static unsigned int timeout; + +static void timedout(int sig) +{ + fprintf(stderr, "%s[%d]: %s[%d] timed out after %u sec\n", + argv0, getpid(), *prgargv, pid, timeout); + if (pid) + kill(-pid, signo); +} + +static void interrupted(int sig) +{ + alarm(0); + if (pid) + kill(-pid, sig); +} + +static void usage() +{ + fprintf(stderr, "%s [-] program ...\n" + "Where is a signal number (see kill -l).\n" + "Some symbolic names recognized. KILL used by default\n", + argv0); + exit(1); +} + +static struct { + const char *name; + int signo; +} known[] = { + {"HUP", SIGHUP}, + {"INT", SIGINT}, + {"QUIT", SIGQUIT}, + {"ILL", SIGILL}, + {"TRAP", SIGTRAP}, + {"ABRT", SIGABRT}, + {"BUS", SIGBUS}, + {"FPE", SIGFPE}, + {"KILL", SIGKILL}, + {"USR1", SIGUSR1}, + {"SEGV", SIGSEGV}, + {"USR2", SIGUSR2}, + {"PIPE", SIGPIPE}, + {"ALRM", SIGALRM}, + {"TERM", SIGTERM}, + {"STKFLT", SIGSTKFLT}, + {"CHLD", SIGCHLD}, + {"CONT", SIGCONT}, + {"STOP", SIGSTOP}, + {"TSTP", SIGTSTP}, + {"TTIN", SIGTTIN}, + {"TTOU", SIGTTOU}, + {"URG", SIGURG}, + {"XCPU", SIGXCPU}, + {"XFSZ", SIGXFSZ}, + {"VTALRM", SIGVTALRM}, + {"PROF", SIGPROF}, + {"WINCH", SIGWINCH}, + {"IO", SIGIO}, + {"PWR", SIGPWR}, + {"SYS", SIGSYS}, +}; + +static int signo_arg(const char *arg) +{ + if (*arg == '-') { + char *p; + int s = strtol(++arg, &p, 10); + if (!*p && p > arg && s > 0 && s < _NSIG) { + signo = s; + return 1; + } + if (!strncasecmp(arg, "SIG", 3)) + arg += 3; + for (s = 0; s < sizeof(known)/sizeof(*known); ++s) + if (!strcasecmp(arg, known[s].name)) { + signo = known[s].signo; + return 1; + } + } + return 0; +} + +int main(int argc, char** argv) +{ + argv0 = strrchr(*argv, '/'); + if (argv0) + ++argv0; + else + argv0 = *argv; + + signal(SIGALRM, timedout); + signal(SIGINT, interrupted); + signal(SIGHUP, interrupted); + + ++argv; + + if (!*argv) + usage(); + + if (signo_arg(*argv)) + ++argv; + if (sscanf(*argv, "%u", &timeout) == 1) + ++argv; + else + usage(); + if (!signo && signo_arg(*argv)) + ++argv; + if (!signo) + signo = SIGKILL; + + if (!*argv) + usage(); + + prgargv = argv; + alarm(timeout); + pid = fork(); + + if (!pid) { + signal(SIGALRM, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGHUP, SIG_DFL); + setpgid(0, 0); + execvp(*prgargv, prgargv); + fprintf(stderr, "%s: %s: %s\n", + argv0, *prgargv, strerror(errno)); + _exit(2); + } else if (pid < 0) { + fprintf(stderr, "%s: %s\n", argv0, strerror(errno)); + } else { + int status; + while (waitpid(pid, &status, 0) < 0 && EINTR == errno) + ; + alarm(0); + if (WIFEXITED(status)) + return WEXITSTATUS(status); + if (WIFSIGNALED(status)) { + /* + * Some signals are special, lets die with + * the same signal as child process + */ + if (WTERMSIG(status) == SIGHUP || + WTERMSIG(status) == SIGINT || + WTERMSIG(status) == SIGTERM || + WTERMSIG(status) == SIGQUIT || + WTERMSIG(status) == SIGKILL) { + signal(WTERMSIG(status), SIG_DFL); + raise(WTERMSIG(status)); + } + fprintf(stderr, "%s: %s: %s\n", + argv0, *prgargv, strsignal(WTERMSIG(status))); + } + else + fprintf(stderr, "%s died\n", *prgargv); + } + return 2; +} -- 2.39.2