Browse Source

More junkcode!

Rusty Russell 16 years ago
parent
commit
1c1a74f4e2

+ 78 - 0
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_ */
+

+ 173 - 0
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 <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;
+}