Make improvements

- Expand redbean UNIX module
- Expand redbean documentation
- Ensure Lua copyright is embedded in binary
- Increase the PATH_MAX limit especially on NT
- Use column major sorting for linenoise completions
- Fix some suboptimalities in redbean's new UNIX API
- Figured out right flags for Multics newline in raw mode
This commit is contained in:
Justine Tunney 2022-04-24 09:59:22 -07:00
parent cf3174dc74
commit 2046c0d2ae
305 changed files with 6602 additions and 4221 deletions

View file

@ -35,8 +35,8 @@
uint64_t i;
char *oldpath;
char tmp[PATH_MAX];
char pathbuf[PATH_MAX];
char tmp[PATH_MAX + 1];
char pathbuf[PATH_MAX + 1];
char testlib_enable_tmp_setup_teardown;
void SetUp(void) {
@ -54,34 +54,34 @@ void TearDown(void) {
TEST(commandv, testPathSearch) {
EXPECT_NE(-1, touch("bin/sh", 0755));
EXPECT_STREQ("bin/sh", commandv("sh", pathbuf));
EXPECT_STREQ("bin/sh", commandv("sh", pathbuf, sizeof(pathbuf)));
}
TEST(commandv, testPathSearch_appendsComExtension) {
EXPECT_NE(-1, touch("bin/sh.com", 0755));
EXPECT_STREQ("bin/sh.com", commandv("sh", pathbuf));
EXPECT_STREQ("bin/sh.com", commandv("sh", pathbuf, sizeof(pathbuf)));
}
TEST(commandv, testSlashes_wontSearchPath_butChecksAccess) {
EXPECT_NE(-1, touch("home/sh", 0755));
i = g_syscount;
EXPECT_STREQ("home/sh", commandv("home/sh", pathbuf));
EXPECT_STREQ("home/sh", commandv("home/sh", pathbuf, sizeof(pathbuf)));
if (!IsWindows()) EXPECT_EQ(i + 1, g_syscount);
}
TEST(commandv, testSlashes_wontSearchPath_butStillAppendsComExtension) {
EXPECT_NE(-1, touch("home/sh.com", 0755));
i = g_syscount;
EXPECT_STREQ("home/sh.com", commandv("home/sh", pathbuf));
EXPECT_STREQ("home/sh.com", commandv("home/sh", pathbuf, sizeof(pathbuf)));
if (!IsWindows()) EXPECT_EQ(i + 2, g_syscount);
}
TEST(commandv, testSameDir_doesntHappenByDefaultUnlessItsWindows) {
EXPECT_NE(-1, touch("bog", 0755));
if (IsWindows()) {
EXPECT_STREQ("./bog", commandv("bog", pathbuf));
EXPECT_STREQ("./bog", commandv("bog", pathbuf, sizeof(pathbuf)));
} else {
EXPECT_EQ(NULL, commandv("bog", pathbuf));
EXPECT_EQ(NULL, commandv("bog", pathbuf, sizeof(pathbuf)));
}
}
@ -89,9 +89,9 @@ TEST(commandv, testSameDir_willHappenWithColonBlank) {
CHECK_NE(-1, setenv("PATH", "bin:", true));
EXPECT_NE(-1, touch("bog", 0755));
if (IsWindows()) {
EXPECT_STREQ("./bog", commandv("bog", pathbuf));
EXPECT_STREQ("./bog", commandv("bog", pathbuf, sizeof(pathbuf)));
} else {
EXPECT_STREQ("bog", commandv("bog", pathbuf));
EXPECT_STREQ("bog", commandv("bog", pathbuf, sizeof(pathbuf)));
}
}
@ -99,8 +99,8 @@ TEST(commandv, testSameDir_willHappenWithColonBlank2) {
CHECK_NE(-1, setenv("PATH", ":bin", true));
EXPECT_NE(-1, touch("bog", 0755));
if (IsWindows()) {
EXPECT_STREQ("./bog", commandv("bog", pathbuf));
EXPECT_STREQ("./bog", commandv("bog", pathbuf, sizeof(pathbuf)));
} else {
EXPECT_STREQ("bog", commandv("bog", pathbuf));
EXPECT_STREQ("bog", commandv("bog", pathbuf, sizeof(pathbuf)));
}
}

View file

@ -29,6 +29,13 @@ void SetUp(void) {
} else {
exit(7);
}
} else if (getenv("_WEIRDENV")) {
for (char **e = environ; *e; ++e) {
if (!strcmp(*e, "WEIRD")) {
exit(0);
}
}
exit(7);
}
}
@ -47,3 +54,20 @@ TEST(execve, testWeirdAnsiC89emptyArgv) {
EXPECT_TRUE(WIFEXITED(ws));
EXPECT_EQ(0, WEXITSTATUS(ws));
}
TEST(execve, testWeirdEnvironmentVariable) {
char *prog;
int pid, ws;
if (IsWindows()) return;
if (IsOpenbsd()) return;
prog = GetProgramExecutableName();
ASSERT_NE(-1, (pid = fork()));
if (!pid) {
execve(prog, (char *const[]){prog, 0},
(char *const[]){"_WEIRDENV=1", "WEIRD", 0});
_Exit(127);
}
ASSERT_NE(-1, wait(&ws));
EXPECT_TRUE(WIFEXITED(ws));
EXPECT_EQ(0, WEXITSTATUS(ws));
}

