mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-28 08:12:28 +00:00
Improve cosmo's conformance to libc-test
This change addresses various open source compatibility issues, so that we pass 313/411 of the tests in https://github.com/jart/libc-test where earlier today we were passing about 30/411 of them, due to header toil. Please note that Glibc only passes 341/411 so 313 today is pretty good! - Make the conformance of libc/isystem/ headers nearly perfect - Import more of the remaining math library routines from Musl - Fix inconsistencies with type signatures of calls like umask - Write tests for getpriority/setpriority which work great now - conform to `struct sockaddr *` on remaining socket functions - Import a bunch of uninteresting stdlib functions e.g. rand48 - Introduce readdir_r, scandir, pthread_kill, sigsetjmp, etc.. Follow the instructions in our `tool/scripts/cosmocc` toolchain to run these tests yourself. You use `make CC=cosmocc` on the test repository
This commit is contained in:
parent
467a332e38
commit
e557058ac8
189 changed files with 5091 additions and 884 deletions
88
test/libc/calls/getpriority_test.c
Normal file
88
test/libc/calls/getpriority_test.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/prio.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/testlib/subprocess.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
void SetUp(void) {
|
||||
if (getpriority(PRIO_PROCESS, getpid()) != 0) {
|
||||
kprintf("getpriority_test.com must be launched at priority zero\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(getpriority, badWhich_einval) {
|
||||
ASSERT_SYS(EINVAL, -1, getpriority(-1, 0));
|
||||
ASSERT_SYS(EINVAL, -1, setpriority(-1, 0, 0));
|
||||
}
|
||||
|
||||
TEST(getpriority, lowerPriorityOfSelf) {
|
||||
SPAWN(fork);
|
||||
ASSERT_SYS(0, 0, getpriority(PRIO_PROCESS, 0));
|
||||
ASSERT_SYS(0, 0, getpriority(PRIO_PROCESS, getpid()));
|
||||
ASSERT_SYS(0, 0, setpriority(PRIO_PROCESS, getpid(), 5));
|
||||
ASSERT_SYS(0, 5, getpriority(PRIO_PROCESS, getpid()));
|
||||
ASSERT_SYS(0, 5, getpriority(PRIO_PROCESS, 0));
|
||||
EXITS(0);
|
||||
}
|
||||
|
||||
TEST(getpriority, higherPriorityOfSelf) {
|
||||
if (IsWindows() || getuid() == 0) {
|
||||
SPAWN(fork);
|
||||
ASSERT_SYS(0, 0, setpriority(PRIO_PROCESS, 0, -5));
|
||||
ASSERT_SYS(0, -5, getpriority(PRIO_PROCESS, 0));
|
||||
ASSERT_SYS(0, 0, setpriority(PRIO_PROCESS, 0, 0));
|
||||
EXITS(0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(getpriority, lowerAndRaiseItAgain_notAllowed) {
|
||||
return; // this behavior seems limited to modern linux
|
||||
SPAWN(fork);
|
||||
ASSERT_SYS(0, 0, setpriority(PRIO_PROCESS, 0, 5));
|
||||
ASSERT_SYS(EACCES, -1, setpriority(PRIO_PROCESS, 0, 4));
|
||||
EXITS(0);
|
||||
}
|
||||
|
||||
TEST(getpriority, lowerPriorityOfSubprocess) {
|
||||
int pid, ws;
|
||||
sigset_t ss, oldss;
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, SIGUSR1);
|
||||
ASSERT_SYS(0, 0, sigprocmask(SIG_BLOCK, &ss, &oldss));
|
||||
ASSERT_NE(-1, (pid = fork()));
|
||||
if (!pid) {
|
||||
sigemptyset(&ss);
|
||||
ASSERT_SYS(EINTR, -1, sigsuspend(&ss));
|
||||
_Exit(0);
|
||||
}
|
||||
ASSERT_SYS(0, 0, getpriority(PRIO_PROCESS, pid));
|
||||
ASSERT_SYS(0, 0, setpriority(PRIO_PROCESS, pid, 5));
|
||||
ASSERT_SYS(0, 5, getpriority(PRIO_PROCESS, pid));
|
||||
ASSERT_SYS(0, 0, kill(pid, SIGUSR1));
|
||||
ASSERT_SYS(0, pid, wait(&ws));
|
||||
ASSERT_SYS(0, 0, sigprocmask(SIG_SETMASK, &oldss, 0));
|
||||
}
|
|
@ -277,7 +277,9 @@ TEST(pledge, stdioTty_sendtoRestricted_requiresNullAddr) {
|
|||
mmap((void *)0x300000000000, FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
sin->sin_family = AF_INET;
|
||||
ASSERT_SYS(EPERM, -1, sendto(sv[0], "hello", 5, 0, sin, sizeof(*sin)));
|
||||
ASSERT_SYS(
|
||||
EPERM, -1,
|
||||
sendto(sv[0], "hello", 5, 0, (struct sockaddr *)sin, sizeof(*sin)));
|
||||
_Exit(0);
|
||||
}
|
||||
close(sv[0]);
|
||||
|
@ -346,10 +348,11 @@ TEST(pledge, inet_forbidsOtherSockets) {
|
|||
ASSERT_SYS(EPERM, -1, socket(AF_INET, SOCK_DGRAM, IPPROTO_RAW));
|
||||
ASSERT_SYS(EPERM, -1, setsockopt(3, SOL_SOCKET, SO_TIMESTAMP, &yes, 4));
|
||||
struct sockaddr_in sin = {AF_INET, 0, {htonl(0x7f000001)}};
|
||||
ASSERT_SYS(0, 0, bind(4, &sin, sizeof(sin)));
|
||||
ASSERT_SYS(0, 0, bind(4, (struct sockaddr *)&sin, sizeof(sin)));
|
||||
uint32_t az = sizeof(sin);
|
||||
ASSERT_SYS(0, 0, getsockname(4, &sin, &az));
|
||||
ASSERT_SYS(0, 5, sendto(3, "hello", 5, 0, &sin, sizeof(sin)));
|
||||
ASSERT_SYS(0, 0, getsockname(4, (struct sockaddr *)&sin, &az));
|
||||
ASSERT_SYS(0, 5,
|
||||
sendto(3, "hello", 5, 0, (struct sockaddr *)&sin, sizeof(sin)));
|
||||
_Exit(0);
|
||||
}
|
||||
EXPECT_NE(-1, wait(&ws));
|
||||
|
|
|
@ -93,7 +93,7 @@ TEST(ppoll, weCanProveItChecksForSignals) {
|
|||
TEST(poll, testNegativeOneFd_isIgnored) {
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
struct sockaddr_in addr = {AF_INET, 0, {htonl(INADDR_LOOPBACK)}};
|
||||
ASSERT_SYS(0, 0, bind(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, listen(3, 10));
|
||||
struct pollfd fds[] = {{-1}, {3}};
|
||||
EXPECT_SYS(0, 0, poll(fds, ARRAYLEN(fds), 1));
|
||||
|
|
|
@ -172,13 +172,6 @@ TEST(strtoul, weirdComma) {
|
|||
EXPECT_EQ(0, e - p);
|
||||
}
|
||||
|
||||
TEST(strtoul, outsideLimit_doesModulus) {
|
||||
EXPECT_EQ(/* python -c 'print(((2**123-1)/123)%(2**64))' */
|
||||
9298358801382050408ull,
|
||||
strtoul(/* python -c 'print((2**123-1)/123)' */
|
||||
"86453853384384772221385825058884200", 0, 10));
|
||||
}
|
||||
|
||||
TEST(strtol, testHex) {
|
||||
EXPECT_EQ(0, strtol("", 0, 16));
|
||||
EXPECT_EQ(0, strtol("0", 0, 16));
|
||||
|
@ -556,6 +549,15 @@ TEST(wcstoumax, testIBM) {
|
|||
ASSERT_STREQ(L"f", e);
|
||||
}
|
||||
|
||||
TEST(strtoul, testoverflow) {
|
||||
errno = 0;
|
||||
char *e = 0;
|
||||
unsigned long x = strtoul("18446744073709551616", &e, 0);
|
||||
ASSERT_EQ(ULONG_MAX, x);
|
||||
ASSERT_EQ(ERANGE, errno);
|
||||
ASSERT_STREQ("", e);
|
||||
}
|
||||
|
||||
BENCH(atoi, bench) {
|
||||
EZBENCH2("atoi 10⁸", donothing, EXPROPRIATE(atoi(VEIL("r", "100000000"))));
|
||||
EZBENCH2("strtol 10⁸", donothing,
|
||||
|
|
|
@ -113,13 +113,12 @@ int main(int argc, char *argv[]) {
|
|||
pDataOverrunCrash(10 + 1);
|
||||
exit(0);
|
||||
case 5:
|
||||
exit((intptr_t)pStackOverrunCrash(10 + 1));
|
||||
exit((intptr_t)pStackOverrunCrash(10 + 10000));
|
||||
case 6:
|
||||
exit((intptr_t)pMemoryLeakCrash());
|
||||
case 7:
|
||||
exit(pNpeCrash(0));
|
||||
case 8:
|
||||
__cxa_finalize(0);
|
||||
exit(pNpeCrash(0));
|
||||
case 9:
|
||||
exit(pStackOverflow(pStackOverflow, 0));
|
||||
|
|
|
@ -18,15 +18,18 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/cxaatexit.internal.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/memtrack.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/sysconf.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -34,7 +37,10 @@
|
|||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/subprocess.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
#define N 1024
|
||||
#define M 20
|
||||
|
@ -44,10 +50,6 @@ void SetUp(void) {
|
|||
if (IsWindows()) exit(0);
|
||||
}
|
||||
|
||||
void SetUpOnce(void) {
|
||||
ASSERT_SYS(0, 0, pledge("stdio rpath", 0));
|
||||
}
|
||||
|
||||
TEST(malloc, zeroMeansOne) {
|
||||
ASSERT_GE(malloc_usable_size(gc(malloc(0))), 1);
|
||||
}
|
||||
|
@ -146,3 +148,36 @@ BENCH(bulk_free, bench) {
|
|||
EZBENCH2("bulk_free()", BulkFreeBenchSetup(),
|
||||
bulk_free(bulk, ARRAYLEN(bulk)));
|
||||
}
|
||||
|
||||
#define ITERATIONS 10000
|
||||
|
||||
void *Worker(void *arg) {
|
||||
for (int i = 0; i < ITERATIONS; ++i) {
|
||||
char *p;
|
||||
ASSERT_NE(NULL, (p = malloc(lemur64() % 128)));
|
||||
ASSERT_NE(NULL, (p = realloc(p, max(lemur64() % 128, 1))));
|
||||
free(p);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
BENCH(malloc, torture) {
|
||||
int i, n = GetCpuCount() * 2;
|
||||
pthread_t *t = _gc(malloc(sizeof(pthread_t) * n));
|
||||
if (!n) return;
|
||||
printf("\nmalloc torture test w/ %d threads and %d iterations\n", n,
|
||||
ITERATIONS);
|
||||
SPAWN(fork);
|
||||
struct timespec t1 = _timespec_real();
|
||||
for (i = 0; i < n; ++i) {
|
||||
ASSERT_EQ(0, pthread_create(t + i, 0, Worker, 0));
|
||||
}
|
||||
for (i = 0; i < n; ++i) {
|
||||
ASSERT_EQ(0, pthread_join(t[i], 0));
|
||||
}
|
||||
struct timespec t2 = _timespec_real();
|
||||
printf("consumed %g wall and %g cpu seconds\n",
|
||||
_timespec_tomicros(_timespec_sub(t2, t1)) * 1e-6,
|
||||
(double)clock() / CLOCKS_PER_SEC);
|
||||
EXITS(0);
|
||||
}
|
||||
|
|
56
test/libc/runtime/sigsetjmp_test.c
Normal file
56
test/libc/runtime/sigsetjmp_test.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/siginfo.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/sa.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
sigjmp_buf jb;
|
||||
volatile int sigs;
|
||||
volatile int jumps;
|
||||
|
||||
void OnSignal(int sig, siginfo_t *si, void *ctx) {
|
||||
++sigs;
|
||||
}
|
||||
|
||||
TEST(sigsetjmp, test) {
|
||||
if (IsWindows()) return; // no sigusr1 support
|
||||
sigset_t ss;
|
||||
int i, n = 1000;
|
||||
struct sigaction sa = {.sa_sigaction = OnSignal};
|
||||
ASSERT_SYS(0, 0, sigaction(SIGUSR1, &sa, 0));
|
||||
for (i = 0; i < n; ++i) {
|
||||
if (!sigsetjmp(jb, 1)) {
|
||||
sigemptyset(&ss);
|
||||
sigaddset(&ss, SIGUSR1);
|
||||
ASSERT_SYS(0, 0, sigprocmask(SIG_BLOCK, &ss, 0));
|
||||
ASSERT_SYS(0, 0, raise(SIGUSR1));
|
||||
siglongjmp(jb, 1);
|
||||
} else {
|
||||
++jumps;
|
||||
}
|
||||
}
|
||||
ASSERT_EQ(1000, jumps);
|
||||
ASSERT_EQ(1000, sigs);
|
||||
}
|
|
@ -47,8 +47,9 @@ void SetUpOnce(void) {
|
|||
TEST(nointernet, testLocalhost_isAllowed) {
|
||||
struct sockaddr_in addr = {AF_INET, 0, {htonl(0x7f000001)}};
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 0, bind(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(ECONNREFUSED, -1, connect(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(ECONNREFUSED, -1,
|
||||
connect(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
}
|
||||
|
||||
|
@ -56,8 +57,8 @@ TEST(nointernet, testPublicInternet_isDenied) {
|
|||
struct sockaddr_in addr = {AF_INET, 0, {htonl(0x06060600)}};
|
||||
ASSERT_SYS(EPERM, -1, socket(AF_BLUETOOTH, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(ENOSYS, -1, bind(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(ENOSYS, -1, connect(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(ENOSYS, -1, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(ENOSYS, -1, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
}
|
||||
|
||||
|
|
|
@ -65,8 +65,8 @@ TEST(sendfile, testSeeking) {
|
|||
ASSERT_SYS(0, 512, write(3, kHyperion, 512));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 0, bind(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, &addr, &addrsize));
|
||||
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
|
||||
ASSERT_SYS(0, 0, listen(3, 1));
|
||||
if (!fork()) {
|
||||
ASSERT_SYS(0, 4, accept(3, (struct sockaddr *)&addr, &addrsize));
|
||||
|
@ -89,7 +89,7 @@ TEST(sendfile, testSeeking) {
|
|||
}
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 0, connect(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 12, read(3, buf, 12)); // needed due to windows
|
||||
ASSERT_SYS(0, 500, read(3, buf + 12, 700));
|
||||
ASSERT_EQ(0, memcmp(buf, kHyperion, 512));
|
||||
|
@ -111,8 +111,8 @@ TEST(sendfile, testPositioning) {
|
|||
ASSERT_SYS(0, 512, write(3, kHyperion, 512));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 0, bind(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, &addr, &addrsize));
|
||||
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
|
||||
ASSERT_SYS(0, 0, listen(3, 1));
|
||||
if (!fork()) {
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
@ -130,7 +130,7 @@ TEST(sendfile, testPositioning) {
|
|||
}
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 0, connect(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 6, read(3, buf, 6));
|
||||
ASSERT_SYS(0, 6, read(3, buf + 6, 6));
|
||||
ASSERT_SYS(0, 0, read(3, buf, 12));
|
||||
|
|
|
@ -38,7 +38,7 @@ TEST(setsockopt, SO_RCVTIMEO) {
|
|||
struct sockaddr_in sa = {AF_INET, 0, {htonl(0x7f000001)}};
|
||||
EXPECT_SYS(0, 3, socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
|
||||
EXPECT_SYS(0, 0, setsockopt(3, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)));
|
||||
EXPECT_SYS(0, 0, bind(3, &sa, sizeof(struct sockaddr_in)));
|
||||
EXPECT_SYS(0, 0, bind(3, (struct sockaddr *)&sa, sizeof(struct sockaddr_in)));
|
||||
EXPECT_SYS(EAGAIN, -1, read(3, buf, sizeof(buf)));
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
}
|
||||
|
|
|
@ -36,8 +36,8 @@ TEST(ipv4, test) {
|
|||
.sin_addr.s_addr = htonl(0x7f000001),
|
||||
};
|
||||
ASSERT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 0, bind(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, &addr, &addrsize));
|
||||
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
|
||||
ASSERT_SYS(0, 0, listen(3, SOMAXCONN));
|
||||
ASSERT_NE(-1, (pid = fork()));
|
||||
if (!pid) {
|
||||
|
@ -49,7 +49,7 @@ TEST(ipv4, test) {
|
|||
}
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
EXPECT_SYS(0, 3, socket(AF_INET, SOCK_STREAM, IPPROTO_TCP));
|
||||
EXPECT_SYS(0, 0, connect(3, &addr, sizeof(addr)));
|
||||
EXPECT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
EXPECT_SYS(0, 5, read(3, buf, 16));
|
||||
EXPECT_STREQ("hello", buf);
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
|
@ -68,8 +68,8 @@ TEST(ipv6, test) {
|
|||
.sin6_addr.s6_addr[15] = 1,
|
||||
};
|
||||
ASSERT_SYS(0, 3, socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP));
|
||||
ASSERT_SYS(0, 0, bind(3, &addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, &addr, &addrsize));
|
||||
ASSERT_SYS(0, 0, bind(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
ASSERT_SYS(0, 0, getsockname(3, (struct sockaddr *)&addr, &addrsize));
|
||||
ASSERT_EQ(AF_INET6, addr.sin6_family);
|
||||
ASSERT_NE(0, addr.sin6_port);
|
||||
ASSERT_SYS(0, 0, listen(3, SOMAXCONN));
|
||||
|
@ -83,7 +83,7 @@ TEST(ipv6, test) {
|
|||
}
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
EXPECT_SYS(0, 3, socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP));
|
||||
EXPECT_SYS(0, 0, connect(3, &addr, sizeof(addr)));
|
||||
EXPECT_SYS(0, 0, connect(3, (struct sockaddr *)&addr, sizeof(addr)));
|
||||
EXPECT_SYS(0, 5, read(3, buf, 16));
|
||||
EXPECT_STREQ("hello", buf);
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
|
|
|
@ -66,7 +66,7 @@ TEST(unix, datagram) {
|
|||
alarm(3);
|
||||
while (!fileexists(addr.sun_path)) usleep(10000);
|
||||
ASSERT_SYS(0, 3, socket(AF_UNIX, SOCK_DGRAM, 0));
|
||||
ASSERT_SYS(0, 5, sendto(3, "hello", 5, 0, &addr, len));
|
||||
ASSERT_SYS(0, 5, sendto(3, "hello", 5, 0, (struct sockaddr *)&addr, len));
|
||||
ASSERT_SYS(0, 0, close(3));
|
||||
ASSERT_NE(-1, wait(&ws));
|
||||
EXPECT_TRUE(WIFEXITED(ws));
|
||||
|
|
|
@ -16,9 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/mem/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/hyperion.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
@ -33,6 +34,18 @@ TEST(fgets, test) {
|
|||
fclose(f);
|
||||
}
|
||||
|
||||
TEST(fgets, eof) {
|
||||
FILE *f;
|
||||
char s[10];
|
||||
char buf[] = "test";
|
||||
ASSERT_NE(NULL, (f = fmemopen(buf, sizeof buf, "r")));
|
||||
ASSERT_EQ(s, fgets(s, sizeof s, f));
|
||||
ASSERT_EQ(0, strcmp(s, buf));
|
||||
ASSERT_EQ(0, fgets(s, sizeof s, f));
|
||||
ASSERT_EQ('t', s[0]);
|
||||
ASSERT_EQ(0, fclose(f));
|
||||
}
|
||||
|
||||
void Benchmark(void) {
|
||||
FILE *f;
|
||||
char *line;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue