#include #include #include #include #include #include #include #include extern const char *__progname; #include "test.h" struct kid { pid_t pid; } ; typedef struct shared SHARED; struct shared { int failed; } ; static pid_t parent = 0; static pid_t mypid = 0; static SHARED *shared; void test_init(void) { void *mmrv; int pgsz; int size; pgsz = getpagesize(); size = ((sizeof(SHARED) + pgsz - 1) / pgsz) * pgsz; mmrv = mmap(0,size,PROT_READ|PROT_WRITE,MAP_ANON|MAP_SHARED,-1,0); if (mmrv == MAP_FAILED) { fprintf(stderr,"%s: mmap shared space: %s\n",__progname,strerror(errno)); sleep(1); exit(1); } shared = mmrv; shared->failed = 0; } void call_failed(const char *call) { fprintf(stderr,"%s: %s failed (%d), expected success\n",__progname,call,errno); test_fail(); } void call_worked(const char *call) { fprintf(stderr,"%s: %s worked, expected failure\n",__progname,call); test_fail(); } void wrong_error(const char *call, int got, int exp) { char *sg; char *se; sg = strdup(strerror(got)); se = strdup(strerror(exp)); fprintf(stderr,"%s: %s failed %d [%s], expected %d [%s]\n",__progname,call,got,sg,exp,se); free(sg); free(se); test_fail(); } void mustwrite(int fd, const void *data, int len) { const unsigned char *dp; int n; dp = data; while (len > 0) { n = write(fd,dp,len); if (n < 0) { fprintf(stderr,"%s: write: %s\n",__progname,strerror(errno)); test_fail(); } dp += n; len -= n; } } void mustread(int fd, void *data, int len) { unsigned char *dp; int n; dp = data; while (len > 0) { n = read(fd,dp,len); if (n < 0) { fprintf(stderr,"%s: read: %s\n",__progname,strerror(errno)); test_fail(); } if (n == 0) { fprintf(stderr,"%s: read got unexpected EOF\n",__progname); test_fail(); } dp += n; len -= n; } } void local_socketpair(int *fd1, int *fd2) { int p[2]; if (socketpair(AF_LOCAL,SOCK_STREAM,0,&p[0]) < 0) { fprintf(stderr,"%s: socketpair: %s\n",__progname,strerror(errno)); sleep(1); exit(1); } *fd1 = p[0]; *fd2 = p[1]; } KID *fork_kid(void (*fn)(void *), void *arg) { KID *k; if (mypid == 0) mypid = getpid(); fflush(0); k = malloc(sizeof(KID)); k->pid = fork(); if (k->pid < 0) { fprintf(stderr,"%s: fork: %s\n",__progname,strerror(errno)); test_fail(); } if (k->pid == 0) { parent = mypid; (*fn)(arg); _exit(0); } return(k); } void reap_kid(KID *k) { pid_t dead; while (1) { dead = wait4(k->pid,0,0,0); if (dead < 0) { if (errno == EINTR) continue; fprintf(stderr,"%s: wait4: %s\n",__progname,strerror(errno)); test_fail(); } if (dead == k->pid) break; fprintf(stderr,"%s: wait4 got child %d, expected %d\n",__progname,(int)dead,(int)k->pid); } free(k); } void panic_(const char *f, int l) { fprintf(stderr,"%s: panic: \"%s\", line %d\n",__progname,f,l); fflush(0); shared->failed = 1; sleep(1); abort(); } void test_fail(void) { printf("\n\nTEST FAILED\n"); shared->failed = 1; sleep(1); exit(1); } int test_failed(void) { return(shared->failed); } LLI tstamp(void) { struct timeval tv; gettimeofday(&tv,0); return((tv.tv_sec*1000000LL)+(tv.tv_usec*1LL)); }