mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +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 tgkill(int, int, int);
|
||||
int tkill(int, int);
|
||||
int tmpfd(void);
|
||||
int touch(const char *, uint32_t);
|
||||
int truncate(const char *, uint64_t);
|
||||
int ttyname_r(int, char *, size_t);
|
||||
|
|
|
@ -1939,12 +1939,9 @@ privileged int sys_pledge_linux(unsigned long ipromises, int mode) {
|
|||
} else {
|
||||
// non-trapping mode
|
||||
//
|
||||
// 1. our sigsys error message handler can't be inherited across
|
||||
// execve() boundaries so if you've pledged exec then that'll
|
||||
// mean no error messages for you.
|
||||
//
|
||||
// 2. we do not trap pledge("", 0) because that would go against
|
||||
// its documented purpose of only permitted exit().
|
||||
// our sigsys error message handler can't be inherited across
|
||||
// execve() boundaries so if you've pledged exec then that'll
|
||||
// likely cause a SIGSYS in your child after the exec happens
|
||||
switch (mode & PLEDGE_PENALTY_MASK) {
|
||||
case PLEDGE_PENALTY_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_CLOEXEC,"CLOEXEC" //
|
||||
.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_APPEND,"APPEND" // weird on nt
|
||||
.e O_TMPFILE,"TMPFILE" // linux, windows
|
||||
.e O_NOFOLLOW,"NOFOLLOW" // unix
|
||||
.e O_SYNC,"SYNC" // unix
|
||||
.e O_ASYNC,"ASYNC" // unix
|
||||
|
|
|
@ -17,59 +17,58 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/stdio/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.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
|
||||
* will be unlink()'d before this function returns. The file content
|
||||
* will be released from disk once fclose() is called.
|
||||
* FILE *f;
|
||||
* if (!(f = tmpfile())) {
|
||||
* 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
|
||||
* @threadsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
FILE *tmpfile(void) {
|
||||
int fd;
|
||||
FILE *f;
|
||||
unsigned x;
|
||||
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+"))) {
|
||||
return f;
|
||||
} else {
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
} else if (errno == EEXIST) {
|
||||
errno = e;
|
||||
if ((fd = tmpfd()) != -1) {
|
||||
if ((f = fdopen(fd, "w+"))) {
|
||||
return f;
|
||||
} else {
|
||||
break;
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
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_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_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_NONBLOCK 0x00000800 0x00000004 0x00000004 0x00000004 0x00000004 0x00000800 # 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"
|
||||
.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 │
|
||||
│ 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/temp.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.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) {
|
||||
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, fflush(f));
|
||||
rewind(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/intrin/likely.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/likely.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/stdio/rand.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"
|
||||
#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;
|
||||
(void)newsize; /* placate people compiling -Wunused-variable */
|
||||
/* Prefer mremap, fall back to munmap */
|
||||
if ((CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL) ||
|
||||
(CALL_MUNMAP(sp->base + newsize, extra) == 0)) {
|
||||
if (CALL_MREMAP(sp->base, sp->size, newsize, 0) != MFAIL ||
|
||||
(!extra || !CALL_MUNMAP(sp->base + newsize, 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)));
|
||||
}
|
||||
|
||||
// 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)
|
||||
// ├─→ true
|
||||
// └─→ nil, unix.Errno
|
||||
|
@ -2640,6 +2648,7 @@ static const luaL_Reg kLuaUnix[] = {
|
|||
{"sync", LuaUnixSync}, // flushes files and disks
|
||||
{"syslog", LuaUnixSyslog}, // logs to system log
|
||||
{"tiocgwinsz", LuaUnixTiocgwinsz}, // pseudoteletypewriter dimensions
|
||||
{"tmpfd", LuaUnixTmpfd}, // create anonymous file
|
||||
{"truncate", LuaUnixTruncate}, // shrink or extend file medium
|
||||
{"umask", LuaUnixUmask}, // set default file mask
|
||||
{"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;
|
||||
if (!var) return 0;
|
||||
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"));
|
||||
start = 0;
|
||||
|
@ -1808,15 +1808,6 @@ child_execute_job (struct childbase *child, int good_stdin, char **argv)
|
|||
if (stack_limit.rlim_cur)
|
||||
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")));
|
||||
|
||||
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",
|
||||
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",
|
||||
c->file->name, strerror (errno));
|
||||
return -1;
|
||||
_Exit (127);
|
||||
}
|
||||
DB (DB_JOBS, (_("Unveiling %s with permissions %s\n"),
|
||||
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",
|
||||
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. */
|
||||
exec_command (argv, child->environment);
|
||||
|
||||
if (pid < 0)
|
||||
OSS (error, NILF, "%s: exec_command failed: %s",
|
||||
argv[0], strerror (r));
|
||||
|
||||
return pid;
|
||||
OnError:
|
||||
return -1;
|
||||
_Exit (127);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2029,7 +2024,7 @@ exec_command (char **argv, char **envp)
|
|||
if(errno == ENOENT)
|
||||
OSS (error, NILF, "%s: command doesn't exist: %s",
|
||||
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. */
|
||||
const char *shell;
|
||||
|
@ -2063,7 +2058,7 @@ exec_command (char **argv, char **envp)
|
|||
OSS (error, NILF, "%s: execv failed: %s",
|
||||
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)
|
||||
@$(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/pythontester.com
|
||||
@$(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
|
||||
#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) */
|
||||
|
|
|
@ -2361,7 +2361,6 @@ UNIX MODULE
|
|||
- `O_NONBLOCK` asks read/write to fail with EAGAIN rather than block
|
||||
- `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_TMPFILE` try to make temp more secure (Linux and Windows only)
|
||||
- `O_NOFOLLOW` fail if it's a symlink (zero on Windows)
|
||||
- `O_DSYNC` 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.
|
||||
|
||||
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
|
||||
|
|
Loading…
Reference in a new issue