View file

@ -40,3 +40,10 @@ TEST(getcwd, testNullBuf_allocatesResult) {
EXPECT_NE(-1, chdir("subdir"));
EXPECT_STREQ("subdir", basename(gc(getcwd(0, 0))));
}
TEST(getcwd, testWindows_addsFunnyPrefix) {
if (!IsWindows()) return;
char path[PATH_MAX + 1];
ASSERT_NE(0, getcwd(path, sizeof(path)));
EXPECT_STARTSWITH("//?/", path);
}

View file

@ -17,9 +17,11 @@
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/calls/calls.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/log/check.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/o.h"
#include "libc/testlib/testlib.h"
@ -58,6 +60,15 @@ TEST(mkdir, testPathIsDirectory_EEXIST) {
EXPECT_EQ(EEXIST, errno);
}
TEST(mkdir, enametoolong) {
int i;
size_t n = 2048;
char *d, *s = gc(calloc(1, n));
for (i = 0; i < n - 1; ++i) s[i] = 'x';
s[i] = 0;
EXPECT_SYS(ENAMETOOLONG, -1, mkdir(s, 0644));
}
TEST(makedirs, testEmptyString_EEXIST) {
EXPECT_EQ(-1, mkdir("", 0755));
EXPECT_EQ(ENOENT, errno);
@ -72,3 +83,14 @@ TEST(mkdirat, testRelativePath_opensRelativeToDirFd) {
EXPECT_EQ(-1, makedirs("", 0755));
EXPECT_NE(-1, close(dirfd));
}
TEST(mkdir, longname) {
int i;
char *d, s[270] = {0};
for (i = 0; i < sizeof(s) - 1; ++i) s[i] = 'x';
s[i] = 0;
ASSERT_NE(NULL, (d = gc(getcwd(0, 0))));
memcpy(s, d, strlen(d));
s[strlen(d)] = '/';
ASSERT_SYS(0, 0, mkdir(s, 0644));
}

View file

@ -38,7 +38,13 @@ BENCH(read, bench) {
char buf[16];
ASSERT_SYS(0, 3, open("/dev/zero", O_RDONLY));
EZBENCH2("read", donothing, read(3, buf, 5));
EZBENCH2("readv", donothing, readv(3, &(struct iovec){buf, 5}, 1));
EZBENCH2("pread", donothing, pread(3, buf, 5, 0));
EZBENCH2("readv₁", donothing, readv(3, &(struct iovec){buf, 5}, 1));
EZBENCH2("readv₂", donothing,
readv(3, (struct iovec[]){{buf, 1}, {buf + 1, 4}}, 2));
EZBENCH2("preadv₁", donothing, preadv(3, &(struct iovec){buf, 5}, 1, 0));
EZBENCH2("preadv₂", donothing,
preadv(3, (struct iovec[]){{buf, 1}, {buf + 1, 4}}, 2, 0));
EZBENCH2("sys_read", donothing, sys_read(3, buf, 5));
EZBENCH2("sys_readv", donothing, sys_readv(3, &(struct iovec){buf, 5}, 1));
EZBENCH2("Read", donothing, Read(3, buf, 5));

View file

@ -83,10 +83,8 @@ TEST(readlinkat, frootloop) {
ASSERT_SYS(0, 0, symlink("froot", "froot"));
ASSERT_SYS(ELOOP, -1, readlink("froot/loop", buf, sizeof(buf)));
if (O_NOFOLLOW) {
ASSERT_SYS(IsFreebsd() ? EMLINK
: IsNetbsd() ? EFTYPE
: ELOOP,
-1, open("froot", O_RDONLY | O_NOFOLLOW));
ASSERT_SYS(IsFreebsd() ? EMLINK : IsNetbsd() ? EFTYPE : ELOOP, -1,
open("froot", O_RDONLY | O_NOFOLLOW));
if (0 && O_PATH) { /* need rhel5 test */
ASSERT_NE(-1, (fd = open("froot", O_RDONLY | O_NOFOLLOW | O_PATH)));
ASSERT_NE(-1, close(fd));
@ -101,3 +99,11 @@ TEST(readlinkat, statReadsNameLength) {
EXPECT_TRUE(S_ISLNK(st.st_mode));
EXPECT_EQ(5, st.st_size);
}
TEST(readlinkat, realpathReturnsLongPath) {
if (!IsWindows()) return;
struct stat st;
char buf[PATH_MAX];
ASSERT_SYS(0, 0, touch("froot", 0644));
ASSERT_STARTSWITH("//?/", realpath("froot", buf));
}

View file

@ -22,7 +22,6 @@
#include "libc/calls/struct/iovec.h"
#include "libc/calls/struct/seccomp.h"
#include "libc/errno.h"
#include "libc/intrin/kprintf.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/sysv/consts/audit.h"

View file

@ -23,7 +23,6 @@
#include "libc/calls/ucontext.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/intrin/kprintf.h"
#include "libc/runtime/runtime.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"

View file

@ -23,7 +23,6 @@
#include "libc/calls/struct/sigset.h"
#include "libc/calls/ucontext.h"
#include "libc/dce.h"
#include "libc/intrin/kprintf.h"
#include "libc/sysv/consts/sa.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"

View file

@ -21,7 +21,6 @@
#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/str/str.h"
#include "libc/sysv/consts/sa.h"

View file

@ -23,6 +23,13 @@
#include "libc/testlib/ezbench.h"
#include "libc/testlib/testlib.h"
void __on_arithmetic_overflow(void) {
// prevent -ftrapv crashes
//
// for some reason gcc generates trap code even when we're doing it
// manually with __builtin_mul_overflow() :'(
}
TEST(atoi, test) {
EXPECT_EQ(0, atoi(""));
EXPECT_EQ(0, atoi("-b"));

View file

@ -354,6 +354,33 @@ TEST(ksnprintf, badUtf16) {
}
}
TEST(ksnprintf, truncation) {
char buf[16] = {0};
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(0, 0, "%s", "xxxxx");
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(buf, 1, "%s", "xxxxx");
EXPECT_STREQ("", buf);
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(buf, 2, "%s", "xxxxx");
EXPECT_STREQ(".", buf);
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(buf, 3, "%s", "xxxxx");
EXPECT_STREQ("..", buf);
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(buf, 4, "%s", "xxxxx");
EXPECT_STREQ("...", buf);
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(buf, 5, "%s", "xxxxx");
EXPECT_STREQ("x...", buf);
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(buf, 6, "%s", "xxxxxxxxxxx");
EXPECT_STREQ("xx...", buf);
rngset(buf, sizeof(buf) - 1, lemur64, -1);
ksnprintf(buf, 7, "%s", "xxxxxxxxx");
EXPECT_STREQ("xxx...", buf);
}
BENCH(printf, bench) {
char b[128];
int snprintf_(char *, size_t, const char *, ...) asm("snprintf");

View file

@ -63,7 +63,7 @@ static void CheckMemoryIntervalsAreOk(const struct MemoryIntervals *mm) {
static void RunTrackMemoryIntervalTest(const struct MemoryIntervals t[2], int x,
int y, long h) {
struct MemoryIntervals *mm;
mm = memcpy(malloc(sizeof(*t)), t, sizeof(*t));
mm = memcpy(memalign(64, sizeof(*t)), t, sizeof(*t));
CheckMemoryIntervalsAreOk(mm);
CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h, 0, 0, 0, 0, 0, 0));
CheckMemoryIntervalsAreOk(mm);
@ -75,7 +75,7 @@ static int RunReleaseMemoryIntervalsTest(const struct MemoryIntervals t[2],
int x, int y) {
int rc;
struct MemoryIntervals *mm;
mm = memcpy(malloc(sizeof(*t)), t, sizeof(*t));
mm = memcpy(memalign(64, sizeof(*t)), t, sizeof(*t));
CheckMemoryIntervalsAreOk(mm);
if ((rc = ReleaseMemoryIntervals(mm, x, y, NULL)) != -1) {
CheckMemoryIntervalsAreOk(mm);

View file

@ -57,7 +57,7 @@ void OnSigBus(int sig, struct siginfo *si, struct ucontext *ctx) {
#if 0
kprintf("SIGBUS%n");
kprintf("si->si_signo = %G%n", si->si_signo);
kprintf("si->si_errno = %s (%d)%n", strerror_short(si->si_errno),
kprintf("si->si_errno = %s (%d)%n", strerrno(si->si_errno),
si->si_errno);
kprintf("si->si_code = %s (%d)%n", GetSiCodeName(sig, si->si_code),
si->si_code);