Commit 1c1a74f4 authored by Rusty Russell's avatar Rusty Russell

More junkcode!

parent 920193fe
/* 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_ */
/* execute a program with a timeout by alarm(2) */
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
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 <timeout-seconds> [-<signal>] program ...\n"
"Where <signal> 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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment