add run wrapper, move t_printf and t_status into separate translation unit
authorSzabolcs Nagy <nsz@port70.net>
Sun, 21 Jul 2013 21:44:41 +0000 (21:44 +0000)
committerSzabolcs Nagy <nsz@port70.net>
Sun, 21 Jul 2013 21:44:41 +0000 (21:44 +0000)
Makefile
src/common/path.c
src/common/print.c [new file with mode: 0644]
src/common/run.c [new file with mode: 0644]
src/common/setrlim.c [new file with mode: 0644]
src/common/test.h
src/functional/sem.c
src/functional/sscanf_long.c

index 96cc89a..3383bad 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 SRCS:=$(sort $(wildcard src/*/*.c))
 OBJS:=$(SRCS:%.c=%.o)
-DIRS:=$(sort $(wildcard src/*))
+DIRS:=$(filter-out src/common,$(sort $(wildcard src/*)))
 NAMES:=$(OBJS:.o=)
 SPEC_PATTERNS:=src/common/% src/api/% src/math/%
 CFLAGS:=-Isrc/common
@@ -29,6 +29,13 @@ BINS:=$(foreach n,$(NAMES),$($(n).BINS)) src/api/main $(MBINS)
 LIBS:=$(foreach n,$(NAMES),$($(n).LIBS))
 ERRS:=$(BINS:%=%.err)
 
+debug:
+       @echo MBINS $(MBINS)
+       @echo BINS $(BINS)
+       @echo LIBS $(LIBS)
+       @echo ERRS $(ERRS)
+       @echo DIRS $(DIRS)
+
 define target_template
 $(1)/all: $(1)/REPORT
 $(1)/clean:
@@ -41,11 +48,16 @@ endef
 
 $(foreach d,$(DIRS),$(eval $(call target_template,$(d))))
 
-src/common/all: src/common/libtest.a
+src/common/all: src/common/REPORT
+src/common/REPORT: src/common/run
+       cat src/common/*.err >$@
+REPORT: src/common/REPORT
+src/common/run: src/common/run.o src/common/libtest.a
+$(ERRS): src/common/run
 
 all:REPORT
 clean:
-       rm -f $(OBJS) $(BINS) $(LIBS) src/common/libtest.a src/*/*.err
+       rm -f $(OBJS) $(BINS) $(LIBS) src/common/libtest.a src/common/run src/*/*.err
 cleanall: clean
        rm -f REPORT src/*/REPORT
 REPORT:
@@ -89,7 +101,7 @@ $(IOBJS):CFLAGS+=-DX_PS -DX_TPS -DX_SS
        touch $@
 %.err: %
 # TODO: proper wrapping that records exit status
-       ./$< 2>/dev/null >$@ || true
+       src/common/run ./$< 2>/dev/null >$@ || true
 
 .PHONY: all clean cleanall
 
index 4fd7633..6ca9951 100644 (file)
@@ -1,4 +1,5 @@
 #include <string.h>
+#include <stdio.h>
 #include "test.h"
 
 /* relative path to p */
diff --git a/src/common/print.c b/src/common/print.c
new file mode 100644 (file)
index 0000000..45a4fd5
--- /dev/null
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+volatile int t_status = 0;
+
+int t_printf(const char *s, ...)
+{
+       va_list ap;
+       char buf[512];
+       int n;
+
+       t_status = 1;
+       va_start(ap, s);
+       n = vsnprintf(buf, sizeof buf, s, ap);
+       va_end(ap);
+       if (n < 0)
+               n = 0;
+       else if (n >= sizeof buf) {
+               n = sizeof buf;
+               buf[n - 1] = '\n';
+               buf[n - 2] = '.';
+               buf[n - 3] = '.';
+               buf[n - 4] = '.';
+       }
+       return write(1, buf, n);
+}
diff --git a/src/common/run.c b/src/common/run.c
new file mode 100644 (file)
index 0000000..8a2a0f3
--- /dev/null
@@ -0,0 +1,87 @@
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#include "test.h"
+
+static void handler(int s)
+{
+}
+
+static void setrl(int r, long lim) {
+       struct rlimit rl;
+
+       if (getrlimit(r, &rl))
+               t_error("getrlimit %d: %s\n", r, strerror(errno));
+       rl.rlim_cur = lim;
+       if (lim < rl.rlim_max)
+               rl.rlim_max = lim;
+       if (setrlimit(r, &rl))
+               t_error("setrlimit %d: %s\n", r, strerror(errno));
+}
+
+static int start(char *argv[])
+{
+       int pid;
+
+       pid = fork();
+       if (pid == 0) {
+               setrl(RLIMIT_STACK, 100*1024);
+               setrl(RLIMIT_CPU, 2);
+               execv(argv[0], argv);
+               t_error("%s exec failed: %s\n", argv[0], strerror(errno));
+               exit(1);
+       }
+       if (pid == -1) {
+               t_error("%s fork failed: %s\n", argv[0], strerror(errno));
+               exit(-1);
+       }
+       return pid;
+}
+
+int main(int argc, char *argv[])
+{
+       int status;
+       sigset_t set;
+       int timeout = 0;
+       int sig = 0;
+       int pid;
+
+       if (argc < 2) {
+               t_error("usage: ./run cmd [args..]\n");
+               return -1;
+       }
+       argv++;
+       sigemptyset(&set);
+       sigaddset(&set, SIGCHLD);
+       sigprocmask(SIG_BLOCK, &set, 0);
+       signal(SIGCHLD, handler);
+       pid = start(argv);
+       if (sigtimedwait(&set, 0, &(struct timespec){5,0}) == -1) {
+               if (errno == EAGAIN)
+                       timeout = 1;
+               if (kill(pid, SIGKILL) == -1)
+                       t_error("%s kill failed: %s\n", argv[0], strerror(errno));
+       }
+       if (waitpid(pid, &status, 0) != pid) {
+               t_error("%s waitpid failed: %s\n", argv[0], strerror(errno));
+               return -1;
+       }
+       if (WIFEXITED(status)) {
+               if (WEXITSTATUS(status) == 0)
+                       return 0;
+               t_printf("FAIL %s [status %d]\n", argv[0], WEXITSTATUS(status));
+       } else if (timeout) {
+               t_printf("FAIL %s [timed out]\n", argv[0]);
+       } else if (WIFSIGNALED(status)) {
+               t_printf("FAIL %s [signal %s]\n", argv[0], strsignal(WTERMSIG(status)));
+       } else
+               t_printf("FAIL %s [unknown]\n", argv[0]);
+       return 1;
+}
diff --git a/src/common/setrlim.c b/src/common/setrlim.c
new file mode 100644 (file)
index 0000000..fc76a8e
--- /dev/null
@@ -0,0 +1,26 @@
+#include <string.h>
+#include <errno.h>
+#include <sys/resource.h>
+#include "test.h"
+
+int t_setrlim(int r, long lim)
+{
+       struct rlimit rl;
+
+       if (getrlimit(r, &rl)) {
+               t_error("getrlimit %d: %s\n", r, strerror(errno));
+               return -1;
+       }
+       if (lim > rl.rlim_max)
+               return -1;
+       if (lim == rl.rlim_max && lim == rl.rlim_cur)
+               return 0;
+       rl.rlim_max = lim;
+       rl.rlim_cur = lim;
+       if (setrlimit(r, &rl)) {
+               t_error("setrlimit %d: %s\n", r, strerror(errno));
+               return -1;
+       }
+       return 0;
+}
+
index e24a1db..21e5caf 100644 (file)
@@ -1,36 +1,14 @@
 #include <stdint.h>
-#include <stdio.h>
-#include <stdarg.h>
 #include <unistd.h>
 
 /* TODO: not thread-safe nor fork-safe */
-static volatile int t_status;
+extern volatile int t_status;
 
 #define T_LOC2(l) __FILE__ ":" #l
 #define T_LOC1(l) T_LOC2(l)
-#define t_error(...) t_printf("ERROR " T_LOC1(__LINE__) ": " __VA_ARGS__)
-
-static int t_printf(const char *s, ...)
-{
-       va_list ap;
-       char buf[512];
-       int n;
-
-       t_status = 1;
-       va_start(ap, s);
-       n = vsnprintf(buf, sizeof buf, s, ap);
-       va_end(ap);
-       if (n < 0)
-               n = 0;
-       else if (n >= sizeof buf) {
-               n = sizeof buf;
-               buf[n - 1] = '\n';
-               buf[n - 2] = '.';
-               buf[n - 3] = '.';
-               buf[n - 4] = '.';
-       }
-       return write(1, buf, n);
-}
+#define t_error(...) t_printf(T_LOC1(__LINE__) ": " __VA_ARGS__)
+
+int t_printf(const char *s, ...);
 
 int t_vmfill(void **, size_t *, int);
 
@@ -45,3 +23,5 @@ int t_choose(uint64_t n, size_t k, uint64_t *p);
 
 char *t_pathrel(char *buf, size_t n, char *argv0, char *p);
 
+int t_setrlim(int r, long lim);
+
index d953a8e..86662b6 100644 (file)
@@ -1,4 +1,5 @@
 #include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 #include <string.h>
 #include <semaphore.h>
index 160648b..c9208af 100644 (file)
@@ -6,17 +6,6 @@
 #include <sys/resource.h>
 #include "test.h"
 
-static void setrl(int r, long lim)
-{
-       struct rlimit rl;
-
-       if (getrlimit(r, &rl))
-               t_error("getrlimit %d: %s\n", r, strerror(errno));
-       rl.rlim_cur = lim;
-       if (setrlimit(r, &rl))
-               t_error("setrlimit %d: %s\n", r, strerror(errno));
-}
-
 int main(void)
 {
        enum {n = 8*1024*1024};
@@ -27,7 +16,7 @@ int main(void)
 
        if (!s)
                return t_error("out of memory");
-       setrl(RLIMIT_STACK, 128*1024);
+       t_setrlim(RLIMIT_STACK, 100*1024);
 
        for (i = 0; i < n; i++) s[i] = '1';
        s[n-3] = ' ';