mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 13:52:28 +00:00
Fix some bugs
This commit is contained in:
parent
5584f6adcf
commit
6c0bbfac4a
15 changed files with 289 additions and 136 deletions
|
@ -184,6 +184,7 @@ int sys_ptrace(int, ...);
|
||||||
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
int sysctl(const int *, unsigned, void *, size_t *, void *, size_t);
|
||||||
int tgkill(int, int, int);
|
int tgkill(int, int, int);
|
||||||
int tkill(int, int);
|
int tkill(int, int);
|
||||||
|
int tmpfd(void);
|
||||||
int touch(const char *, uint32_t);
|
int touch(const char *, uint32_t);
|
||||||
int truncate(const char *, uint64_t);
|
int truncate(const char *, uint64_t);
|
||||||
int ttyname_r(int, char *, size_t);
|
int ttyname_r(int, char *, size_t);
|
||||||
|
|
|
@ -1939,12 +1939,9 @@ privileged int sys_pledge_linux(unsigned long ipromises, int mode) {
|
||||||
} else {
|
} else {
|
||||||
// non-trapping mode
|
// non-trapping mode
|
||||||
//
|
//
|
||||||
// 1. our sigsys error message handler can't be inherited across
|
// our sigsys error message handler can't be inherited across
|
||||||
// execve() boundaries so if you've pledged exec then that'll
|
// execve() boundaries so if you've pledged exec then that'll
|
||||||
// mean no error messages for you.
|
// likely cause a SIGSYS in your child after the exec happens
|
||||||
//
|
|
||||||
// 2. we do not trap pledge("", 0) because that would go against
|
|
||||||
// its documented purpose of only permitted exit().
|
|
||||||
switch (mode & PLEDGE_PENALTY_MASK) {
|
switch (mode & PLEDGE_PENALTY_MASK) {
|
||||||
case PLEDGE_PENALTY_KILL_THREAD:
|
case PLEDGE_PENALTY_KILL_THREAD:
|
||||||
sf[0].k = SECCOMP_RET_KILL_THREAD;
|
sf[0].k = SECCOMP_RET_KILL_THREAD;
|
||||||
|
|
113
libc/calls/tmpfd.c
Normal file
113
libc/calls/tmpfd.c
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/*-*- 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 2020 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/errno.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
|
#include "libc/stdio/rand.h"
|
||||||
|
#include "libc/stdio/temp.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/o.h"
|
||||||
|
|
||||||
|
#define _O_TMPFILE 000020200000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns file descriptor of open anonymous file, e.g.
|
||||||
|
*
|
||||||
|
* int fd;
|
||||||
|
* if ((fd = tmpfd()) == -1) {
|
||||||
|
* perror("tmpfd");
|
||||||
|
* exit(1);
|
||||||
|
* }
|
||||||
|
* // do stuff
|
||||||
|
* close(f);
|
||||||
|
*
|
||||||
|
* This creates a secure temporary file inside $TMPDIR. If it isn't
|
||||||
|
* defined, then /tmp is used on UNIX and GetTempPath() is used on the
|
||||||
|
* New Technology. This resolution of $TMPDIR happens once in a ctor,
|
||||||
|
* which is copied to the `kTmpDir` global.
|
||||||
|
*
|
||||||
|
* Once close() is called, the returned file is guaranteed to be deleted
|
||||||
|
* automatically. On UNIX the file is unlink()'d before this function
|
||||||
|
* returns. On the New Technology it happens upon close().
|
||||||
|
*
|
||||||
|
* On newer Linux only (c. 2013) it's possible to turn the anonymous
|
||||||
|
* returned file back into a real file, by doing this:
|
||||||
|
*
|
||||||
|
* linkat(AT_FDCWD, _gc(xasprintf("/proc/self/fd/%d", fd)),
|
||||||
|
* AT_FDCWD, "real.txt", AT_SYMLINK_FOLLOW)
|
||||||
|
*
|
||||||
|
* On the New Technology, temporary files created by this function
|
||||||
|
* should have better performance, because `kNtFileAttributeTemporary`
|
||||||
|
* asks the kernel to more aggressively cache and reduce i/o ops.
|
||||||
|
*
|
||||||
|
* The tmpfd() function should be favored over `open(O_TMPFILE)` because
|
||||||
|
* the latter only works on Linux, and will cause open() failures on all
|
||||||
|
* other platforms.
|
||||||
|
*
|
||||||
|
* @return file descriptor on success, or -1 w/ errno
|
||||||
|
* @see tmpfile() for stdio version
|
||||||
|
* @asyncsignalsafe
|
||||||
|
* @threadsafe
|
||||||
|
* @vforksafe
|
||||||
|
*/
|
||||||
|
int tmpfd(void) {
|
||||||
|
FILE *f;
|
||||||
|
unsigned x;
|
||||||
|
int fd, i, j, e;
|
||||||
|
char path[PATH_MAX], *p;
|
||||||
|
e = errno;
|
||||||
|
if (IsLinux() && (fd = open(kTmpPath, O_RDWR | _O_TMPFILE, 0600)) != -1) {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
errno = e;
|
||||||
|
p = path;
|
||||||
|
p = stpcpy(p, kTmpPath);
|
||||||
|
p = stpcpy(p, "tmp.");
|
||||||
|
if (program_invocation_short_name &&
|
||||||
|
strlen(program_invocation_short_name) < 128) {
|
||||||
|
p = stpcpy(p, program_invocation_short_name);
|
||||||
|
*p++ = '.';
|
||||||
|
}
|
||||||
|
for (i = 0; i < 10; ++i) {
|
||||||
|
x = rand64();
|
||||||
|
for (j = 0; j < 6; ++j) {
|
||||||
|
p[j] = "0123456789abcdefghijklmnopqrstuvwxyz"[x % 36];
|
||||||
|
x /= 36;
|
||||||
|
}
|
||||||
|
p[j] = 0;
|
||||||
|
e = errno;
|
||||||
|
if ((fd = open(path,
|
||||||
|
O_RDWR | O_CREAT | O_EXCL | (IsWindows() ? _O_TMPFILE : 0),
|
||||||
|
0600)) != -1) {
|
||||||
|
if (!IsWindows()) {
|
||||||
|
if (unlink(path)) {
|
||||||
|
asm("hlt");
|
||||||
|
unreachable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fd;
|
||||||
|
} else if (errno == EEXIST) {
|
||||||
|
errno = e;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
|
@ -40,10 +40,10 @@ kOpenFlags:
|
||||||
.e O_TRUNC,"TRUNC" //
|
.e O_TRUNC,"TRUNC" //
|
||||||
.e O_CLOEXEC,"CLOEXEC" //
|
.e O_CLOEXEC,"CLOEXEC" //
|
||||||
.e O_NONBLOCK,"NONBLOCK" //
|
.e O_NONBLOCK,"NONBLOCK" //
|
||||||
.e O_DIRECTORY,"DIRECTORY" //
|
.e O_TMPFILE,"TMPFILE" // linux, windows
|
||||||
|
.e O_DIRECTORY,"DIRECTORY" // order matters
|
||||||
.e O_DIRECT,"DIRECT" // no-op on xnu/openbsd
|
.e O_DIRECT,"DIRECT" // no-op on xnu/openbsd
|
||||||
.e O_APPEND,"APPEND" // weird on nt
|
.e O_APPEND,"APPEND" // weird on nt
|
||||||
.e O_TMPFILE,"TMPFILE" // linux, windows
|
|
||||||
.e O_NOFOLLOW,"NOFOLLOW" // unix
|
.e O_NOFOLLOW,"NOFOLLOW" // unix
|
||||||
.e O_SYNC,"SYNC" // unix
|
.e O_SYNC,"SYNC" // unix
|
||||||
.e O_ASYNC,"ASYNC" // unix
|
.e O_ASYNC,"ASYNC" // unix
|
||||||
|
|
|
@ -17,59 +17,58 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/stdio/rand.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
|
||||||
#include "libc/stdio/temp.h"
|
#include "libc/stdio/temp.h"
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "libc/sysv/consts/o.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens stream backed by anonymous file.
|
* Opens stream backed by anonymous file, e.g.
|
||||||
*
|
*
|
||||||
* We use $TMPDIR or /tmp to create a temporary file securely, which
|
* FILE *f;
|
||||||
* will be unlink()'d before this function returns. The file content
|
* if (!(f = tmpfile())) {
|
||||||
* will be released from disk once fclose() is called.
|
* perror("tmpfile");
|
||||||
|
* exit(1);
|
||||||
|
* }
|
||||||
|
* // do stuff
|
||||||
|
* fclose(f);
|
||||||
*
|
*
|
||||||
* @see mkostempsm(), kTmpPath
|
* This creates a secure temporary file inside $TMPDIR. If it isn't
|
||||||
|
* defined, then /tmp is used on UNIX and GetTempPath() is used on the
|
||||||
|
* New Technology. This resolution of $TMPDIR happens once in a ctor,
|
||||||
|
* which is copied to the `kTmpDir` global.
|
||||||
|
*
|
||||||
|
* Once fclose() is called, the returned file is guaranteed to be
|
||||||
|
* deleted automatically. On UNIX the file is unlink()'d before this
|
||||||
|
* function returns. On the New Technology it happens upon fclose().
|
||||||
|
*
|
||||||
|
* On newer Linux only (c. 2013) it's possible to turn the anonymous
|
||||||
|
* returned file back into a real file, by doing this:
|
||||||
|
*
|
||||||
|
* linkat(AT_FDCWD, _gc(xasprintf("/proc/self/fd/%d", fileno(f))),
|
||||||
|
* AT_FDCWD, "real.txt", AT_SYMLINK_FOLLOW)
|
||||||
|
*
|
||||||
|
* On the New Technology, temporary files created by this function
|
||||||
|
* should have better performance, because `kNtFileAttributeTemporary`
|
||||||
|
* asks the kernel to more aggressively cache and reduce i/o ops.
|
||||||
|
*
|
||||||
|
* Favor tmpfd() or tmpfile() over `open(O_TMPFILE)` because the latter
|
||||||
|
* is Linux-only and will cause open() failures on all other platforms.
|
||||||
|
*
|
||||||
|
* @see tmpfd() if you don't want to link stdio/malloc
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
* @threadsafe
|
* @threadsafe
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
FILE *tmpfile(void) {
|
FILE *tmpfile(void) {
|
||||||
|
int fd;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
unsigned x;
|
if ((fd = tmpfd()) != -1) {
|
||||||
int fd, i, j, e;
|
|
||||||
char path[PATH_MAX], *p;
|
|
||||||
p = path;
|
|
||||||
p = stpcpy(p, kTmpPath);
|
|
||||||
p = stpcpy(p, "tmp.");
|
|
||||||
if (program_invocation_short_name &&
|
|
||||||
strlen(program_invocation_short_name) < 128) {
|
|
||||||
p = stpcpy(p, program_invocation_short_name);
|
|
||||||
*p++ = '.';
|
|
||||||
}
|
|
||||||
for (i = 0; i < 10; ++i) {
|
|
||||||
x = rand64();
|
|
||||||
for (j = 0; j < 6; ++j) {
|
|
||||||
p[j] = "0123456789abcdefghijklmnopqrstuvwxyz"[x % 36];
|
|
||||||
x /= 36;
|
|
||||||
}
|
|
||||||
p[j] = 0;
|
|
||||||
e = errno;
|
|
||||||
if ((fd = open(path, O_RDWR | O_CREAT | O_EXCL, 0600)) != -1) {
|
|
||||||
unlink(path);
|
|
||||||
if ((f = fdopen(fd, "w+"))) {
|
if ((f = fdopen(fd, "w+"))) {
|
||||||
return f;
|
return f;
|
||||||
} else {
|
} else {
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (errno == EEXIST) {
|
|
||||||
errno = e;
|
|
||||||
} else {
|
} else {
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ syscon open O_SEQUENTIAL 0 0 0 0 0 0x40000000 # kNtFileFlagSequen
|
||||||
syscon open O_COMPRESSED 0 0 0 0 0 0x20000000 # kNtFileAttributeCompressed [SYNC libc/calls/open-nt.c]
|
syscon open O_COMPRESSED 0 0 0 0 0 0x20000000 # kNtFileAttributeCompressed [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_INDEXED 0 0 0 0 0 0x10000000 # !kNtFileAttributeNotContentIndexed [SYNC libc/calls/open-nt.c]
|
syscon open O_INDEXED 0 0 0 0 0 0x10000000 # !kNtFileAttributeNotContentIndexed [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux [SYNC libc/calls/open-nt.c]
|
syscon open O_CLOEXEC 0x00080000 0x01000000 0x00100000 0x00010000 0x00400000 0x00080000 # NT faked as Linux [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_TMPFILE 0x00410000 0 0 0 0 0x00410000 # Linux 3.11+ (c. 2013) __O_TMPFILE | O_DIRECTORY; kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose [SYNC libc/calls/open-nt.c]
|
syscon open O_TMPFILE 0x00410000 0xffffffff 0xffffffff 0xffffffff 0xffffffff 0xffffffff # please use tmpfd(); Linux 3.11+ (c. 2013) __O_TMPFILE | O_DIRECTORY; kNtFileAttributeTemporary|kNtFileFlagDeleteOnClose [SYNC libc/calls/open-nt.c]
|
||||||
syscon open O_SPARSE 0 0 0 0 0 0 # wut
|
syscon open O_SPARSE 0 0 0 0 0 0 # wut
|
||||||
syscon open O_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus
|
syscon open O_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # bsd consensus
|
||||||
syscon open O_ASYNC 0x00002000 0x00000040 0x00000040 0x00000040 0x00000040 0 # bsd consensus
|
syscon open O_ASYNC 0x00002000 0x00000040 0x00000040 0x00000040 0x00000040 0 # bsd consensus
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
#include "libc/sysv/consts/syscon.internal.h"
|
#include "libc/sysv/consts/syscon.internal.h"
|
||||||
.syscon open,O_TMPFILE,0x00410000,0,0,0,0,0x00410000
|
.syscon open,O_TMPFILE,0x00410000,0xffffffff,0xffffffff,0xffffffff,0xffffffff,0xffffffff
|
||||||
|
|
|
@ -16,15 +16,78 @@
|
||||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/struct/dirent.h"
|
||||||
|
#include "libc/calls/struct/stat.h"
|
||||||
|
#include "libc/calls/syscall_support-sysv.internal.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
#include "libc/runtime/gc.internal.h"
|
||||||
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/stdio/temp.h"
|
#include "libc/stdio/temp.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/at.h"
|
||||||
#include "libc/testlib/testlib.h"
|
#include "libc/testlib/testlib.h"
|
||||||
|
#include "libc/x/x.h"
|
||||||
|
|
||||||
|
char testlib_enable_tmp_setup_teardown;
|
||||||
|
char oldtmpdir[PATH_MAX];
|
||||||
|
|
||||||
|
bool IsDirectoryEmpty(const char *path) {
|
||||||
|
DIR *d;
|
||||||
|
bool res = true;
|
||||||
|
struct dirent *e;
|
||||||
|
ASSERT_NE(NULL, (d = opendir(path)));
|
||||||
|
while ((e = readdir(d))) {
|
||||||
|
if (!strcmp(e->d_name, ".")) continue;
|
||||||
|
if (!strcmp(e->d_name, "..")) continue;
|
||||||
|
res = false;
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUp(void) {
|
||||||
|
strcpy(oldtmpdir, kTmpPath);
|
||||||
|
strcpy(kTmpPath, ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
void TearDown(void) {
|
||||||
|
strcpy(kTmpPath, oldtmpdir);
|
||||||
|
}
|
||||||
|
|
||||||
TEST(tmpfile, test) {
|
TEST(tmpfile, test) {
|
||||||
FILE *f = tmpfile();
|
FILE *f;
|
||||||
|
struct stat st;
|
||||||
|
EXPECT_TRUE(IsDirectoryEmpty(kTmpPath));
|
||||||
|
f = tmpfile();
|
||||||
|
if (IsWindows()) {
|
||||||
|
EXPECT_FALSE(IsDirectoryEmpty(kTmpPath));
|
||||||
|
} else {
|
||||||
|
EXPECT_TRUE(IsDirectoryEmpty(kTmpPath));
|
||||||
|
}
|
||||||
|
EXPECT_SYS(0, 0, fstat(fileno(f), &st));
|
||||||
|
EXPECT_NE(010600, st.st_mode);
|
||||||
EXPECT_NE(-1, fputc('t', f));
|
EXPECT_NE(-1, fputc('t', f));
|
||||||
EXPECT_NE(-1, fflush(f));
|
EXPECT_NE(-1, fflush(f));
|
||||||
rewind(f);
|
rewind(f);
|
||||||
EXPECT_EQ('t', fgetc(f));
|
EXPECT_EQ('t', fgetc(f));
|
||||||
EXPECT_NE(-1, fclose(f));
|
EXPECT_EQ(0, fclose(f));
|
||||||
|
EXPECT_TRUE(IsDirectoryEmpty(kTmpPath));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(tmpfile, renameToRealFile) {
|
||||||
|
if (!IsLinux() || !__is_linux_2_6_23()) return;
|
||||||
|
FILE *f;
|
||||||
|
f = tmpfile();
|
||||||
|
ASSERT_EQ(2, fputs("hi", f));
|
||||||
|
ASSERT_SYS(0, 0,
|
||||||
|
linkat(AT_FDCWD, gc(xasprintf("/proc/self/fd/%d", fileno(f))),
|
||||||
|
AT_FDCWD, "real", AT_SYMLINK_FOLLOW));
|
||||||
|
ASSERT_EQ(0, fclose(f));
|
||||||
|
ASSERT_NE(NULL, (f = fopen("real", "r")));
|
||||||
|
ASSERT_EQ('h', fgetc(f));
|
||||||
|
ASSERT_EQ('i', fgetc(f));
|
||||||
|
ASSERT_EQ(0, fclose(f));
|
||||||
}
|
}
|
||||||
|
|
10
third_party/dlmalloc/dlmalloc.c
vendored
10
third_party/dlmalloc/dlmalloc.c
vendored
|
@ -1,17 +1,17 @@
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/intrin/likely.h"
|
|
||||||
#include "libc/intrin/weaken.h"
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
|
#include "libc/intrin/likely.h"
|
||||||
|
#include "libc/intrin/weaken.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nexgen32e/bsr.h"
|
#include "libc/nexgen32e/bsr.h"
|
||||||
#include "libc/nexgen32e/rdtsc.h"
|
#include "libc/nexgen32e/rdtsc.h"
|
||||||
#include "libc/stdio/rand.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/runtime/sysconf.h"
|
#include "libc/runtime/sysconf.h"
|
||||||
|
#include "libc/stdio/rand.h"
|
||||||
#include "libc/stdio/stdio.h"
|
#include "libc/stdio/stdio.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
|
@ -342,8 +342,8 @@ static int sys_trim(mstate m, size_t pad) {
|
||||||
size_t newsize = sp->size - extra;
|
size_t newsize = sp->size - extra;
|
||||||
(void)newsize; /* placate people compiling -Wunused-variable */
|
(void)newsize; /* placate people compiling -Wunused-variable */
|
||||||
/* Prefer mremap, fall back to munmap */
|
/* Prefer mremap, fall back to munmap */
|
||||||
if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
|
if (CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL ||
|
||||||
(CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
|
(!extra || !CALL_MUNMAP(sp->base + newsize, extra))) {
|
||||||
released = extra;
|
released = extra;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
9
third_party/lua/lunix.c
vendored
9
third_party/lua/lunix.c
vendored
|
@ -948,6 +948,14 @@ static int LuaUnixOpen(lua_State *L) {
|
||||||
luaL_optinteger(L, 2, O_RDONLY), luaL_optinteger(L, 3, 0)));
|
luaL_optinteger(L, 2, O_RDONLY), luaL_optinteger(L, 3, 0)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unix.tmpfd()
|
||||||
|
// ├─→ fd:int
|
||||||
|
// └─→ nil, unix.Errno
|
||||||
|
static int LuaUnixTmpfd(lua_State *L) {
|
||||||
|
int olderr = errno;
|
||||||
|
return SysretInteger(L, "tmpfd", olderr, tmpfd());
|
||||||
|
}
|
||||||
|
|
||||||
// unix.close(fd:int)
|
// unix.close(fd:int)
|
||||||
// ├─→ true
|
// ├─→ true
|
||||||
// └─→ nil, unix.Errno
|
// └─→ nil, unix.Errno
|
||||||
|
@ -2640,6 +2648,7 @@ static const luaL_Reg kLuaUnix[] = {
|
||||||
{"sync", LuaUnixSync}, // flushes files and disks
|
{"sync", LuaUnixSync}, // flushes files and disks
|
||||||
{"syslog", LuaUnixSyslog}, // logs to system log
|
{"syslog", LuaUnixSyslog}, // logs to system log
|
||||||
{"tiocgwinsz", LuaUnixTiocgwinsz}, // pseudoteletypewriter dimensions
|
{"tiocgwinsz", LuaUnixTiocgwinsz}, // pseudoteletypewriter dimensions
|
||||||
|
{"tmpfd", LuaUnixTmpfd}, // create anonymous file
|
||||||
{"truncate", LuaUnixTruncate}, // shrink or extend file medium
|
{"truncate", LuaUnixTruncate}, // shrink or extend file medium
|
||||||
{"umask", LuaUnixUmask}, // set default file mask
|
{"umask", LuaUnixUmask}, // set default file mask
|
||||||
{"unlink", LuaUnixUnlink}, // remove file
|
{"unlink", LuaUnixUnlink}, // remove file
|
||||||
|
|
37
third_party/make/job.c
vendored
37
third_party/make/job.c
vendored
|
@ -1753,7 +1753,7 @@ unveil_variable (const struct variable *var)
|
||||||
char *val, *tok, *state, *start;
|
char *val, *tok, *state, *start;
|
||||||
if (!var) return 0;
|
if (!var) return 0;
|
||||||
start = val = xstrdup (variable_expand (var->value));
|
start = val = xstrdup (variable_expand (var->value));
|
||||||
while (tok = strtok_r (start, " \t\r\n", &state))
|
while ((tok = strtok_r (start, " \t\r\n", &state)))
|
||||||
{
|
{
|
||||||
RETURN_ON_ERROR (Unveil (tok, "r"));
|
RETURN_ON_ERROR (Unveil (tok, "r"));
|
||||||
start = 0;
|
start = 0;
|
||||||
|
@ -1808,15 +1808,6 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
|
||||||
if (stack_limit.rlim_cur)
|
if (stack_limit.rlim_cur)
|
||||||
setrlimit (RLIMIT_STACK, &stack_limit);
|
setrlimit (RLIMIT_STACK, &stack_limit);
|
||||||
|
|
||||||
/* For any redirected FD, dup2() it to the standard FD.
|
|
||||||
They are all marked close-on-exec already. */
|
|
||||||
if (fdin >= 0 && fdin != FD_STDIN)
|
|
||||||
EINTRLOOP (r, dup2 (fdin, FD_STDIN));
|
|
||||||
if (fdout != FD_STDOUT)
|
|
||||||
EINTRLOOP (r, dup2 (fdout, FD_STDOUT));
|
|
||||||
if (fderr != FD_STDERR)
|
|
||||||
EINTRLOOP (r, dup2 (fderr, FD_STDERR));
|
|
||||||
|
|
||||||
g_strict = Vartoi (lookup_variable (STRING_SIZE_TUPLE (".STRICT")));
|
g_strict = Vartoi (lookup_variable (STRING_SIZE_TUPLE (".STRICT")));
|
||||||
|
|
||||||
intptr_t loc = (intptr_t)child; /* we can cast if it's on the heap ;_; */
|
intptr_t loc = (intptr_t)child; /* we can cast if it's on the heap ;_; */
|
||||||
|
@ -1846,7 +1837,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
|
||||||
{
|
{
|
||||||
OSS (error, NILF, "%s: command not found on $PATH: %s",
|
OSS (error, NILF, "%s: command not found on $PATH: %s",
|
||||||
argv[0], strerror (errno));
|
argv[0], strerror (errno));
|
||||||
return -1;
|
_Exit (127);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1955,7 +1946,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
|
||||||
{
|
{
|
||||||
OSS (error, NILF, "%s: touch target failed %s",
|
OSS (error, NILF, "%s: touch target failed %s",
|
||||||
c->file->name, strerror (errno));
|
c->file->name, strerror (errno));
|
||||||
return -1;
|
_Exit (127);
|
||||||
}
|
}
|
||||||
DB (DB_JOBS, (_("Unveiling %s with permissions %s\n"),
|
DB (DB_JOBS, (_("Unveiling %s with permissions %s\n"),
|
||||||
c->file->name, "rwx"));
|
c->file->name, "rwx"));
|
||||||
|
@ -1963,7 +1954,7 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
|
||||||
{
|
{
|
||||||
OSS (error, NILF, "%s: unveil target failed %s",
|
OSS (error, NILF, "%s: unveil target failed %s",
|
||||||
c->file->name, strerror (errno));
|
c->file->name, strerror (errno));
|
||||||
return -1;
|
_Exit (127);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2001,16 +1992,20 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* For any redirected FD, dup2() it to the standard FD.
|
||||||
|
They are all marked close-on-exec already. */
|
||||||
|
if (fdin >= 0 && fdin != FD_STDIN)
|
||||||
|
EINTRLOOP (r, dup2 (fdin, FD_STDIN));
|
||||||
|
if (fdout != FD_STDOUT)
|
||||||
|
EINTRLOOP (r, dup2 (fdout, FD_STDOUT));
|
||||||
|
if (fderr != FD_STDERR)
|
||||||
|
EINTRLOOP (r, dup2 (fderr, FD_STDERR));
|
||||||
|
|
||||||
/* Run the command. */
|
/* Run the command. */
|
||||||
exec_command (argv, child->environment);
|
exec_command (argv, child->environment);
|
||||||
|
|
||||||
if (pid < 0)
|
|
||||||
OSS (error, NILF, "%s: exec_command failed: %s",
|
|
||||||
argv[0], strerror (r));
|
|
||||||
|
|
||||||
return pid;
|
|
||||||
OnError:
|
OnError:
|
||||||
return -1;
|
_Exit (127);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2029,7 +2024,7 @@ exec_command (char **argv, char **envp)
|
||||||
if(errno == ENOENT)
|
if(errno == ENOENT)
|
||||||
OSS (error, NILF, "%s: command doesn't exist: %s",
|
OSS (error, NILF, "%s: command doesn't exist: %s",
|
||||||
argv[0], strerror (errno));
|
argv[0], strerror (errno));
|
||||||
else if(!g_strict && errno == ENOEXEC)
|
else if(errno == ENOEXEC)
|
||||||
{
|
{
|
||||||
/* The file was not a program. Try it as a shell script. */
|
/* The file was not a program. Try it as a shell script. */
|
||||||
const char *shell;
|
const char *shell;
|
||||||
|
@ -2063,7 +2058,7 @@ exec_command (char **argv, char **envp)
|
||||||
OSS (error, NILF, "%s: execv failed: %s",
|
OSS (error, NILF, "%s: execv failed: %s",
|
||||||
argv[0], strerror (errno));
|
argv[0], strerror (errno));
|
||||||
|
|
||||||
_exit (127);
|
_Exit (127);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
14
third_party/python/python.mk
vendored
14
third_party/python/python.mk
vendored
|
@ -2082,6 +2082,20 @@ o/$(MODE)/third_party/python/pythontester.com.dbg: \
|
||||||
$(APE_NO_MODIFY_SELF)
|
$(APE_NO_MODIFY_SELF)
|
||||||
@$(APELINK)
|
@$(APELINK)
|
||||||
|
|
||||||
|
# if these files exist, then python will try to open them
|
||||||
|
o/$(MODE)/third_party/python/Lib/test/test_robotparser.py.runs \
|
||||||
|
o/$(MODE)/third_party/python/Lib/test/test_wsgiref.py.runs: private \
|
||||||
|
.UNVEIL += \
|
||||||
|
/etc/mime.types \
|
||||||
|
/etc/httpd/mime.types \
|
||||||
|
/etc/httpd/conf/mime.types \
|
||||||
|
/etc/apache/mime.types \
|
||||||
|
/etc/apache2/mime.types \
|
||||||
|
/usr/local/etc/httpd/conf/mime.types \
|
||||||
|
/usr/local/lib/netscape/mime.types \
|
||||||
|
/usr/local/etc/httpd/conf/mime.types \
|
||||||
|
/usr/local/etc/mime.types
|
||||||
|
|
||||||
o/$(MODE)/third_party/python/Lib/test/test_grammar.py.runs: \
|
o/$(MODE)/third_party/python/Lib/test/test_grammar.py.runs: \
|
||||||
o/$(MODE)/third_party/python/pythontester.com
|
o/$(MODE)/third_party/python/pythontester.com
|
||||||
@$(COMPILE) -ACHECK -wtT$@ $(PYHARNESSARGS) $< -m test.test_grammar $(PYTESTARGS)
|
@$(COMPILE) -ACHECK -wtT$@ $(PYHARNESSARGS) $< -m test.test_grammar $(PYTESTARGS)
|
||||||
|
|
56
third_party/unzip/unix.c
vendored
56
third_party/unzip/unix.c
vendored
|
@ -133,62 +133,6 @@ static ZCONST char CannotSetTimestamps[] =
|
||||||
|
|
||||||
|
|
||||||
#ifndef SFX
|
#ifndef SFX
|
||||||
#ifdef NO_DIR /* for AT&T 3B1 */
|
|
||||||
|
|
||||||
#define _opendir(path) fopen(path,"r")
|
|
||||||
#define _closedir(dir) fclose(dir)
|
|
||||||
typedef FILE DIR;
|
|
||||||
typedef struct zdir {
|
|
||||||
FILE *dirhandle;
|
|
||||||
struct dirent *entry;
|
|
||||||
} DIR
|
|
||||||
DIR *opendir OF((ZCONST char *dirspec));
|
|
||||||
void closedir OF((DIR *dirp));
|
|
||||||
struct dirent *readdir OF((DIR *dirp));
|
|
||||||
|
|
||||||
DIR *opendir(dirspec)
|
|
||||||
ZCONST char *dirspec;
|
|
||||||
{
|
|
||||||
DIR *dirp;
|
|
||||||
|
|
||||||
if ((dirp = malloc(sizeof(DIR)) != NULL) {
|
|
||||||
if ((dirp->dirhandle = fopen(dirspec, "r")) == NULL) {
|
|
||||||
free(dirp);
|
|
||||||
dirp = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return dirp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void closedir(dirp)
|
|
||||||
DIR *dirp;
|
|
||||||
{
|
|
||||||
fclose(dirp->dirhandle);
|
|
||||||
free(dirp);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Apparently originally by Rich Salz.
|
|
||||||
* Cleaned up and modified by James W. Birdsall.
|
|
||||||
*/
|
|
||||||
struct dirent *readdir(dirp)
|
|
||||||
DIR *dirp;
|
|
||||||
{
|
|
||||||
|
|
||||||
if (dirp == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
if (fread(&(dirp->entry), sizeof (struct dirent), 1,
|
|
||||||
dirp->dirhandle) == 0)
|
|
||||||
return (struct dirent *)NULL;
|
|
||||||
else if ((dirp->entry).d_ino)
|
|
||||||
return &(dirp->entry);
|
|
||||||
|
|
||||||
} /* end function readdir() */
|
|
||||||
|
|
||||||
#endif /* NO_DIR */
|
|
||||||
|
|
||||||
|
|
||||||
/**********************/
|
/**********************/
|
||||||
/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
|
/* Function do_wild() */ /* for porting: dir separator; match(ignore_case) */
|
||||||
|
|
|
@ -2361,7 +2361,6 @@ UNIX MODULE
|
||||||
- `O_NONBLOCK` asks read/write to fail with EAGAIN rather than block
|
- `O_NONBLOCK` asks read/write to fail with EAGAIN rather than block
|
||||||
- `O_DIRECT` it's complicated (not supported on Apple and OpenBSD)
|
- `O_DIRECT` it's complicated (not supported on Apple and OpenBSD)
|
||||||
- `O_DIRECTORY` useful for stat'ing (hint on UNIX but required on NT)
|
- `O_DIRECTORY` useful for stat'ing (hint on UNIX but required on NT)
|
||||||
- `O_TMPFILE` try to make temp more secure (Linux and Windows only)
|
|
||||||
- `O_NOFOLLOW` fail if it's a symlink (zero on Windows)
|
- `O_NOFOLLOW` fail if it's a symlink (zero on Windows)
|
||||||
- `O_DSYNC` it's complicated (zero on non-Linux/Apple)
|
- `O_DSYNC` it's complicated (zero on non-Linux/Apple)
|
||||||
- `O_RSYNC` it's complicated (zero on non-Linux/Apple)
|
- `O_RSYNC` it's complicated (zero on non-Linux/Apple)
|
||||||
|
@ -4201,6 +4200,25 @@ UNIX MODULE
|
||||||
|
|
||||||
Returns cellular dimensions of pseudoteletypewriter display.
|
Returns cellular dimensions of pseudoteletypewriter display.
|
||||||
|
|
||||||
|
unix.tmpfd()
|
||||||
|
├─→ fd:int
|
||||||
|
└─→ nil, unix.Errno
|
||||||
|
|
||||||
|
Returns file descriptor of open anonymous file.
|
||||||
|
|
||||||
|
This creates a secure temporary file inside `$TMPDIR`. If it isn't
|
||||||
|
defined, then `/tmp` is used on UNIX and GetTempPath() is used on
|
||||||
|
the New Technology. This resolution of `$TMPDIR` happens once in a
|
||||||
|
ctor, which is copied to the `kTmpDir` global.
|
||||||
|
|
||||||
|
Once close() is called, the returned file is guaranteed to be
|
||||||
|
deleted automatically. On UNIX the file is unlink()'d before this
|
||||||
|
function returns. On the New Technology it happens upon close().
|
||||||
|
|
||||||
|
On the New Technology, temporary files created by this function
|
||||||
|
should have better performance, because `kNtFileAttributeTemporary`
|
||||||
|
asks the kernel to more aggressively cache and reduce i/o ops.
|
||||||
|
|
||||||
|
|
||||||
────────────────────────────────────────────────────────────────────────────────
|
────────────────────────────────────────────────────────────────────────────────
|
||||||
UNIX DIR OBJECT
|
UNIX DIR OBJECT
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue