mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-24 14:22:28 +00:00
Fix some issues and do some code cleanup
This commit is contained in:
parent
1f229e4efc
commit
312ed5c67c
72 changed files with 880 additions and 982 deletions
|
@ -55,6 +55,18 @@ TEST(open, enametoolong) {
|
|||
ASSERT_SYS(ENAMETOOLONG, -1, creat(s, 0644));
|
||||
}
|
||||
|
||||
TEST(open, testSpaceInFilename) {
|
||||
char buf[8] = {0};
|
||||
ASSERT_SYS(0, 0, xbarf("hello txt", "hello", -1));
|
||||
ASSERT_SYS(0, 3, open("hello txt", O_WRONLY));
|
||||
EXPECT_SYS(0, 1, write(3, "H", 1));
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
ASSERT_SYS(0, 3, open("hello txt", O_RDONLY));
|
||||
EXPECT_SYS(0, 5, read(3, buf, 7));
|
||||
EXPECT_STREQ("Hello", buf);
|
||||
EXPECT_SYS(0, 0, close(3));
|
||||
}
|
||||
|
||||
TEST(open, testOpenExistingForWriteOnly_seeksToStart) {
|
||||
char buf[8] = {0};
|
||||
ASSERT_SYS(0, 0, xbarf("hello.txt", "hello", -1));
|
||||
|
|
|
@ -46,6 +46,27 @@ TEST(asan, test) {
|
|||
EXPECT_FALSE(__asan_is_valid(p, 64 + 4));
|
||||
EXPECT_TRUE(__asan_is_valid(p + 1, 64 + 2));
|
||||
EXPECT_FALSE(__asan_is_valid(p + 1, 64 + 3));
|
||||
EXPECT_FALSE(__asan_is_valid(p - 1, 64));
|
||||
}
|
||||
|
||||
TEST(asan, test2) {
|
||||
char *p;
|
||||
if (!IsAsan()) return;
|
||||
p = gc(memalign(16, 64));
|
||||
// asan design precludes this kind of poisoning
|
||||
__asan_poison(p + 1, 1, kAsanProtected);
|
||||
EXPECT_TRUE(__asan_is_valid(p, 2));
|
||||
EXPECT_TRUE(__asan_is_valid(p + 1, 2));
|
||||
// but we can do this
|
||||
__asan_poison(p + 7, 1, kAsanProtected);
|
||||
EXPECT_TRUE(__asan_is_valid(p + 6, 1));
|
||||
EXPECT_FALSE(__asan_is_valid(p + 7, 1));
|
||||
EXPECT_TRUE(__asan_is_valid(p + 8, 1));
|
||||
EXPECT_FALSE(__asan_is_valid(p + 6, 2));
|
||||
EXPECT_FALSE(__asan_is_valid(p + 7, 2));
|
||||
EXPECT_FALSE(__asan_is_valid(p + 6, 3));
|
||||
__asan_unpoison(p + 7, 1);
|
||||
EXPECT_TRUE(__asan_is_valid(p + 6, 3));
|
||||
}
|
||||
|
||||
TEST(asan, testEmptySize_isAlwaysValid) {
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*-*- 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/dce.h"
|
||||
#include "libc/nexgen32e/threaded.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
char tib[64];
|
||||
|
||||
TEST(gettid, test) {
|
||||
if (IsLinux()) EXPECT_EQ(getpid(), gettid());
|
||||
if (IsNetbsd()) EXPECT_EQ(1, gettid());
|
||||
}
|
||||
|
||||
BENCH(gettid, bench) {
|
||||
int gettid_(void) asm("gettid");
|
||||
EZBENCH2("gettid (single threaded)", donothing, gettid());
|
||||
__install_tls(__initialize_tls(tib));
|
||||
EZBENCH2("gettid (tls enabled)", donothing, gettid());
|
||||
}
|
|
@ -28,6 +28,8 @@ TEST(tls, test) {
|
|||
EXPECT_EQ(31337, errno);
|
||||
EXPECT_EQ(&__errno, __errno_location());
|
||||
__initialize_tls(tib);
|
||||
*(int *)((char *)tib + 0x38) = gettid();
|
||||
*(int *)((char *)tib + 0x3c) = __errno;
|
||||
__install_tls(tib);
|
||||
EXPECT_EQ(31337, errno);
|
||||
EXPECT_EQ(tib, __get_tls());
|
||||
|
|
|
@ -80,10 +80,10 @@ TEST(rand64, testLcg_doesntProduceIdenticalValues) {
|
|||
}
|
||||
|
||||
TEST(rand64, testThreadSafety_doesntProduceIdenticalValues) {
|
||||
char *tls[THREADS];
|
||||
int i, j, rc, ws;
|
||||
sigset_t ss, oldss;
|
||||
char *tls[THREADS];
|
||||
void *stacks[THREADS];
|
||||
int i, j, rc, ws, tid[THREADS];
|
||||
struct sigaction oldsa;
|
||||
struct sigaction sa = {.sa_handler = OnChld, .sa_flags = SA_RESTART};
|
||||
EXPECT_NE(-1, sigaction(SIGCHLD, &sa, &oldsa));
|
||||
|
@ -92,19 +92,20 @@ TEST(rand64, testThreadSafety_doesntProduceIdenticalValues) {
|
|||
sigaddset(&ss, SIGCHLD);
|
||||
EXPECT_EQ(0, sigprocmask(SIG_BLOCK, &ss, &oldss));
|
||||
ready = false;
|
||||
memset(tid, -1, sizeof(tid));
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
tls[i] = __initialize_tls(calloc(1, 64));
|
||||
stacks[i] = mmap(0, GetStackSize(), PROT_READ | PROT_WRITE,
|
||||
MAP_STACK | MAP_ANONYMOUS, -1, 0);
|
||||
ASSERT_NE(-1, clone(Thrasher, stacks[i], GetStackSize(),
|
||||
CLONE_THREAD | CLONE_VM | CLONE_FS | CLONE_FILES |
|
||||
CLONE_SIGHAND | CLONE_SETTLS | CLONE_CHILD_CLEARTID,
|
||||
(void *)(intptr_t)i, 0, tls[i], 64, tid + i));
|
||||
ASSERT_NE(
|
||||
-1,
|
||||
clone(Thrasher, stacks[i], GetStackSize(),
|
||||
CLONE_THREAD | CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND |
|
||||
CLONE_SETTLS | CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID,
|
||||
(void *)(intptr_t)i, 0, tls[i], 64, (int *)(tls[i] + 0x38)));
|
||||
}
|
||||
ready = true;
|
||||
for (i = 0; i < THREADS; ++i) {
|
||||
_spinlock(tid + i);
|
||||
_spinlock((int *)(tls[i] + 0x38));
|
||||
EXPECT_SYS(0, 0, munmap(stacks[i], GetStackSize()));
|
||||
free(tls[i]);
|
||||
}
|
||||
|
|
|
@ -41,6 +41,12 @@ void Extract(const char *from, const char *to, int mode) {
|
|||
}
|
||||
|
||||
void SetUpOnce(void) {
|
||||
|
||||
// nothing to do if we're using elf
|
||||
if (~SUPPORT_VECTOR & (WINDOWS | XNU)) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
ASSERT_SYS(0, 0, mkdir("bin", 0755));
|
||||
Extract("/zip/apetest.com", "bin/apetest.com", 0755);
|
||||
Extract("/zip/apetest2.com", "bin/apetest2.com", 0755);
|
||||
|
|
|
@ -45,7 +45,7 @@ void SetUp(void) {
|
|||
tls = calloc(1, 64);
|
||||
__initialize_tls(tls);
|
||||
*(int *)(tls + 0x3c) = 31337;
|
||||
childetid = (int *)(tls + 0x0038);
|
||||
childetid = (int *)(tls + 0x38);
|
||||
ASSERT_NE(MAP_FAILED, (stack = mmap(0, GetStackSize(), PROT_READ | PROT_WRITE,
|
||||
MAP_STACK | MAP_ANONYMOUS, -1, 0)));
|
||||
}
|
||||
|
@ -95,6 +95,7 @@ TEST(clone, test1) {
|
|||
CLONE_SETTLS,
|
||||
(void *)23, &ptid, tls, 64, childetid)));
|
||||
_spinlock(childetid); // CLONE_CHILD_CLEARTID
|
||||
ASSERT_NE(gettid(), tid);
|
||||
ASSERT_EQ(tid, ptid);
|
||||
ASSERT_EQ(42, x);
|
||||
ASSERT_NE(me, tid);
|
||||
|
@ -130,6 +131,6 @@ TEST(clone, tlsSystemCallsErrno_wontClobberMainThreadBecauseTls) {
|
|||
BENCH(clone, bench) {
|
||||
errno_t *volatile ep;
|
||||
char *volatile tp;
|
||||
EZBENCH2("__errno_location", donothing, (ep = (__errno_location())));
|
||||
EZBENCH2("__errno_location", donothing, (ep = __errno_location()));
|
||||
EZBENCH2("__get_tls", donothing, (tp = __get_tls()));
|
||||
}
|
||||
|
|
87
test/libc/stdio/fgetln_test.c
Normal file
87
test/libc/stdio/fgetln_test.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
/*-*- 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/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.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"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
TEST(fgetln, test) {
|
||||
FILE *f;
|
||||
f = fmemopen(gc(strdup(kHyperion)), kHyperionSize, "r+");
|
||||
EXPECT_STREQ("The fall of Hyperion - a Dream\n", fgetln(f, 0));
|
||||
EXPECT_STREQ("John Keats\n", fgetln(f, 0));
|
||||
EXPECT_STREQ("\n", fgetln(f, 0));
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
TEST(fgetln, testGoodLastLine) {
|
||||
FILE *f;
|
||||
size_t n;
|
||||
f = fmemopen("foo\nbar\n", 8, "r");
|
||||
EXPECT_STREQ("foo\n", fgetln(f, &n));
|
||||
EXPECT_EQ(4, n);
|
||||
EXPECT_STREQ("bar\n", fgetln(f, &n));
|
||||
EXPECT_EQ(4, n);
|
||||
EXPECT_EQ(NULL, fgetln(f, 0));
|
||||
EXPECT_FALSE(ferror(f));
|
||||
EXPECT_TRUE(feof(f));
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
TEST(fgetln, testEvilLastLine) {
|
||||
FILE *f;
|
||||
f = fmemopen("foo\nbar", 7, "r");
|
||||
EXPECT_STREQ("foo\n", fgetln(f, 0));
|
||||
EXPECT_STREQ("bar", fgetln(f, 0));
|
||||
EXPECT_EQ(NULL, fgetln(f, 0));
|
||||
EXPECT_FALSE(ferror(f));
|
||||
EXPECT_TRUE(feof(f));
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
TEST(fgetln, testReadingFromStdin_doesntLeakMemory) {
|
||||
FILE *f;
|
||||
int oldstdin, pfds[2];
|
||||
oldstdin = dup(0);
|
||||
EXPECT_SYS(0, 0, pipe(pfds));
|
||||
EXPECT_SYS(0, 8, write(pfds[1], "foo\nbar\n", 8));
|
||||
EXPECT_SYS(0, 0, close(pfds[1]));
|
||||
EXPECT_SYS(0, 0, close(0));
|
||||
EXPECT_SYS(0, 0, dup(pfds[0]));
|
||||
EXPECT_SYS(0, 0, close(pfds[0]));
|
||||
EXPECT_STREQ("foo\n", fgetln(stdin, 0));
|
||||
EXPECT_STREQ("bar\n", fgetln(stdin, 0));
|
||||
EXPECT_EQ(NULL, fgetln(stdin, 0));
|
||||
EXPECT_FALSE(ferror(stdin));
|
||||
EXPECT_TRUE(feof(stdin));
|
||||
EXPECT_SYS(0, 0, close(0));
|
||||
EXPECT_SYS(0, 0, dup(oldstdin));
|
||||
clearerr(stdin);
|
||||
}
|
||||
|
||||
BENCH(fgetln, bench) {
|
||||
FILE *f = fmemopen(gc(strdup(kHyperion)), kHyperionSize, "r+");
|
||||
EZBENCH2("fgetln", donothing, fgetln(f, 0));
|
||||
EZBENCH2("xgetline", donothing, free(xgetline(f)));
|
||||
fclose(f);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue