From: Szabolcs Nagy Date: Fri, 5 Jul 2013 22:12:13 +0000 (+0000) Subject: add new tests from libc-testsuit (fcntl, f[w]scanf, setjmp, socket, stat) X-Git-Url: http://nsz.repo.hu/git/?p=libc-test;a=commitdiff_plain;h=0c5fb5124c162a631c247ed63c3a995df2914ff8 add new tests from libc-testsuit (fcntl, f[w]scanf, setjmp, socket, stat) --- diff --git a/src/functional/fcntl.c b/src/functional/fcntl.c new file mode 100644 index 0000000..83ea950 --- /dev/null +++ b/src/functional/fcntl.c @@ -0,0 +1,49 @@ +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(c, ...) ((c) ? 1 : (error(#c" failed: " __VA_ARGS__),0)) +#define TESTE(c) (errno=0, TEST(c, "errno = %s\n", strerror(errno)) + +int main(void) +{ + struct flock fl = {0}; + FILE *f; + int fd; + pid_t pid; + int status; + + if (!TESTE(f=tmpfile())) return test_status; + fd = fileno(f); + + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + TESTE(fcntl(fd, F_SETLK, &fl)==0); + + pid = fork(); + if (!pid) { + fl.l_type = F_RDLCK; + _exit(fcntl(fd, F_SETLK, &fl)==0 || + (errno!=EAGAIN && errno!=EACCES)); + } + while (waitpid(pid, &status, 0)<0 && errno==EINTR); + TEST(status==0, "lock failed to work\n"); + + pid = fork(); + if (!pid) { + fl.l_type = F_WRLCK; + _exit(fcntl(fd, F_GETLK, &fl) || fl.l_pid != getppid()); + } + while (waitpid(pid, &status, 0)<0 && errno==EINTR); + TEST(status==0, "child failed to detect lock held by parent\n"); + + fclose(f); + + return test_status; +} diff --git a/src/functional/fscanf.c b/src/functional/fscanf.c index 62627b7..c8063e0 100644 --- a/src/functional/fscanf.c +++ b/src/functional/fscanf.c @@ -1,4 +1,3 @@ -#include #include #include #include @@ -6,46 +5,129 @@ #include #include "test.h" -#define T(f, x, m) do { \ - r = (f); \ - if (r != (x)) \ - error("%s failed (got %d, expected %d, errno \"%s\") (%s)\n", \ - #f, r, x, errno ? strerror(errno) : "", m); \ - errno = 0; \ -} while (0) +#define TEST(r, f, x, m) ( \ + errno=0, ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) ) -#define S(s, x, m) do { \ - if (strcmp(s, x) != 0) \ - error("got [%s] want [%s] (%s)\n", s, x, m); \ -} while(0) +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +static FILE *writetemp(const char *data) +{ + FILE *f = tmpfile(); + if (!f) return 0; + if (!fwrite(data, strlen(data), 1, f)) { + fclose(f); + return 0; + } + rewind(f); + return f; +} int main(void) { - int r, x, y; + int i, x, y; + double u; char a[100], b[100]; - int p[2]; FILE *f; + int p[2]; + + TEST(i, pipe(p), 0, "failed to open pipe %d!=%d (%s)"); + TEST(i, !(f = fdopen(p[0], "rb")), 0, "failed to fdopen pipe %d!=%d (%s)"); - T(pipe(p), 0, "open pipe"); - T(!(f = fdopen(p[0], "rb")), 0, "fdopen pipe"); if (!f) { close(p[0]); close(p[1]); - return test_status; + return 1; } - T(write(p[1], "hello, world\n", 13), 13, "write to pipe"); - T(fscanf(f, "%s %[own]", a, b), 2, ""); - S(a, "hello,", "wrong result for %s"); - S(b, "wo", "wrong result for %[own]"); - T(fgetc(f), 'r', "fgetc 'r'"); + TEST(i, write(p[1], "hello, world\n", 13), 13, "write error %d!=%d (%s)"); + TEST(i, fscanf(f, "%s %[own]", a, b), 2, "got %d fields, expected %d"); + TEST_S(a, "hello,", "wrong result for %s"); + TEST_S(b, "wo", "wrong result for %[own]"); + TEST(i, fgetc(f), 'r', "'%c' != '%c') (%s)"); - T(write(p[1], " 0x12 0x34", 10), 10, ""); - T(fscanf(f, "ld %5i%2i", &x, &y), 1, ""); - T(x, 0x12, ""); - T(fgetc(f), '3', "fgetc '3'"); + TEST(i, write(p[1], " 0x12 0x34", 10), 10, "write error %d!=%d (%s)"); + TEST(i, fscanf(f, "ld %5i%2i", &x, &y), 1, "got %d fields, expected %d"); + TEST(i, x, 0x12, "%d != %d"); + TEST(i, fgetc(f), '3', "'%c' != '%c'"); fclose(f); close(p[1]); + + TEST(i, !!(f=writetemp(" 42")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fscanf(f, " %n%*d%n", &x, &y), 0, "%d != %d"); + TEST(i, x, 6, "%d != %d"); + TEST(i, y, 8, "%d != %d"); + TEST(i, ftell(f), 8, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("[abc123]....x")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fscanf(f, "%10[^]]%n%10[].]%n", a, &x, b, &y), 2, "%d != %d"); + TEST_S(a, "[abc123", "wrong result for %[^]]"); + TEST_S(b, "]....", "wrong result for %[].]"); + TEST(i, x, 7, "%d != %d"); + TEST(i, y, 12, "%d != %d"); + TEST(i, ftell(f), 12, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'x', "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0x1p 12")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + u=-1; + TEST(i, fscanf(f, "%lf%n %d", &u, &x, &y), 0, "%d != %d"); + TEST(u, u, -1.0, "%g != %g"); + TEST(i, x, -1, "%d != %d"); + TEST(i, y, -1, "%d != %d"); + TEST(i, ftell(f), 4, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), ' ', "%d != %d"); + rewind(f); + TEST(i, fgetc(f), '0', "%d != %d"); + TEST(i, fgetc(f), 'x', "%d != %d"); + TEST(i, fscanf(f, "%lf%n%c %d", &u, &x, a, &y), 3, "%d != %d"); + TEST(u, u, 1.0, "%g != %g"); + TEST(i, x, 1, "%d != %d"); + TEST(i, a[0], 'p', "%d != %d"); + TEST(i, y, 12, "%d != %d"); + TEST(i, ftell(f), 7, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0x.1p4 012")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + u=-1; + TEST(i, fscanf(f, "%lf%n %i", &u, &x, &y), 2, "%d != %d"); + TEST(u, u, 1.0, "%g != %g"); + TEST(i, x, 6, "%d != %d"); + TEST(i, y, 10, "%d != %d"); + TEST(i, ftell(f), 13, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0xx")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fscanf(f, "%x%n", &x, &y), 0, "%d != %d"); + TEST(i, x, -1, "%d != %d"); + TEST(i, y, -1, "%d != %d"); + TEST(i, ftell(f), 2, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + fclose(f); + } + return test_status; } diff --git a/src/functional/fwscanf.c b/src/functional/fwscanf.c new file mode 100644 index 0000000..70ba50b --- /dev/null +++ b/src/functional/fwscanf.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(r, f, x, m) ( \ + errno=0, ((r) = (f)) == (x) || \ + (error("%s failed (" m ")\n", #f, r, x, strerror(errno)), 0) ) + +#define TEST_S(s, x, m) ( \ + !strcmp((s),(x)) || \ + (error("[%s] != [%s] (%s)\n", s, x, m), 0) ) + +static FILE *writetemp(const char *data) +{ + FILE *f = tmpfile(); + if (!f) return 0; + if (!fwrite(data, strlen(data), 1, f)) { + fclose(f); + return 0; + } + rewind(f); + return f; +} + +int main(void) +{ + int i, x, y; + double u; + char a[100], b[100]; + FILE *f; + + TEST(i, !!(f=writetemp(" 42")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fwscanf(f, L" %n%*d%n", &x, &y), 0, "%d != %d"); + TEST(i, x, 6, "%d != %d"); + TEST(i, y, 8, "%d != %d"); + TEST(i, ftell(f), 8, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("[abc123]....x")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fwscanf(f, L"%10[^]]%n%10[].]%n", a, &x, b, &y), 2, "%d != %d"); + TEST_S(a, "[abc123", "wrong result for %[^]]"); + TEST_S(b, "]....", "wrong result for %[].]"); + TEST(i, x, 7, "%d != %d"); + TEST(i, y, 12, "%d != %d"); + TEST(i, ftell(f), 12, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), 'x', "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0x1p 12")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + u=-1; + TEST(i, fwscanf(f, L"%lf%n %d", &u, &x, &y), 0, "%d != %d"); + TEST(u, u, -1.0, "%g != %g"); + TEST(i, x, -1, "%d != %d"); + TEST(i, y, -1, "%d != %d"); + TEST(i, ftell(f), 4, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + TEST(i, fgetc(f), ' ', "%d != %d"); + rewind(f); + TEST(i, fgetc(f), '0', "%d != %d"); + TEST(i, fgetc(f), 'x', "%d != %d"); + TEST(i, fwscanf(f, L"%lf%n%c %d", &u, &x, a, &y), 3, "%d != %d"); + TEST(u, u, 1.0, "%g != %g"); + TEST(i, x, 1, "%d != %d"); + TEST(i, a[0], 'p', "%d != %d"); + TEST(i, y, 12, "%d != %d"); + TEST(i, ftell(f), 7, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0x.1p4 012")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + u=-1; + TEST(i, fwscanf(f, L"%lf%n %i", &u, &x, &y), 2, "%d != %d"); + TEST(u, u, 1.0, "%g != %g"); + TEST(i, x, 6, "%d != %d"); + TEST(i, y, 10, "%d != %d"); + TEST(i, ftell(f), 13, "%d != %d"); + TEST(i, !!feof(f), 1, "%d != %d"); + fclose(f); + } + + TEST(i, !!(f=writetemp("0xx")), 1, "failed to make temp file"); + if (f) { + x=y=-1; + TEST(i, fwscanf(f, L"%x%n", &x, &y), 0, "%d != %d"); + TEST(i, x, -1, "%d != %d"); + TEST(i, y, -1, "%d != %d"); + TEST(i, ftell(f), 2, "%d != %d"); + TEST(i, feof(f), 0, "%d != %d"); + fclose(f); + } + + return test_status; +} diff --git a/src/functional/setjmp.c b/src/functional/setjmp.c new file mode 100644 index 0000000..7bd534b --- /dev/null +++ b/src/functional/setjmp.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(c, ...) ((c) ? 1 : (error(#c" failed: " __VA_ARGS__),0)) +#define TESTE(c) (errno=0, TEST(c, "errno = %s\n", strerror(errno))) + +int main(void) +{ + volatile int x = 0, r; + jmp_buf jb; + sigjmp_buf sjb; + volatile sigset_t oldset; + sigset_t set; + + if (!setjmp(jb)) { + x = 1; + longjmp(jb, 1); + } + TEST(x==1, "setjmp/longjmp seems to have been bypassed\n"); + + x = 0; + r = setjmp(jb); + if (!x) { + x = 1; + longjmp(jb, 0); + } + TEST(r==1, "longjmp(jb, 0) caused setjmp to return %d\n", r); + + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + sigprocmask(SIG_UNBLOCK, &set, &set); + oldset = set; + + /* Improve the chances of catching failure of sigsetjmp to + * properly save the signal mask in the sigjmb_buf. */ + memset(&sjb, -1, sizeof sjb); + + if (!sigsetjmp(sjb, 1)) { + sigemptyset(&set); + sigaddset(&set, SIGUSR1); + sigprocmask(SIG_BLOCK, &set, 0); + siglongjmp(sjb, 1); + } + set = oldset; + sigprocmask(SIG_SETMASK, &set, &set); + TEST(sigismember(&set, SIGUSR1)==0, "siglongjmp failed to restore mask\n"); + + return test_status; +} diff --git a/src/functional/socket.c b/src/functional/socket.c new file mode 100644 index 0000000..fc01e67 --- /dev/null +++ b/src/functional/socket.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(c, ...) ((c) ? 1 : (error(#c" failed: " __VA_ARGS__),0)) +#define TESTE(c) (errno=0, TEST(c, "errno = %s\n", strerror(errno)) + +int main(void) +{ + struct sockaddr_in sa = { .sin_family = AF_INET }; + int s, c, t; + char buf[100]; + + TESTE((s=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP))>=0); + TESTE(bind(s, (void *)&sa, sizeof sa)==0); + TESTE(getsockname(s, (void *)&sa, (socklen_t[]){sizeof sa})==0); + + TESTE(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, + &(struct timeval){.tv_usec=1}, sizeof(struct timeval))==0); + + TESTE((c=socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP))>=0); + sa.sin_addr.s_addr = htonl(0x7f000001); + TESTE(sendto(c, "x", 1, 0, (void *)&sa, sizeof sa)==1); + TESTE(recvfrom(s, buf, sizeof buf, 0, (void *)&sa, (socklen_t[]){sizeof sa})==1); + TEST(buf[0]=='x', "'%c'\n", buf[0]); + + close(c); + close(s); + + memset(&sa, 0, sizeof sa); + sa.sin_family = AF_INET; + TESTE((s=socket(PF_INET, SOCK_STREAM|SOCK_CLOEXEC, IPPROTO_TCP))>=0); + TEST(fcntl(s, F_GETFD)&FD_CLOEXEC, "SOCK_CLOEXEC did not work\n"); + TESTE(bind(s, (void *)&sa, sizeof sa)==0); + TESTE(getsockname(s, (void *)&sa, (socklen_t[]){sizeof sa})==0); + sa.sin_addr.s_addr = htonl(0x7f000001); + + TESTE(listen(s, 1)==0); + + TESTE((c=socket(PF_INET, SOCK_STREAM|SOCK_NONBLOCK, IPPROTO_TCP))>=0); + TEST(fcntl(c, F_GETFL)&O_NONBLOCK, "SOCK_NONBLOCK did not work\n"); + + TESTE(connect(c, (void *)&sa, sizeof sa)==0 || errno==EINPROGRESS); + + TESTE((t=accept(s, (void *)&sa, &(socklen_t){sizeof sa}))>=0); + + close(t); + close(c); + close(s); + + return test_status; +} diff --git a/src/functional/stat.c b/src/functional/stat.c new file mode 100644 index 0000000..12abd7c --- /dev/null +++ b/src/functional/stat.c @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +#include +#include +#include "test.h" + +#define TEST(c, ...) ((c) ? 1 : (error(#c" failed: " __VA_ARGS__),0)) + +int main(void) +{ + struct stat st; + FILE *f; + time_t t; + + if (TEST(stat(".",&st)==0, "errno = %s\n", strerror(errno))) { + TEST(S_ISDIR(st.st_mode), "\n"); + TEST(st.st_nlink>0, "%ju\n", (uintmax_t)st.st_nlink); + t = time(0); + TEST(st.st_ctime<=t, "%jd > %jd\n", (intmax_t)st.st_ctime, (intmax_t)t); + TEST(st.st_mtime<=t, "%jd > %jd\n", (intmax_t)st.st_mtime, (intmax_t)t); + TEST(st.st_atime<=t, "%jd > %jd\n", (intmax_t)st.st_atime, (intmax_t)t); + } + + if (TEST(stat("/dev/null",&st)==0, "errno = %s\n", strerror(errno))) { + TEST(S_ISCHR(st.st_mode), "\n"); + } + + if ((f = tmpfile())) { + fputs("hello", f); + fflush(f); + if (TEST(fstat(fileno(f),&st)==0, "errnp = %s\n", strerror(errno))) { + TEST(st.st_uid==geteuid(), "%d vs %d\n", (int)st.st_uid, (int)geteuid()); + TEST(st.st_gid==getegid(), "%d vs %d\n", (int)st.st_uid, (int)geteuid()); + TEST(st.st_size==5, "%jd vs 5\n", (intmax_t)st.st_size); + } + fclose(f); + } + + return test_status; +} diff --git a/src/functional/strtol.c b/src/functional/strtol.c index 81df887..676a2c7 100644 --- a/src/functional/strtol.c +++ b/src/functional/strtol.c @@ -70,5 +70,11 @@ int main(void) TEST(l, strtol(s="123", &c, 37), 0, "%ld != %ld"); TEST2(i, c-s, 0, "wrong final position %d != %d"); TEST2(i, errno, EINVAL, "%d != %d"); + + TEST(l, strtol(s=" 15437", &c, 8), 015437, "%ld != %ld"); + TEST2(i, c-s, 7, "wrong final position %d != %d"); + + TEST(l, strtol(s=" 1", &c, 0), 1, "%ld != %ld"); + TEST2(i, c-s, 3, "wrong final position %d != %d"); return test_status; }