mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 05:42:29 +00:00
Introduce --strace flag for system call tracing
This is similar to the --ftrace (c function call trace) flag, except it's less noisy since it only logs system calls to stderr. Having this flag is valuable because (1) system call tracing tells us a lot about the behavior of complex programs and (2) it's usually very hard to get system call tracing on various operating systems, e.g. strace, ktrace, dtruss, truss, nttrace, etc. Especially on Apple platforms where even with the special boot trick, debuggers still aren't guaranteed to work. make -j8 o//examples o//examples/hello.com --strace This is enabled by default in MODE=, MODE=opt, and MODE=dbg. In MODE=dbg extra information will be printed. make -j8 MODE=dbg o/dbg/examples o/dbg/examples/hello.com --strace |& less This change also changes: - Rename IsText() → _istext() - Rename IsUtf8() → _isutf8() - Fix madvise() on Windows NT - Fix empty string case of inet_ntop() - vfork() wrapper now saves and restores errno - Update xsigaction() to yoink syscall support
This commit is contained in:
parent
c541225af0
commit
14e192e5ba
138 changed files with 1519 additions and 631 deletions
|
@ -5,6 +5,7 @@
|
||||||
#
|
#
|
||||||
# - `make`
|
# - `make`
|
||||||
# - Backtraces
|
# - Backtraces
|
||||||
|
# - Syscall tracing
|
||||||
# - Function tracing
|
# - Function tracing
|
||||||
# - Reasonably small
|
# - Reasonably small
|
||||||
# - Reasonably optimized
|
# - Reasonably optimized
|
||||||
|
@ -13,6 +14,7 @@ ifeq ($(MODE),)
|
||||||
CONFIG_CCFLAGS += \
|
CONFIG_CCFLAGS += \
|
||||||
$(BACKTRACES) \
|
$(BACKTRACES) \
|
||||||
$(FTRACE) \
|
$(FTRACE) \
|
||||||
|
-DSYSDEBUG \
|
||||||
-Og
|
-Og
|
||||||
TARGET_ARCH ?= \
|
TARGET_ARCH ?= \
|
||||||
-msse3
|
-msse3
|
||||||
|
@ -23,6 +25,8 @@ endif
|
||||||
# - `make MODE=opt`
|
# - `make MODE=opt`
|
||||||
# - Backtraces
|
# - Backtraces
|
||||||
# - More optimized
|
# - More optimized
|
||||||
|
# - Syscall tracing
|
||||||
|
# - Function tracing
|
||||||
# - Reasonably small
|
# - Reasonably small
|
||||||
# - No memory corruption detection
|
# - No memory corruption detection
|
||||||
# - assert() / CHECK_xx() may leak code into binary for debuggability
|
# - assert() / CHECK_xx() may leak code into binary for debuggability
|
||||||
|
@ -35,6 +39,7 @@ CONFIG_CPPFLAGS += \
|
||||||
CONFIG_CCFLAGS += \
|
CONFIG_CCFLAGS += \
|
||||||
$(BACKTRACES) \
|
$(BACKTRACES) \
|
||||||
$(FTRACE) \
|
$(FTRACE) \
|
||||||
|
-DSYSDEBUG \
|
||||||
-O3
|
-O3
|
||||||
TARGET_ARCH ?= \
|
TARGET_ARCH ?= \
|
||||||
-march=native
|
-march=native
|
||||||
|
@ -122,6 +127,7 @@ CONFIG_CPPFLAGS += \
|
||||||
CONFIG_CCFLAGS += \
|
CONFIG_CCFLAGS += \
|
||||||
$(BACKTRACES) \
|
$(BACKTRACES) \
|
||||||
$(FTRACE) \
|
$(FTRACE) \
|
||||||
|
-DSYSDEBUG \
|
||||||
-O2 \
|
-O2 \
|
||||||
-fno-inline
|
-fno-inline
|
||||||
CONFIG_COPTS += \
|
CONFIG_COPTS += \
|
||||||
|
@ -287,7 +293,7 @@ endif
|
||||||
# LLVM Mode
|
# LLVM Mode
|
||||||
ifeq ($(MODE), llvm)
|
ifeq ($(MODE), llvm)
|
||||||
TARGET_ARCH ?= -msse3
|
TARGET_ARCH ?= -msse3
|
||||||
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -O2
|
CONFIG_CCFLAGS += $(BACKTRACES) $(FTRACE) -DSYSDEBUG -O2
|
||||||
AS = clang
|
AS = clang
|
||||||
CC = clang
|
CC = clang
|
||||||
CXX = clang++
|
CXX = clang++
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -30,10 +31,14 @@
|
||||||
* @see fchdir()
|
* @see fchdir()
|
||||||
*/
|
*/
|
||||||
int chdir(const char *path) {
|
int chdir(const char *path) {
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
return sys_chdir(path);
|
rc = efault();
|
||||||
|
} else if (!IsWindows()) {
|
||||||
|
rc = sys_chdir(path);
|
||||||
} else {
|
} else {
|
||||||
return sys_chdir_nt(path);
|
rc = sys_chdir_nt(path);
|
||||||
}
|
}
|
||||||
|
STRACE("chdir(%#s) → %d% m", path, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/sock/internal.h"
|
#include "libc/sock/internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -61,6 +61,6 @@ int close(int fd) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
__releasefd(fd);
|
__releasefd(fd);
|
||||||
SYSDEBUG("close(%d) -> %d", fd, rc);
|
STRACE("%s(%d) → %d% m", "close", fd, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/bits/safemacros.internal.h"
|
#include "libc/bits/safemacros.internal.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
#include "libc/log/libfatal.internal.h"
|
||||||
|
@ -159,6 +159,6 @@ noasan char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
||||||
errno = f;
|
errno = f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SYSDEBUG("commandv(%#s, %p) → %#s% m", name, pathbuf, res);
|
STRACE("commandv(%#s, %p) → %#s% m", name, pathbuf, res);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
│ 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/log/libfatal.internal.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -28,21 +28,19 @@
|
||||||
noasan const char *DescribeFrame(int x) {
|
noasan const char *DescribeFrame(int x) {
|
||||||
/* asan runtime depends on this function */
|
/* asan runtime depends on this function */
|
||||||
char *p;
|
char *p;
|
||||||
static char buf[128];
|
static char buf[32];
|
||||||
if (IsShadowFrame(x)) {
|
if (IsShadowFrame(x)) {
|
||||||
p = buf;
|
ksnprintf(buf, sizeof(buf), " /*shadow:%.12p*/", UNSHADOW(ADDR(x)));
|
||||||
p = __stpcpy(p, " shadow of ");
|
|
||||||
p = __fixcpy(p, UNSHADOW(ADDR(x)), 48);
|
|
||||||
return buf;
|
return buf;
|
||||||
return " shadow ";
|
return " /*shadow*/ ";
|
||||||
} else if (IsAutoFrame(x)) {
|
} else if (IsAutoFrame(x)) {
|
||||||
return " automap";
|
return " /*automap*/";
|
||||||
} else if (IsFixedFrame(x)) {
|
} else if (IsFixedFrame(x)) {
|
||||||
return " fixed ";
|
return " /*fixed*/ ";
|
||||||
} else if (IsArenaFrame(x)) {
|
} else if (IsArenaFrame(x)) {
|
||||||
return " arena ";
|
return " /*arena*/ ";
|
||||||
} else if (IsStaticStackFrame(x)) {
|
} else if (IsStaticStackFrame(x)) {
|
||||||
return " stack ";
|
return " /*stack*/ ";
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
|
@ -20,19 +20,26 @@
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
|
|
||||||
|
static noasan char DescribeMapType(int flags) {
|
||||||
|
switch (flags & MAP_TYPE) {
|
||||||
|
case MAP_FILE:
|
||||||
|
return 'f';
|
||||||
|
case MAP_PRIVATE:
|
||||||
|
return 'p';
|
||||||
|
case MAP_SHARED:
|
||||||
|
return 's';
|
||||||
|
default:
|
||||||
|
return '?';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
|
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
|
||||||
/* asan runtime depends on this function */
|
/* asan runtime depends on this function */
|
||||||
p[0] = (prot & PROT_READ) ? 'r' : '-';
|
p[0] = (prot & PROT_READ) ? 'r' : '-';
|
||||||
p[1] = (prot & PROT_WRITE) ? 'w' : '-';
|
p[1] = (prot & PROT_WRITE) ? 'w' : '-';
|
||||||
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
|
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
|
||||||
if (flags & MAP_PRIVATE) {
|
p[3] = DescribeMapType(flags);
|
||||||
p[3] = 'p';
|
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
|
||||||
} else if (flags & MAP_SHARED) {
|
|
||||||
p[3] = 's';
|
|
||||||
} else {
|
|
||||||
p[3] = '?';
|
|
||||||
}
|
|
||||||
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : 'f';
|
|
||||||
p[5] = (flags & MAP_GROWSDOWN) ? 'S' : '-';
|
p[5] = (flags & MAP_GROWSDOWN) ? 'S' : '-';
|
||||||
p[6] = (flags & MAP_FIXED) ? 'F' : '-';
|
p[6] = (flags & MAP_FIXED) ? 'F' : '-';
|
||||||
p[7] = 0;
|
p[7] = 0;
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/enum/filemapflags.h"
|
#include "libc/nt/enum/filemapflags.h"
|
||||||
#include "libc/nt/enum/pageflags.h"
|
#include "libc/nt/enum/pageflags.h"
|
||||||
|
@ -46,14 +46,14 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
dm.maphandle = CreateFileMappingNuma(-1, &kNtIsInheritable,
|
dm.maphandle = CreateFileMappingNuma(-1, &kNtIsInheritable,
|
||||||
kNtPageExecuteReadwrite, upsize >> 32,
|
kNtPageExecuteReadwrite, upsize >> 32,
|
||||||
upsize, NULL, kNtNumaNoPreferredNode);
|
upsize, NULL, kNtNumaNoPreferredNode);
|
||||||
SYSDEBUG("CreateFileMappingNuma(-1, kNtPageExecuteReadwrite, 0x%x/0x%x) -> "
|
STRACE(
|
||||||
"0x%x",
|
"CreateFileMappingNuma(-1, kNtPageExecuteReadwrite, %'zu/%'zu) -> %p",
|
||||||
upsize, size, dm.maphandle);
|
upsize, size, dm.maphandle);
|
||||||
if (dm.maphandle) {
|
if (dm.maphandle) {
|
||||||
dm.addr =
|
dm.addr =
|
||||||
MapViewOfFileExNuma(dm.maphandle, kNtFileMapWrite | kNtFileMapExecute,
|
MapViewOfFileExNuma(dm.maphandle, kNtFileMapWrite | kNtFileMapExecute,
|
||||||
0, 0, upsize, addr, kNtNumaNoPreferredNode);
|
0, 0, upsize, addr, kNtNumaNoPreferredNode);
|
||||||
SYSDEBUG("MapViewOfFileExNuma(WX, 0x%x) -> addr:0x%x", addr, dm.addr);
|
STRACE("MapViewOfFileExNuma(WX, %p) → addr:%p", addr, dm.addr);
|
||||||
if (dm.addr) {
|
if (dm.addr) {
|
||||||
for (i = 0; i < size; i += got) {
|
for (i = 0; i < size; i += got) {
|
||||||
got = 0;
|
got = 0;
|
||||||
|
@ -78,20 +78,16 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
|
||||||
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
|
(prot & PROT_WRITE) ? kNtPageExecuteReadwrite : kNtPageExecuteRead,
|
||||||
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
|
handle != -1 ? 0 : size >> 32, handle != -1 ? 0 : size, NULL,
|
||||||
kNtNumaNoPreferredNode);
|
kNtNumaNoPreferredNode);
|
||||||
SYSDEBUG("CreateFileMappingNuma(fhand:%d, prot:%s, size:0x%x) -> "
|
STRACE("CreateFileMappingNuma(fhand:%ld, prot:%s, size:%'zu) → %p", handle,
|
||||||
"handle:0x%x",
|
(prot & PROT_WRITE) ? "XRW" : "XR", handle != -1 ? 0 : size);
|
||||||
handle, (prot & PROT_WRITE) ? "XRW" : "XR",
|
|
||||||
handle != -1 ? 0 : size);
|
|
||||||
if (dm.maphandle) {
|
if (dm.maphandle) {
|
||||||
dm.addr = MapViewOfFileExNuma(
|
dm.addr = MapViewOfFileExNuma(
|
||||||
dm.maphandle,
|
dm.maphandle,
|
||||||
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
|
(prot & PROT_WRITE) ? kNtFileMapWrite | kNtFileMapExecute
|
||||||
: kNtFileMapRead | kNtFileMapExecute,
|
: kNtFileMapRead | kNtFileMapExecute,
|
||||||
off >> 32, off, size, addr, kNtNumaNoPreferredNode);
|
off >> 32, off, size, addr, kNtNumaNoPreferredNode);
|
||||||
SYSDEBUG(
|
STRACE("MapViewOfFileExNuma(prot:%s, off:%'ld, size:%'zu, addr:%p) → %p",
|
||||||
"MapViewOfFileExNuma(prot:%s, off:0x%x, size:0x%x, addr:0x%x) -> "
|
(prot & PROT_WRITE) ? "WX" : "RX", off, size, addr, dm.addr);
|
||||||
"addr:0x%x",
|
|
||||||
(prot & PROT_WRITE) ? "WX" : "RX", off, size, addr, dm.addr);
|
|
||||||
if (dm.addr) {
|
if (dm.addr) {
|
||||||
return dm;
|
return dm;
|
||||||
} else {
|
} else {
|
|
@ -17,7 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/runtime/directmap.internal.h"
|
#include "libc/runtime/directmap.internal.h"
|
||||||
|
@ -36,20 +36,18 @@ noasan struct DirectMap sys_mmap(void *addr, size_t size, int prot, int flags,
|
||||||
int fd, int64_t off) {
|
int fd, int64_t off) {
|
||||||
/* asan runtime depends on this function */
|
/* asan runtime depends on this function */
|
||||||
char mode[8];
|
char mode[8];
|
||||||
struct DirectMap dm;
|
struct DirectMap d;
|
||||||
if (!IsWindows() && !IsMetal()) {
|
if (!IsWindows() && !IsMetal()) {
|
||||||
dm.addr = __sys_mmap(addr, size, prot, flags, fd, off, off);
|
d.addr = __sys_mmap(addr, size, prot, flags, fd, off, off);
|
||||||
SYSDEBUG("sys_mmap(0x%p%s, 0x%x, %s, %d, %d) -> 0x%p %s", addr,
|
d.maphandle = kNtInvalidHandleValue;
|
||||||
DescribeFrame((intptr_t)addr >> 16), size,
|
|
||||||
DescribeMapping(prot, flags, mode), (long)fd, off, dm.addr,
|
|
||||||
dm.addr != MAP_FAILED ? "" : strerror(errno));
|
|
||||||
dm.maphandle = kNtInvalidHandleValue;
|
|
||||||
return dm;
|
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
return sys_mmap_metal(addr, size, prot, flags, fd, off);
|
d = sys_mmap_metal(addr, size, prot, flags, fd, off);
|
||||||
} else {
|
} else {
|
||||||
return sys_mmap_nt(addr, size, prot, flags,
|
d = sys_mmap_nt(addr, size, prot, flags,
|
||||||
fd != -1 ? g_fds.p[fd].handle : kNtInvalidHandleValue,
|
fd != -1 ? g_fds.p[fd].handle : kNtInvalidHandleValue, off);
|
||||||
off);
|
|
||||||
}
|
}
|
||||||
|
STRACE("sys_mmap(%.12p%s, %'zu, %s, %d, %'ld) → {%.12p, %p}% m", addr,
|
||||||
|
DescribeFrame((intptr_t)addr >> 16), size,
|
||||||
|
DescribeMapping(prot, flags, mode), fd, off, d.addr, d.maphandle);
|
||||||
|
return d;
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,6 +36,6 @@ int dup(int fd) {
|
||||||
} else {
|
} else {
|
||||||
fd2 = sys_dup_nt(fd, -1, 0);
|
fd2 = sys_dup_nt(fd, -1, 0);
|
||||||
}
|
}
|
||||||
SYSDEBUG("dup(%d) -> %d", fd, fd2);
|
STRACE("%s(%d) → %d% m", "dup", fd, fd2);
|
||||||
return fd2;
|
return fd2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -32,11 +32,14 @@
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
int dup2(int oldfd, int newfd) {
|
int dup2(int oldfd, int newfd) {
|
||||||
SYSDEBUG("dup2(%d, %d)", oldfd, newfd);
|
int rc;
|
||||||
if (oldfd == newfd) return newfd;
|
if (oldfd == newfd) {
|
||||||
if (!IsWindows()) {
|
rc = newfd;
|
||||||
return sys_dup3(oldfd, newfd, 0);
|
} else if (!IsWindows()) {
|
||||||
|
rc = sys_dup3(oldfd, newfd, 0);
|
||||||
} else {
|
} else {
|
||||||
return sys_dup_nt(oldfd, newfd, 0);
|
rc = sys_dup_nt(oldfd, newfd, 0);
|
||||||
}
|
}
|
||||||
|
STRACE("dup2(%d, %d) → %d% m", oldfd, newfd, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
@ -36,10 +36,12 @@
|
||||||
* @see dup(), dup2()
|
* @see dup(), dup2()
|
||||||
*/
|
*/
|
||||||
int dup3(int oldfd, int newfd, int flags) {
|
int dup3(int oldfd, int newfd, int flags) {
|
||||||
SYSDEBUG("dup3(%d, %d, %d)", oldfd, newfd, flags);
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_dup3(oldfd, newfd, flags);
|
rc = sys_dup3(oldfd, newfd, flags);
|
||||||
} else {
|
} else {
|
||||||
return sys_dup_nt(oldfd, newfd, flags);
|
rc = sys_dup_nt(oldfd, newfd, flags);
|
||||||
}
|
}
|
||||||
|
STRACE("dup3(%d, %d, %d) → %d% m", oldfd, newfd, flags, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
|
@ -39,35 +39,41 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
int execve(const char *program, char *const argv[], char *const envp[]) {
|
int execve(const char *prog, char *const argv[], char *const envp[]) {
|
||||||
|
int rc;
|
||||||
size_t i;
|
size_t i;
|
||||||
if (!program || !argv || !envp) return efault();
|
if (!prog || !argv || !envp ||
|
||||||
if (IsAsan() &&
|
(IsAsan() &&
|
||||||
(!__asan_is_valid(program, 1) || !__asan_is_valid_strlist(argv) ||
|
(!__asan_is_valid(prog, 1) || !__asan_is_valid_strlist(argv) ||
|
||||||
!__asan_is_valid_strlist(envp))) {
|
!__asan_is_valid_strlist(envp)))) {
|
||||||
return efault();
|
rc = efault();
|
||||||
}
|
|
||||||
if (DEBUGSYS) {
|
|
||||||
kprintf("SYS: execve(%s, {", program);
|
|
||||||
for (i = 0; argv[i]; ++i) {
|
|
||||||
if (i) kprintf(", ");
|
|
||||||
kprintf("%s", argv[i]);
|
|
||||||
}
|
|
||||||
kprintf("}, {");
|
|
||||||
for (i = 0; envp[i]; ++i) {
|
|
||||||
if (i) kprintf(", ");
|
|
||||||
kprintf("%s", envp[i]);
|
|
||||||
}
|
|
||||||
kprintf("})\n");
|
|
||||||
}
|
|
||||||
for (i = 3; i < g_fds.n; ++i) {
|
|
||||||
if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) {
|
|
||||||
close(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!IsWindows()) {
|
|
||||||
return sys_execve(program, argv, envp);
|
|
||||||
} else {
|
} else {
|
||||||
return sys_execve_nt(program, argv, envp);
|
#ifdef SYSDEBUG
|
||||||
|
if (__strace > 0) {
|
||||||
|
kprintf(STRACE_PROLOGUE "execve(%#s, {", prog);
|
||||||
|
for (i = 0; argv[i]; ++i) {
|
||||||
|
if (i) kprintf(", ");
|
||||||
|
kprintf("%#s", argv[i]);
|
||||||
|
}
|
||||||
|
kprintf("}, {");
|
||||||
|
for (i = 0; envp[i]; ++i) {
|
||||||
|
if (i) kprintf(", ");
|
||||||
|
kprintf("%#s", envp[i]);
|
||||||
|
}
|
||||||
|
kprintf("})%n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (i = 3; i < g_fds.n; ++i) {
|
||||||
|
if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) {
|
||||||
|
close(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!IsWindows()) {
|
||||||
|
rc = sys_execve(prog, argv, envp);
|
||||||
|
} else {
|
||||||
|
rc = sys_execve_nt(prog, argv, envp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
STRACE("execve(%#s) failed %d% m", prog, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -42,14 +42,13 @@
|
||||||
int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) {
|
int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) {
|
||||||
int rc;
|
int rc;
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
|
||||||
rc = -1; /* TODO(jart): implement me */
|
STRACE("zipos fchmodat not supported yet");
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
rc = sys_fchmodat(dirfd, path, mode, flags);
|
rc = sys_fchmodat(dirfd, path, mode, flags);
|
||||||
} else {
|
} else {
|
||||||
rc = sys_fchmodat_nt(dirfd, path, mode, flags);
|
rc = sys_fchmodat_nt(dirfd, path, mode, flags);
|
||||||
}
|
}
|
||||||
SYSDEBUG("fchmodat(%d, %s, %o, %d) -> %d %s", (long)dirfd, path, mode, flags,
|
STRACE("fchmodat(%d, %#s, %#o, %d) → %d% m", dirfd, path, mode, flags, rc);
|
||||||
rc != -1 ? "" : strerror(errno));
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -39,9 +40,15 @@
|
||||||
*/
|
*/
|
||||||
int fchownat(int dirfd, const char *path, uint32_t uid, uint32_t gid,
|
int fchownat(int dirfd, const char *path, uint32_t uid, uint32_t gid,
|
||||||
int flags) {
|
int flags) {
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
int rc;
|
||||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
return -1; /* TODO(jart): implement me */
|
rc = efault();
|
||||||
|
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
|
||||||
|
STRACE("zipos fchownat not supported yet");
|
||||||
|
} else {
|
||||||
|
rc = sys_fchownat(dirfd, path, uid, gid, flags);
|
||||||
}
|
}
|
||||||
return sys_fchownat(dirfd, path, uid, gid, flags);
|
STRACE("fchownat(%d, %#s, %d, %d, %#b) → %d% m", dirfd, path, uid, gid, flags,
|
||||||
|
rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,12 @@
|
||||||
*
|
*
|
||||||
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
|
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
|
||||||
*
|
*
|
||||||
|
* This function lets you duplicate file descriptors without running
|
||||||
|
* into an edge case where they take over stdio handles:
|
||||||
|
*
|
||||||
|
* CHECK_GE((newfd = fcntl(oldfd, F_DUPFD, 3)), 3);
|
||||||
|
* CHECK_GE((newfd = fcntl(oldfd, F_DUPFD_CLOEXEC, 3)), 3);
|
||||||
|
*
|
||||||
* This function implements POSIX Advisory Locks, e.g.
|
* This function implements POSIX Advisory Locks, e.g.
|
||||||
*
|
*
|
||||||
* CHECK_NE(-1, fcntl(zfd, F_SETLKW, &(struct flock){F_WRLCK}));
|
* CHECK_NE(-1, fcntl(zfd, F_SETLKW, &(struct flock){F_WRLCK}));
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,9 +29,12 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int fdatasync(int fd) {
|
int fdatasync(int fd) {
|
||||||
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_fdatasync(fd);
|
rc = sys_fdatasync(fd);
|
||||||
} else {
|
} else {
|
||||||
return sys_fdatasync_nt(fd);
|
rc = sys_fdatasync_nt(fd);
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%d) → %d% m", "fdatasync", fd, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,8 +69,7 @@ bool fileexists(const char *path) {
|
||||||
} else {
|
} else {
|
||||||
res = false;
|
res = false;
|
||||||
}
|
}
|
||||||
SYSDEBUG("fileexists(%s) -> %s %s", path, res ? "true" : "false",
|
STRACE("fileexists(%#s) → %hhhd% m", path, res);
|
||||||
res ? "" : strerror(errno));
|
|
||||||
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
||||||
errno = e;
|
errno = e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,9 +31,12 @@
|
||||||
* @return 0 on success, or -1 w/ errno
|
* @return 0 on success, or -1 w/ errno
|
||||||
*/
|
*/
|
||||||
int flock(int fd, int op) {
|
int flock(int fd, int op) {
|
||||||
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_flock(fd, op);
|
rc = sys_flock(fd, op);
|
||||||
} else {
|
} else {
|
||||||
return sys_flock_nt(fd, op);
|
rc = sys_flock_nt(fd, op);
|
||||||
}
|
}
|
||||||
|
STRACE("flock(%d, %d) → %d% m", fd, op, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nexgen32e/bsr.h"
|
#include "libc/nexgen32e/bsr.h"
|
||||||
|
@ -64,7 +64,7 @@ static textwindows uint32_t GetSizeOfReparsePoint(int64_t fh) {
|
||||||
z += x < 0200 ? 1 : bsrl(tpenc(x)) >> 3;
|
z += x < 0200 ? 1 : bsrl(tpenc(x)) >> 3;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("GetSizeOfReparsePoint failed %d", GetLastError());
|
STRACE("%s failed %m", "GetSizeOfReparsePoint");
|
||||||
}
|
}
|
||||||
return z;
|
return z;
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) {
|
||||||
st->st_blocks = ROUNDUP(actualsize, PAGESIZE) / 512;
|
st->st_blocks = ROUNDUP(actualsize, PAGESIZE) / 512;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("GetFileInformationByHandle failed %d", GetLastError());
|
STRACE("%s failed %m", "GetFileInformationByHandle");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -130,7 +130,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) {
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("GetFileType failed %d", GetLastError());
|
STRACE("%s failed %m", "GetFileType");
|
||||||
return __winerr();
|
return __winerr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -42,7 +41,6 @@ int32_t sys_fstat(int32_t fd, struct stat *st) {
|
||||||
__stat2cosmo(st, &ms);
|
__stat2cosmo(st, &ms);
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("sys_fstat(%d) failed w/ %m", fd);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -29,15 +30,19 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int fstat(int fd, struct stat *st) {
|
int fstat(int fd, struct stat *st) {
|
||||||
|
int rc;
|
||||||
if (__isfdkind(fd, kFdZip)) {
|
if (__isfdkind(fd, kFdZip)) {
|
||||||
return weaken(__zipos_fstat)(
|
rc = weaken(__zipos_fstat)(
|
||||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);
|
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);
|
||||||
} else if (!IsWindows() && !IsMetal()) {
|
} else if (!IsWindows() && !IsMetal()) {
|
||||||
return sys_fstat(fd, st);
|
rc = sys_fstat(fd, st);
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
return sys_fstat_metal(fd, st);
|
rc = sys_fstat_metal(fd, st);
|
||||||
|
} else if (!__isfdkind(fd, kFdFile)) {
|
||||||
|
rc = ebadf();
|
||||||
} else {
|
} else {
|
||||||
if (!__isfdkind(fd, kFdFile)) return ebadf();
|
rc = sys_fstat_nt(g_fds.p[fd].handle, st);
|
||||||
return sys_fstat_nt(g_fds.p[fd].handle, st);
|
|
||||||
}
|
}
|
||||||
|
STRACE("fstat(%d, [%s]) → %d% m", fd, __strace_stat(rc, st), rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -38,15 +39,28 @@
|
||||||
* @return 0 on success, or -1 w/ errno
|
* @return 0 on success, or -1 w/ errno
|
||||||
* @see S_ISDIR(st.st_mode), S_ISREG()
|
* @see S_ISDIR(st.st_mode), S_ISREG()
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
int fstatat(int dirfd, const char *path, struct stat *st, int flags) {
|
int fstatat(int dirfd, const char *path, struct stat *st, int flags) {
|
||||||
|
/* execve() depends on this */
|
||||||
|
int rc;
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
if (__isfdkind(dirfd, kFdZip)) return einval(); /* TODO(jart): implement me */
|
if (__isfdkind(dirfd, kFdZip)) {
|
||||||
if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
STRACE("zipos dirfd not supported yet");
|
||||||
return weaken(__zipos_stat)(&zipname, st);
|
rc = einval();
|
||||||
|
} else if (weaken(__zipos_stat) &&
|
||||||
|
weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||||
|
if (!__vforked) {
|
||||||
|
rc = weaken(__zipos_stat)(&zipname, st);
|
||||||
|
} else {
|
||||||
|
rc = enotsup();
|
||||||
|
}
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
return sys_fstatat(dirfd, path, st, flags);
|
rc = sys_fstatat(dirfd, path, st, flags);
|
||||||
} else {
|
} else {
|
||||||
return sys_fstatat_nt(dirfd, path, st, flags);
|
rc = sys_fstatat_nt(dirfd, path, st, flags);
|
||||||
}
|
}
|
||||||
|
STRACE("fstatat(%d, %#s, [%s], %#b) → %d% m", dirfd, path,
|
||||||
|
__strace_stat(rc, st), flags, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -28,9 +29,12 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int fsync(int fd) {
|
int fsync(int fd) {
|
||||||
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_fsync(fd);
|
rc = sys_fsync(fd);
|
||||||
} else {
|
} else {
|
||||||
return sys_fdatasync_nt(fd);
|
rc = sys_fdatasync_nt(fd);
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%d) → %d% m", "fsync", fd, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
@ -32,11 +33,15 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int ftruncate(int fd, int64_t length) {
|
int ftruncate(int fd, int64_t length) {
|
||||||
if (fd < 0) return einval();
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (fd < 0) {
|
||||||
return sys_ftruncate(fd, length, length);
|
rc = einval();
|
||||||
|
} else if (!IsWindows()) {
|
||||||
|
rc = sys_ftruncate(fd, length, length);
|
||||||
} else {
|
} else {
|
||||||
if (fd >= g_fds.n) return ebadf();
|
if (fd >= g_fds.n) rc = ebadf();
|
||||||
return sys_ftruncate_nt(g_fds.p[fd].handle, length);
|
rc = sys_ftruncate_nt(g_fds.p[fd].handle, length);
|
||||||
}
|
}
|
||||||
|
STRACE("ftruncate(%d, %'ld) → %d% m", fd, length, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,10 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
|
|
||||||
.init.start 302,_init_g_fds
|
.init.start 305,_init_g_fds
|
||||||
push %rdi
|
push %rdi
|
||||||
push %rsi
|
push %rsi
|
||||||
call InitializeFileDescriptors
|
call InitializeFileDescriptors
|
||||||
pop %rsi
|
pop %rsi
|
||||||
pop %rdi
|
pop %rdi
|
||||||
.init.end 302,_init_g_fds
|
.init.end 305,_init_g_fds
|
||||||
|
|
|
@ -16,11 +16,13 @@
|
||||||
│ 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/assert.h"
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/log/backtrace.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -43,19 +45,20 @@ char *getcwd(char *buf, size_t size) {
|
||||||
if (buf) {
|
if (buf) {
|
||||||
p = buf;
|
p = buf;
|
||||||
if (!size) {
|
if (!size) {
|
||||||
SYSDEBUG("getcwd(%p, %x) EINVAL", buf, size);
|
|
||||||
einval();
|
einval();
|
||||||
|
STRACE("getcwd(%p, %'zu) %m", buf, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (weaken(malloc)) {
|
} else if (weaken(malloc)) {
|
||||||
|
assert(!__vforked);
|
||||||
if (!size) size = PATH_MAX + 1;
|
if (!size) size = PATH_MAX + 1;
|
||||||
if (!(p = weaken(malloc)(size))) {
|
if (!(p = weaken(malloc)(size))) {
|
||||||
SYSDEBUG("getcwd(%p, %x) ENOMEM", buf, size);
|
STRACE("getcwd(%p, %'zu) %m", buf, size);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("getcwd() EINVAL needs buf≠0 or STATIC_YOINK(\"malloc\")");
|
|
||||||
einval();
|
einval();
|
||||||
|
STRACE("getcwd() needs buf≠0 or STATIC_YOINK(\"malloc\")");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
@ -85,6 +88,6 @@ char *getcwd(char *buf, size_t size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SYSDEBUG("getcwd(%p, %x) -> %s", buf, size, r);
|
STRACE("getcwd(%p, %'zu) → %#s", buf, size, r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -29,13 +30,22 @@
|
||||||
* @return 0 on success or -1 w/ errno
|
* @return 0 on success or -1 w/ errno
|
||||||
*/
|
*/
|
||||||
int getitimer(int which, struct itimerval *curvalue) {
|
int getitimer(int which, struct itimerval *curvalue) {
|
||||||
|
int rc;
|
||||||
if (IsAsan() && !__asan_is_valid(curvalue, sizeof(*curvalue))) {
|
if (IsAsan() && !__asan_is_valid(curvalue, sizeof(*curvalue))) {
|
||||||
return efault();
|
rc = efault();
|
||||||
}
|
} else if (!IsWindows()) {
|
||||||
if (!IsWindows()) {
|
rc = sys_getitimer(which, curvalue);
|
||||||
return sys_getitimer(which, curvalue);
|
} else if (!curvalue) {
|
||||||
|
rc = efault();
|
||||||
} else {
|
} else {
|
||||||
if (!curvalue) return efault();
|
rc = sys_setitimer_nt(which, 0, curvalue);
|
||||||
return sys_setitimer_nt(which, 0, curvalue);
|
|
||||||
}
|
}
|
||||||
|
if (curvalue) {
|
||||||
|
STRACE("getitimer(%d, [{{%'ld, %'ld}, {%'ld, %'ld}}]) → %d% m", which,
|
||||||
|
curvalue->it_interval.tv_sec, curvalue->it_interval.tv_usec,
|
||||||
|
curvalue->it_value.tv_sec, curvalue->it_value.tv_usec, rc);
|
||||||
|
} else {
|
||||||
|
STRACE("getitimer(%d, 0) → %d% m", which, rc);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,15 +18,19 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns process group id.
|
* Returns process group id.
|
||||||
*/
|
*/
|
||||||
int getpgid(int pid) {
|
int getpgid(int pid) {
|
||||||
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_getpgid(pid);
|
rc = sys_getpgid(pid);
|
||||||
} else {
|
} else {
|
||||||
return getpid();
|
rc = getpid();
|
||||||
}
|
}
|
||||||
|
STRACE("%s(%d) → %d% m", "getpgid", pid, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -31,7 +32,16 @@
|
||||||
* @see libc/sysv/consts.sh
|
* @see libc/sysv/consts.sh
|
||||||
*/
|
*/
|
||||||
int getrlimit(int resource, struct rlimit *rlim) {
|
int getrlimit(int resource, struct rlimit *rlim) {
|
||||||
if (resource == 127) return einval();
|
int rc;
|
||||||
if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) return efault();
|
char buf[64];
|
||||||
return sys_getrlimit(resource, rlim);
|
if (resource == 127) {
|
||||||
|
rc = einval();
|
||||||
|
} else if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) {
|
||||||
|
rc = efault();
|
||||||
|
} else {
|
||||||
|
rc = sys_getrlimit(resource, rlim);
|
||||||
|
}
|
||||||
|
STRACE("getrlimit(%s, [%s]) → %d% m", __strace_rlimit_name(resource),
|
||||||
|
__strace_rlimit(buf, sizeof(buf), rc, rlim), rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,14 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates session and sets the process group id.
|
* Creates session and sets the process group id.
|
||||||
*/
|
*/
|
||||||
uint32_t getsid(int pid) {
|
uint32_t getsid(int pid) {
|
||||||
return sys_getsid(pid);
|
int rc;
|
||||||
|
rc = sys_getsid(pid);
|
||||||
|
STRACE("%s(%d) → %d% m", "getsid", pid, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/accounting.h"
|
#include "libc/nt/accounting.h"
|
||||||
|
@ -51,11 +52,14 @@ static textwindows dontinline uint32_t GetUserNameHash(void) {
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
uint32_t getuid(void) {
|
uint32_t getuid(void) {
|
||||||
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_getuid();
|
rc = sys_getuid();
|
||||||
} else {
|
} else {
|
||||||
return GetUserNameHash();
|
rc = GetUserNameHash();
|
||||||
}
|
}
|
||||||
|
STRACE("%s() → %d% m", "getuid", rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,9 +72,12 @@ uint32_t getuid(void) {
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
uint32_t getgid(void) {
|
uint32_t getgid(void) {
|
||||||
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_getgid();
|
rc = sys_getgid();
|
||||||
} else {
|
} else {
|
||||||
return GetUserNameHash();
|
rc = GetUserNameHash();
|
||||||
}
|
}
|
||||||
|
STRACE("%s() → %d% m", "getgid", rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ioctl.h"
|
#include "libc/calls/ioctl.h"
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ioctl.h"
|
#include "libc/calls/ioctl.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/metatermios.internal.h"
|
#include "libc/calls/struct/metatermios.internal.h"
|
||||||
#include "libc/calls/termios.internal.h"
|
#include "libc/calls/termios.internal.h"
|
||||||
#include "libc/calls/ttydefaults.h"
|
#include "libc/calls/ttydefaults.h"
|
||||||
|
@ -65,23 +66,27 @@ static int ioctl_tcgets_sysv(int fd, struct termios *tio) {
|
||||||
* @see ioctl(fd, TIOCGETA, tio) dispatches here
|
* @see ioctl(fd, TIOCGETA, tio) dispatches here
|
||||||
*/
|
*/
|
||||||
int ioctl_tcgets(int fd, ...) {
|
int ioctl_tcgets(int fd, ...) {
|
||||||
|
int rc;
|
||||||
va_list va;
|
va_list va;
|
||||||
struct termios *tio;
|
struct termios *tio;
|
||||||
va_start(va, fd);
|
va_start(va, fd);
|
||||||
tio = va_arg(va, struct termios *);
|
tio = va_arg(va, struct termios *);
|
||||||
va_end(va);
|
va_end(va);
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
if (!tio) return efault();
|
if (!tio) {
|
||||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
rc = efault();
|
||||||
return enotty();
|
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||||
|
rc = enotty();
|
||||||
} else if (IsMetal()) {
|
} else if (IsMetal()) {
|
||||||
return ioctl_tcgets_metal(fd, tio);
|
rc = ioctl_tcgets_metal(fd, tio);
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
return ioctl_tcgets_sysv(fd, tio);
|
rc = ioctl_tcgets_sysv(fd, tio);
|
||||||
} else {
|
} else {
|
||||||
return ioctl_tcgets_nt(fd, tio);
|
rc = ioctl_tcgets_nt(fd, tio);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return einval();
|
rc = einval();
|
||||||
}
|
}
|
||||||
|
STRACE("ioctl_tcgets(%d, %p) → %d% m", fd, tio, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ioctl.h"
|
#include "libc/calls/ioctl.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/metatermios.internal.h"
|
#include "libc/calls/struct/metatermios.internal.h"
|
||||||
#include "libc/calls/termios.internal.h"
|
#include "libc/calls/termios.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -86,5 +87,6 @@ int ioctl_tcsets(int fd, uint64_t request, ...) {
|
||||||
if (rc != -1) {
|
if (rc != -1) {
|
||||||
__nomultics = !(tio->c_oflag & OPOST);
|
__nomultics = !(tio->c_oflag & OPOST);
|
||||||
}
|
}
|
||||||
|
STRACE("ioctl_tcsets(%d, %p, %p) → %d% m", fd, request, tio, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/metastat.internal.h"
|
#include "libc/calls/struct/metastat.internal.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -68,8 +68,7 @@ bool isdirectory(const char *path) {
|
||||||
} else {
|
} else {
|
||||||
res = isdirectory_nt(path);
|
res = isdirectory_nt(path);
|
||||||
}
|
}
|
||||||
SYSDEBUG("isdirectory(%s) -> %s %s", path, res ? "true" : "false",
|
STRACE("isdirectory(%#s) → %hhhd% m", path, res);
|
||||||
res ? "" : strerror(errno));
|
|
||||||
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
|
||||||
errno = e;
|
errno = e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/struct/stat.h"
|
#include "libc/calls/struct/stat.h"
|
||||||
|
#include "libc/sysv/consts/at.h"
|
||||||
#include "libc/sysv/consts/s.h"
|
#include "libc/sysv/consts/s.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,9 +26,11 @@
|
||||||
*
|
*
|
||||||
* @see access(exe, X_OK) which is more accurate on NT
|
* @see access(exe, X_OK) which is more accurate on NT
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
bool isexecutable(const char *path) {
|
bool isexecutable(const char *path) {
|
||||||
|
/* execve() depends on this */
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(path, &st)) return 0;
|
if (fstatat(AT_FDCWD, path, &st, 0)) return 0;
|
||||||
return st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH);
|
return !!(st.st_mode & 0111);
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
* @see isdirectory(), ischardev(), issymlink()
|
* @see isdirectory(), ischardev(), issymlink()
|
||||||
*/
|
*/
|
||||||
bool isregularfile(const char *path) {
|
bool isregularfile(const char *path) {
|
||||||
int rc, e;
|
int e;
|
||||||
union metastat st;
|
union metastat st;
|
||||||
struct ZiposUri zipname;
|
struct ZiposUri zipname;
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -36,18 +37,20 @@
|
||||||
*/
|
*/
|
||||||
int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
|
int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
|
||||||
int flags) {
|
int flags) {
|
||||||
|
int rc;
|
||||||
if (IsAsan() &&
|
if (IsAsan() &&
|
||||||
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
|
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
|
||||||
return efault();
|
rc = efault();
|
||||||
}
|
} else if (weaken(__zipos_notat) &&
|
||||||
if (weaken(__zipos_notat) &&
|
((rc = __zipos_notat(olddirfd, oldpath)) == -1 ||
|
||||||
(weaken(__zipos_notat)(olddirfd, oldpath) == -1 ||
|
(rc = __zipos_notat(newdirfd, newpath)) == -1)) {
|
||||||
weaken(__zipos_notat)(newdirfd, newpath) == -1)) {
|
STRACE("zipos fchownat not supported yet");
|
||||||
return -1; /* TODO(jart): implement me */
|
} else if (!IsWindows()) {
|
||||||
}
|
rc = sys_linkat(olddirfd, oldpath, newdirfd, newpath, flags);
|
||||||
if (!IsWindows()) {
|
|
||||||
return sys_linkat(olddirfd, oldpath, newdirfd, newpath, flags);
|
|
||||||
} else {
|
} else {
|
||||||
return sys_linkat_nt(olddirfd, oldpath, newdirfd, newpath);
|
rc = sys_linkat_nt(olddirfd, oldpath, newdirfd, newpath);
|
||||||
}
|
}
|
||||||
|
STRACE("linkat(%d, %#s, %d, %#s, %#b) → %d% m", olddirfd, oldpath, newdirfd,
|
||||||
|
newpath, flags, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/log/backtrace.internal.h"
|
#include "libc/log/backtrace.internal.h"
|
||||||
#include "libc/zipos/zipos.internal.h"
|
#include "libc/zipos/zipos.internal.h"
|
||||||
|
@ -33,14 +34,17 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int64_t lseek(int fd, int64_t offset, unsigned whence) {
|
int64_t lseek(int fd, int64_t offset, unsigned whence) {
|
||||||
|
int64_t rc;
|
||||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||||
return weaken(__zipos_lseek)(
|
rc = weaken(__zipos_lseek)(
|
||||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, offset, whence);
|
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, offset, whence);
|
||||||
} else if (!IsWindows() && !IsOpenbsd() && !IsNetbsd()) {
|
} else if (!IsWindows() && !IsOpenbsd() && !IsNetbsd()) {
|
||||||
return sys_lseek(fd, offset, whence, 0);
|
rc = sys_lseek(fd, offset, whence, 0);
|
||||||
} else if (IsOpenbsd() || IsNetbsd()) {
|
} else if (IsOpenbsd() || IsNetbsd()) {
|
||||||
return sys_lseek(fd, offset, offset, whence);
|
rc = sys_lseek(fd, offset, offset, whence);
|
||||||
} else {
|
} else {
|
||||||
return sys_lseek_nt(fd, offset, whence);
|
rc = sys_lseek_nt(fd, offset, whence);
|
||||||
}
|
}
|
||||||
|
STRACE("lseek(%d, %'ld, %d) → %'ld% m", fd, offset, whence, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,7 @@ forceinline typeof(OfferVirtualMemory) *GetOfferVirtualMemory(void) {
|
||||||
textwindows int sys_madvise_nt(void *addr, size_t length, int advice) {
|
textwindows int sys_madvise_nt(void *addr, size_t length, int advice) {
|
||||||
uint32_t rangecount;
|
uint32_t rangecount;
|
||||||
struct NtMemoryRangeEntry ranges[1];
|
struct NtMemoryRangeEntry ranges[1];
|
||||||
if ((advice & (int)MADV_WILLNEED) == (int)MADV_WILLNEED ||
|
if (advice == MADV_WILLNEED || advice == MADV_SEQUENTIAL) {
|
||||||
(advice & (int)MADV_SEQUENTIAL) == (int)MADV_SEQUENTIAL) {
|
|
||||||
typeof(PrefetchVirtualMemory) *fn = GetPrefetchVirtualMemory();
|
typeof(PrefetchVirtualMemory) *fn = GetPrefetchVirtualMemory();
|
||||||
if (fn) {
|
if (fn) {
|
||||||
ranges[0].VirtualAddress = addr;
|
ranges[0].VirtualAddress = addr;
|
||||||
|
@ -65,7 +64,7 @@ textwindows int sys_madvise_nt(void *addr, size_t length, int advice) {
|
||||||
} else {
|
} else {
|
||||||
return enosys();
|
return enosys();
|
||||||
}
|
}
|
||||||
} else if ((advice & (int)MADV_FREE) == (int)MADV_FREE) {
|
} else if (advice == MADV_FREE) {
|
||||||
typeof(OfferVirtualMemory) *fn = GetOfferVirtualMemory();
|
typeof(OfferVirtualMemory) *fn = GetOfferVirtualMemory();
|
||||||
if (fn) {
|
if (fn) {
|
||||||
if (fn(addr, length, kNtVmOfferPriorityNormal)) {
|
if (fn(addr, length, kNtVmOfferPriorityNormal)) {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -31,10 +32,18 @@
|
||||||
* @see fadvise()
|
* @see fadvise()
|
||||||
*/
|
*/
|
||||||
int madvise(void *addr, size_t length, int advice) {
|
int madvise(void *addr, size_t length, int advice) {
|
||||||
if (IsAsan() && !__asan_is_valid(addr, length)) return efault();
|
int rc;
|
||||||
if (!IsWindows()) {
|
if (advice != 127 /* see consts.sh */) {
|
||||||
return sys_madvise(addr, length, advice);
|
if (IsAsan() && !__asan_is_valid(addr, length)) {
|
||||||
|
rc = efault();
|
||||||
|
} else if (!IsWindows()) {
|
||||||
|
rc = sys_madvise(addr, length, advice);
|
||||||
|
} else {
|
||||||
|
rc = sys_madvise_nt(addr, length, advice);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return sys_madvise_nt(addr, length, advice);
|
rc = einval();
|
||||||
}
|
}
|
||||||
|
STRACE("madvise(%p, %'zu, %d) → %d% m", addr, length, advice, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/sysv/consts/at.h"
|
||||||
|
@ -38,13 +39,16 @@
|
||||||
* @see makedirs()
|
* @see makedirs()
|
||||||
*/
|
*/
|
||||||
int mkdirat(int dirfd, const char *path, unsigned mode) {
|
int mkdirat(int dirfd, const char *path, unsigned mode) {
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
int rc;
|
||||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||||
return -1; /* TODO(jart): implement me */
|
rc = efault();
|
||||||
}
|
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
|
||||||
if (!IsWindows()) {
|
STRACE("zipos mkdirat not supported yet");
|
||||||
return sys_mkdirat(dirfd, path, mode);
|
} else if (!IsWindows()) {
|
||||||
|
rc = sys_mkdirat(dirfd, path, mode);
|
||||||
} else {
|
} else {
|
||||||
return sys_mkdirat_nt(dirfd, path, mode);
|
rc = sys_mkdirat_nt(dirfd, path, mode);
|
||||||
}
|
}
|
||||||
|
STRACE("mkdirat(%d, %#s, %#o) → %d% m", dirfd, path, mode, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/consts/s.h"
|
#include "libc/sysv/consts/s.h"
|
||||||
|
@ -38,14 +39,17 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int mknod(const char *path, uint32_t mode, uint64_t dev) {
|
int mknod(const char *path, uint32_t mode, uint64_t dev) {
|
||||||
|
int rc;
|
||||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||||
if (mode & S_IFREG) return creat(path, mode & ~S_IFREG);
|
if (mode & S_IFREG) return creat(path, mode & ~S_IFREG);
|
||||||
if (mode & S_IFDIR) return mkdir(path, mode & ~S_IFDIR);
|
if (mode & S_IFDIR) return mkdir(path, mode & ~S_IFDIR);
|
||||||
if (mode & S_IFIFO) return mkfifo(path, mode & ~S_IFIFO);
|
if (mode & S_IFIFO) return mkfifo(path, mode & ~S_IFIFO);
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
/* TODO(jart): Whys there code out there w/ S_xxx passed via dev? */
|
/* TODO(jart): Whys there code out there w/ S_xxx passed via dev? */
|
||||||
return sys_mknod(path, mode, dev);
|
rc = sys_mknod(path, mode, dev);
|
||||||
} else {
|
} else {
|
||||||
return enosys();
|
rc = enosys();
|
||||||
}
|
}
|
||||||
|
STRACE("mknod(%#s, %#o, %#lx) → %d% m", path, mode, dev, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ntmagicpaths.internal.h"
|
#include "libc/calls/ntmagicpaths.internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/nt/systeminfo.h"
|
#include "libc/nt/systeminfo.h"
|
||||||
#include "libc/str/oldutf16.internal.h"
|
#include "libc/str/oldutf16.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -76,8 +76,8 @@ textwindows int __mkntpath2(const char *path,
|
||||||
* 4. Reserve ≥10 for CreateNamedPipe "\\.\pipe\" prefix requirement
|
* 4. Reserve ≥10 for CreateNamedPipe "\\.\pipe\" prefix requirement
|
||||||
* 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
* 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
||||||
*/
|
*/
|
||||||
char *q;
|
|
||||||
char16_t *p;
|
char16_t *p;
|
||||||
|
const char *q;
|
||||||
size_t i, n, m, z;
|
size_t i, n, m, z;
|
||||||
if (!path) return efault();
|
if (!path) return efault();
|
||||||
path = FixNtMagicPath(path, flags);
|
path = FixNtMagicPath(path, flags);
|
||||||
|
@ -96,7 +96,7 @@ textwindows int __mkntpath2(const char *path,
|
||||||
}
|
}
|
||||||
n = tprecode8to16(p, z, q).ax;
|
n = tprecode8to16(p, z, q).ax;
|
||||||
if (n == z - 1) {
|
if (n == z - 1) {
|
||||||
SYSDEBUG("path too long for windows: %s", path);
|
STRACE("path too long for windows: %#s", path);
|
||||||
return enametoolong();
|
return enametoolong();
|
||||||
}
|
}
|
||||||
for (i = 0; i < n; ++i) {
|
for (i = 0; i < n; ++i) {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/files.h"
|
#include "libc/nt/files.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -35,7 +35,7 @@ int __mkntpathat(int dirfd, const char *path, int flags,
|
||||||
kNtFileNameNormalized | kNtVolumeNameDos);
|
kNtFileNameNormalized | kNtVolumeNameDos);
|
||||||
if (!dirlen) return __winerr();
|
if (!dirlen) return __winerr();
|
||||||
if (dirlen + 1 + filelen + 1 > ARRAYLEN(dir)) {
|
if (dirlen + 1 + filelen + 1 > ARRAYLEN(dir)) {
|
||||||
SYSDEBUG("path too long: %.*hs\\%.*hs", dirlen, dir, filelen, file);
|
STRACE("path too long: %#.*hs\\%#.*hs", dirlen, dir, filelen, file);
|
||||||
return enametoolong();
|
return enametoolong();
|
||||||
}
|
}
|
||||||
dir[dirlen] = u'\\';
|
dir[dirlen] = u'\\';
|
||||||
|
|
|
@ -18,10 +18,19 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
#include "libc/sysv/consts/mremap.h"
|
#include "libc/sysv/consts/mremap.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Relocates memory.
|
||||||
|
*
|
||||||
|
* This function lets you move to to different addresses witohut copying
|
||||||
|
* it. This system call is currently supported on Linux and NetBSD. Your
|
||||||
|
* C library runtime won't have any awareness of this memory, so certain
|
||||||
|
* features like ASAN memory safety and kprintf() won't work as well.
|
||||||
|
*/
|
||||||
privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
|
privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
|
||||||
bool cf;
|
bool cf;
|
||||||
uintptr_t rax, rdi, rsi, rdx;
|
uintptr_t rax, rdi, rsi, rdx;
|
||||||
|
@ -43,7 +52,7 @@ privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
|
||||||
asm(CFLAG_ASM("syscall")
|
asm(CFLAG_ASM("syscall")
|
||||||
: CFLAG_CONSTRAINT(cf), "+a"(rax)
|
: CFLAG_CONSTRAINT(cf), "+a"(rax)
|
||||||
: "D"(p), "S"(n), "d"(q), "r"(r10), "r"(r8)
|
: "D"(p), "S"(n), "d"(q), "r"(r10), "r"(r8)
|
||||||
: "rcx", "r11", "memory", "cc");
|
: "rcx", "r9", "r11", "memory", "cc");
|
||||||
if (cf) errno = rax, rax = -1;
|
if (cf) errno = rax, rax = -1;
|
||||||
} else {
|
} else {
|
||||||
rax = einval();
|
rax = einval();
|
||||||
|
@ -51,5 +60,6 @@ privileged void *sys_mremap(void *p, size_t n, size_t m, int f, void *q) {
|
||||||
} else {
|
} else {
|
||||||
rax = enosys();
|
rax = enosys();
|
||||||
}
|
}
|
||||||
|
STRACE("sys_mremap(%p, %'zu, %'zu, %#b, %p) → %p% m", p, n, m, f, q, rax);
|
||||||
return (void *)rax;
|
return (void *)rax;
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/runtime/directmap.internal.h"
|
#include "libc/runtime/directmap.internal.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ int sys_munmap(void *p, size_t n) {
|
||||||
} else {
|
} else {
|
||||||
rc = sys_munmap_metal(p, n);
|
rc = sys_munmap_metal(p, n);
|
||||||
}
|
}
|
||||||
SYSDEBUG("sys_munmap(0x%p%s, 0x%x) -> %d", p,
|
STRACE("sys_munmap(%p%s, %'zu) → %d", p, DescribeFrame((intptr_t)p >> 16), n,
|
||||||
DescribeFrame((intptr_t)p >> 16), n, (long)rc);
|
rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
|
@ -19,7 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nt/enum/accessmask.h"
|
#include "libc/nt/enum/accessmask.h"
|
||||||
#include "libc/nt/enum/securityimpersonationlevel.h"
|
#include "libc/nt/enum/securityimpersonationlevel.h"
|
||||||
|
@ -87,24 +87,24 @@ TryAgain:
|
||||||
if (result || flags == F_OK) {
|
if (result || flags == F_OK) {
|
||||||
rc = 0;
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("ntaccesscheck finale failed %d %d", result, flags);
|
STRACE("ntaccesscheck finale failed %d %d", result, flags);
|
||||||
rc = eacces();
|
rc = eacces();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = __winerr();
|
rc = __winerr();
|
||||||
SYSDEBUG("AccessCheck failed: %m");
|
STRACE("%s failed: %m", "AccessCheck");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = __winerr();
|
rc = __winerr();
|
||||||
SYSDEBUG("DuplicateToken failed: %m");
|
STRACE("%s failed: %m", "DuplicateToken");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rc = __winerr();
|
rc = __winerr();
|
||||||
SYSDEBUG("OpenProcessToken failed: %m");
|
STRACE("%s failed: %m", "OpenProcessToken");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
e = GetLastError();
|
e = GetLastError();
|
||||||
SYSDEBUG("GetFileSecurity failed: %d %d", e, secsize);
|
STRACE("GetFileSecurity failed: %d %u", e, secsize);
|
||||||
if (!IsTiny() && e == kNtErrorInsufficientBuffer) {
|
if (!IsTiny() && e == kNtErrorInsufficientBuffer) {
|
||||||
if (!freeme && weaken(malloc) && (freeme = weaken(malloc)(secsize))) {
|
if (!freeme && weaken(malloc) && (freeme = weaken(malloc)(secsize))) {
|
||||||
s = freeme;
|
s = freeme;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "libc/bits/pushpop.h"
|
#include "libc/bits/pushpop.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ntspawn.h"
|
#include "libc/calls/ntspawn.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/enum/filemapflags.h"
|
#include "libc/nt/enum/filemapflags.h"
|
||||||
#include "libc/nt/enum/pageflags.h"
|
#include "libc/nt/enum/pageflags.h"
|
||||||
|
@ -95,7 +95,7 @@ textwindows int ntspawn(
|
||||||
} else {
|
} else {
|
||||||
__winerr();
|
__winerr();
|
||||||
}
|
}
|
||||||
SYSDEBUG("CreateProcess(`%hs`, `%hs`) -> %d", prog16, block->cmdline, rc);
|
STRACE("CreateProcess(%#hs, %#hs) → %d% m", prog16, block->cmdline, rc);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
__winerr();
|
__winerr();
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/log/log.h"
|
#include "libc/log/log.h"
|
||||||
|
@ -73,8 +73,7 @@ int openat(int dirfd, const char *file, int flags, ...) {
|
||||||
} else {
|
} else {
|
||||||
rc = efault();
|
rc = efault();
|
||||||
}
|
}
|
||||||
SYSDEBUG("openat(%d, %s, %d, %d) -> %d %s", (long)dirfd, file, flags,
|
STRACE("openat(%d, %#s, %#x, %#o) → %d% m", dirfd, file, flags,
|
||||||
(flags & (O_CREAT | O_TMPFILE)) ? mode : 0, (long)rc,
|
(flags & (O_CREAT | O_TMPFILE)) ? mode : 0, rc);
|
||||||
rc == -1 ? strerror(errno) : "");
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/sysv/consts/sig.h"
|
#include "libc/sysv/consts/sig.h"
|
||||||
|
@ -36,6 +37,7 @@ int pause(void) {
|
||||||
int rc, olderr;
|
int rc, olderr;
|
||||||
sigset_t oldmask;
|
sigset_t oldmask;
|
||||||
olderr = errno;
|
olderr = errno;
|
||||||
|
STRACE("pause()");
|
||||||
if ((rc = sys_pause()) == -1 && errno == ENOSYS) {
|
if ((rc = sys_pause()) == -1 && errno == ENOSYS) {
|
||||||
errno = olderr;
|
errno = olderr;
|
||||||
if (sigprocmask(SIG_BLOCK, NULL, &oldmask) == -1) return -1;
|
if (sigprocmask(SIG_BLOCK, NULL, &oldmask) == -1) return -1;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "libc/bits/bits.h"
|
#include "libc/bits/bits.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/log/libfatal.internal.h"
|
#include "libc/log/libfatal.internal.h"
|
||||||
|
@ -125,7 +125,7 @@ textstartup void program_executable_name_init(int argc, char **argv,
|
||||||
GetProgramExecutableName(executable, argv[0], auxv);
|
GetProgramExecutableName(executable, argv[0], auxv);
|
||||||
errno = e;
|
errno = e;
|
||||||
__stpcpy(program_executable_name, executable);
|
__stpcpy(program_executable_name, executable);
|
||||||
SYSDEBUG("program_executable_name → %#s", program_executable_name);
|
STRACE("program_executable_name → %#s", program_executable_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *const program_executable_name_init_ctor[] initarray = {
|
const void *const program_executable_name_init_ctor[] initarray = {
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/nexgen32e/bsr.h"
|
#include "libc/nexgen32e/bsr.h"
|
||||||
#include "libc/nt/createfile.h"
|
#include "libc/nt/createfile.h"
|
||||||
|
@ -39,7 +39,7 @@
|
||||||
static textwindows ssize_t sys_readlinkat_nt_error(void) {
|
static textwindows ssize_t sys_readlinkat_nt_error(void) {
|
||||||
uint32_t e;
|
uint32_t e;
|
||||||
e = GetLastError();
|
e = GetLastError();
|
||||||
SYSDEBUG("sys_readlinkat_nt() error %d", e);
|
STRACE("sys_readlinkat_nt() error %d", e);
|
||||||
switch (e) {
|
switch (e) {
|
||||||
case kNtErrorNotAReparsePoint:
|
case kNtErrorNotAReparsePoint:
|
||||||
return einval();
|
return einval();
|
||||||
|
@ -56,11 +56,11 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
||||||
uint64_t w;
|
uint64_t w;
|
||||||
wint_t x, y;
|
wint_t x, y;
|
||||||
void *freeme;
|
void *freeme;
|
||||||
uint32_t e, i, j, n, mem;
|
uint32_t i, j, n, mem;
|
||||||
char16_t path16[PATH_MAX], *p;
|
char16_t path16[PATH_MAX], *p;
|
||||||
struct NtReparseDataBuffer *rdb;
|
struct NtReparseDataBuffer *rdb;
|
||||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) {
|
if (__mkntpathat(dirfd, path, 0, path16) == -1) {
|
||||||
SYSDEBUG("sys_readlinkat_nt() failed b/c __mkntpathat() failed");
|
STRACE("sys_readlinkat_nt() failed b/c __mkntpathat() failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (weaken(malloc)) {
|
if (weaken(malloc)) {
|
||||||
|
@ -72,7 +72,7 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
||||||
rdb = (struct NtReparseDataBuffer *)buf;
|
rdb = (struct NtReparseDataBuffer *)buf;
|
||||||
freeme = 0;
|
freeme = 0;
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("sys_readlinkat_nt() needs bigger buffer malloc() to be yoinked");
|
STRACE("sys_readlinkat_nt() needs bigger buffer malloc() to be yoinked");
|
||||||
return enomem();
|
return enomem();
|
||||||
}
|
}
|
||||||
if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting,
|
if ((h = CreateFile(path16, 0, 0, 0, kNtOpenExisting,
|
||||||
|
@ -113,20 +113,20 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
||||||
if (freeme || (intptr_t)(buf + j) <= (intptr_t)(p + i)) {
|
if (freeme || (intptr_t)(buf + j) <= (intptr_t)(p + i)) {
|
||||||
rc = j;
|
rc = j;
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("sys_readlinkat_nt() too many astral codepoints");
|
STRACE("sys_readlinkat_nt() too many astral codepoints");
|
||||||
rc = enametoolong();
|
rc = enametoolong();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("sys_readlinkat_nt() should have kNtIoReparseTagSymlink");
|
STRACE("sys_readlinkat_nt() should have kNtIoReparseTagSymlink");
|
||||||
rc = einval();
|
rc = einval();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("DeviceIoControl(kNtFsctlGetReparsePoint) failed");
|
STRACE("%s failed %m", "DeviceIoControl(kNtFsctlGetReparsePoint)");
|
||||||
rc = sys_readlinkat_nt_error();
|
rc = sys_readlinkat_nt_error();
|
||||||
}
|
}
|
||||||
CloseHandle(h);
|
CloseHandle(h);
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("CreateFile(kNtFileFlagOpenReparsePoint) failed");
|
STRACE("%s failed %m", "CreateFile(kNtFileFlagOpenReparsePoint)");
|
||||||
rc = sys_readlinkat_nt_error();
|
rc = sys_readlinkat_nt_error();
|
||||||
}
|
}
|
||||||
if (freeme && weaken(free)) {
|
if (freeme && weaken(free)) {
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -50,18 +50,17 @@
|
||||||
*/
|
*/
|
||||||
ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
|
ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
|
||||||
ssize_t bytes;
|
ssize_t bytes;
|
||||||
struct ZiposUri zipname;
|
|
||||||
if ((IsAsan() && !__asan_is_valid(buf, bufsiz)) || (bufsiz && !buf)) {
|
if ((IsAsan() && !__asan_is_valid(buf, bufsiz)) || (bufsiz && !buf)) {
|
||||||
bytes = efault();
|
bytes = efault();
|
||||||
} else if (weaken(__zipos_notat) && __zipos_notat(dirfd, path) == -1) {
|
} else if (weaken(__zipos_notat) &&
|
||||||
SYSDEBUG("TOOD: zipos support for readlinkat");
|
(bytes = __zipos_notat(dirfd, path)) == -1) {
|
||||||
bytes = enosys(); /* TODO(jart): code me */
|
STRACE("TOOD: zipos support for readlinkat");
|
||||||
} else if (!IsWindows()) {
|
} else if (!IsWindows()) {
|
||||||
bytes = sys_readlinkat(dirfd, path, buf, bufsiz);
|
bytes = sys_readlinkat(dirfd, path, buf, bufsiz);
|
||||||
} else {
|
} else {
|
||||||
bytes = sys_readlinkat_nt(dirfd, path, buf, bufsiz);
|
bytes = sys_readlinkat_nt(dirfd, path, buf, bufsiz);
|
||||||
}
|
}
|
||||||
SYSDEBUG("readlinkat(%d, %s, 0x%p, 0x%x) -> %d %s", (long)dirfd, path, buf,
|
STRACE("readlinkat(%d, %#s, [%#.*s]) → %d% m", dirfd, path, MAX(0, bytes),
|
||||||
bufsiz, bytes, bytes != -1 ? "" : strerror(errno));
|
buf, bytes);
|
||||||
return bytes;
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
void __releasefd(int fd) {
|
void __releasefd(int fd) {
|
||||||
int x;
|
int x;
|
||||||
if (!__vforked && 0 <= fd && fd < g_fds.n) {
|
if (!__vforked && 0 <= fd && fd < g_fds.n) {
|
||||||
g_fds.p[fd].kind = kFdEmpty;
|
bzero(g_fds.p + fd, sizeof(*g_fds.p));
|
||||||
do {
|
do {
|
||||||
x = g_fds.f;
|
x = g_fds.f;
|
||||||
if (fd >= x) break;
|
if (fd >= x) break;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/consts/at.h"
|
#include "libc/sysv/consts/at.h"
|
||||||
|
@ -36,18 +37,20 @@
|
||||||
*/
|
*/
|
||||||
int renameat(int olddirfd, const char *oldpath, int newdirfd,
|
int renameat(int olddirfd, const char *oldpath, int newdirfd,
|
||||||
const char *newpath) {
|
const char *newpath) {
|
||||||
|
int rc;
|
||||||
if (IsAsan() &&
|
if (IsAsan() &&
|
||||||
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
|
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
|
||||||
return efault();
|
rc = efault();
|
||||||
}
|
} else if (weaken(__zipos_notat) &&
|
||||||
if (weaken(__zipos_notat) &&
|
((rc = __zipos_notat(olddirfd, oldpath)) == -1 ||
|
||||||
(weaken(__zipos_notat)(olddirfd, oldpath) == -1 ||
|
(rc = __zipos_notat(newdirfd, newpath)) == -1)) {
|
||||||
weaken(__zipos_notat)(newdirfd, newpath) == -1)) {
|
STRACE("zipos renameat not supported yet");
|
||||||
return -1; /* TODO(jart): implement me */
|
} else if (!IsWindows()) {
|
||||||
}
|
rc = sys_renameat(olddirfd, oldpath, newdirfd, newpath);
|
||||||
if (!IsWindows()) {
|
|
||||||
return sys_renameat(olddirfd, oldpath, newdirfd, newpath);
|
|
||||||
} else {
|
} else {
|
||||||
return sys_renameat_nt(olddirfd, oldpath, newdirfd, newpath);
|
rc = sys_renameat_nt(olddirfd, oldpath, newdirfd, newpath);
|
||||||
}
|
}
|
||||||
|
STRACE("renameat(%d, %#s, %d, %#s) → %d% m", olddirfd, oldpath, newdirfd,
|
||||||
|
newpath, rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,14 +16,15 @@
|
||||||
│ 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/dce.h"
|
|
||||||
#include "libc/calls/internal.h"
|
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/dce.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asks kernel to deschedule thread momentarily.
|
* Asks kernel to deschedule thread momentarily.
|
||||||
*/
|
*/
|
||||||
int sched_yield(void) {
|
int sched_yield(void) {
|
||||||
|
/* TODO(jart): Add get_sched_yield() so we can STRACE() */
|
||||||
if (!IsWindows()) {
|
if (!IsWindows()) {
|
||||||
return sys_sched_yield();
|
return sys_sched_yield();
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
@ -32,7 +33,16 @@
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
int setrlimit(int resource, const struct rlimit *rlim) {
|
int setrlimit(int resource, const struct rlimit *rlim) {
|
||||||
if (resource == 127) return einval();
|
int rc;
|
||||||
if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) return efault();
|
char buf[64];
|
||||||
return sys_setrlimit(resource, rlim);
|
if (resource == 127) {
|
||||||
|
rc = einval();
|
||||||
|
} else if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) {
|
||||||
|
rc = efault();
|
||||||
|
} else {
|
||||||
|
rc = sys_setrlimit(resource, rlim);
|
||||||
|
}
|
||||||
|
STRACE("setrlimit(%s, %s) → %d% m", __strace_rlimit_name(resource),
|
||||||
|
__strace_rlimit(buf, sizeof(buf), 0, rlim), rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sigbits.h"
|
#include "libc/calls/sigbits.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/sigaction-freebsd.internal.h"
|
#include "libc/calls/struct/sigaction-freebsd.internal.h"
|
||||||
#include "libc/calls/struct/sigaction-linux.internal.h"
|
#include "libc/calls/struct/sigaction-linux.internal.h"
|
||||||
#include "libc/calls/struct/sigaction-netbsd.h"
|
#include "libc/calls/struct/sigaction-netbsd.h"
|
||||||
|
@ -129,19 +130,8 @@ static void sigaction_native2cosmo(union metasigaction *sa) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static int __sigaction(int sig, const struct sigaction *act,
|
||||||
* Installs handler for kernel interrupt, e.g.:
|
struct sigaction *oldact) {
|
||||||
*
|
|
||||||
* void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx);
|
|
||||||
* struct sigaction sa = {.sa_sigaction = GotCtrlC,
|
|
||||||
* .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO};
|
|
||||||
* CHECK_NE(-1, sigaction(SIGINT, &sa, NULL));
|
|
||||||
*
|
|
||||||
* @see xsigaction() for a much better api
|
|
||||||
* @asyncsignalsafe
|
|
||||||
* @vforksafe
|
|
||||||
*/
|
|
||||||
int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
|
||||||
_Static_assert((sizeof(struct sigaction) > sizeof(struct sigaction_linux) &&
|
_Static_assert((sizeof(struct sigaction) > sizeof(struct sigaction_linux) &&
|
||||||
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) &&
|
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) &&
|
||||||
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) &&
|
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) &&
|
||||||
|
@ -233,3 +223,25 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
||||||
}
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Installs handler for kernel interrupt, e.g.:
|
||||||
|
*
|
||||||
|
* void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx);
|
||||||
|
* struct sigaction sa = {.sa_sigaction = GotCtrlC,
|
||||||
|
* .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO};
|
||||||
|
* CHECK_NE(-1, sigaction(SIGINT, &sa, NULL));
|
||||||
|
*
|
||||||
|
* @see xsigaction() for a much better api
|
||||||
|
* @asyncsignalsafe
|
||||||
|
* @vforksafe
|
||||||
|
*/
|
||||||
|
int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
||||||
|
int rc;
|
||||||
|
char buf[2][128];
|
||||||
|
rc = __sigaction(sig, act, oldact);
|
||||||
|
STRACE("sigaction(%s, %s, [%s]) → %d% m", strsignal(sig),
|
||||||
|
__strace_sigaction(buf[0], sizeof(buf[0]), 0, act),
|
||||||
|
__strace_sigaction(buf[1], sizeof(buf[1]), rc, oldact), rc);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/metasigaltstack.h"
|
#include "libc/calls/struct/metasigaltstack.h"
|
||||||
#include "libc/calls/struct/sigaltstack.h"
|
#include "libc/calls/struct/sigaltstack.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
@ -70,37 +71,41 @@ static noasan void sigaltstack2linux(struct sigaltstack *linux,
|
||||||
*/
|
*/
|
||||||
noasan int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) {
|
noasan int sigaltstack(const struct sigaltstack *neu, struct sigaltstack *old) {
|
||||||
int rc;
|
int rc;
|
||||||
void *a, *b;
|
void *b;
|
||||||
|
const void *a;
|
||||||
struct sigaltstack_bsd bsd;
|
struct sigaltstack_bsd bsd;
|
||||||
if (IsAsan() && ((old && __asan_check(old, sizeof(*old)).kind) ||
|
if (IsAsan() && ((old && __asan_check(old, sizeof(*old)).kind) ||
|
||||||
(neu && (__asan_check(neu, sizeof(*neu)).kind ||
|
(neu && (__asan_check(neu, sizeof(*neu)).kind ||
|
||||||
__asan_check(neu->ss_sp, neu->ss_size).kind)))) {
|
__asan_check(neu->ss_sp, neu->ss_size).kind)))) {
|
||||||
return efault();
|
rc = efault();
|
||||||
}
|
} else if (IsLinux() || IsBsd()) {
|
||||||
if (IsLinux()) {
|
if (IsLinux()) {
|
||||||
a = neu;
|
a = neu;
|
||||||
b = old;
|
b = old;
|
||||||
} else if (IsBsd()) {
|
|
||||||
if (neu) {
|
|
||||||
sigaltstack2bsd(&bsd, neu);
|
|
||||||
a = &bsd;
|
|
||||||
} else {
|
} else {
|
||||||
a = 0;
|
if (neu) {
|
||||||
|
sigaltstack2bsd(&bsd, neu);
|
||||||
|
a = &bsd;
|
||||||
|
} else {
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
if (old) {
|
||||||
|
b = &bsd;
|
||||||
|
} else {
|
||||||
|
b = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (old) {
|
if ((rc = sys_sigaltstack(a, b)) != -1) {
|
||||||
b = &bsd;
|
if (IsBsd() && old) {
|
||||||
|
sigaltstack2linux(old, &bsd);
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
} else {
|
} else {
|
||||||
b = 0;
|
rc = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return enosys();
|
rc = enosys();
|
||||||
}
|
|
||||||
if ((rc = sys_sigaltstack(a, b)) != -1) {
|
|
||||||
if (IsBsd() && old) {
|
|
||||||
sigaltstack2linux(old, &bsd);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
STRACE("sigaltstack() → %d% m", rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,23 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
|
#include "libc/fmt/itoa.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
#include "libc/sysv/consts/sig.h"
|
||||||
#include "libc/sysv/errfuns.h"
|
#include "libc/sysv/errfuns.h"
|
||||||
|
|
||||||
|
static const char *DescribeHow(char buf[12], int how) {
|
||||||
|
if (how == SIG_BLOCK) return "SIG_BLOCK";
|
||||||
|
if (how == SIG_UNBLOCK) return "SIG_UNBLOCK";
|
||||||
|
if (how == SIG_SETMASK) return "SIG_SETMASK";
|
||||||
|
FormatInt32(buf, how);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes program signal blocking state, e.g.:
|
* Changes program signal blocking state, e.g.:
|
||||||
*
|
*
|
||||||
|
@ -40,25 +51,50 @@
|
||||||
* @vforksafe
|
* @vforksafe
|
||||||
*/
|
*/
|
||||||
int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
|
int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
|
||||||
int32_t x;
|
int x, rc;
|
||||||
if (IsAsan() &&
|
char howbuf[12];
|
||||||
((opt_set && !__asan_is_valid(opt_set, sizeof(*opt_set))) ||
|
char buf[2][41];
|
||||||
(opt_out_oldset &&
|
sigset_t old, *oldp;
|
||||||
!__asan_is_valid(opt_out_oldset, sizeof(*opt_out_oldset))))) {
|
if (!(IsAsan() &&
|
||||||
return efault();
|
((opt_set && !__asan_is_valid(opt_set, sizeof(*opt_set))) ||
|
||||||
}
|
(opt_out_oldset &&
|
||||||
if (!IsWindows() && !IsOpenbsd()) {
|
!__asan_is_valid(opt_out_oldset, sizeof(*opt_out_oldset)))))) {
|
||||||
return sys_sigprocmask(how, opt_set, opt_out_oldset, 8);
|
if (!IsWindows() && !IsOpenbsd()) {
|
||||||
} else if (IsOpenbsd()) {
|
if (opt_out_oldset) {
|
||||||
if (!opt_set) how = 1;
|
bzero(&old, sizeof(old));
|
||||||
if (opt_set) opt_set = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
oldp = &old;
|
||||||
if ((x = sys_sigprocmask(how, opt_set, 0, 0)) != -1) {
|
} else {
|
||||||
if (opt_out_oldset) memcpy(opt_out_oldset, &x, sizeof(x));
|
oldp = 0;
|
||||||
return 0;
|
}
|
||||||
|
if (sys_sigprocmask(how, opt_set, oldp, 8) != -1) {
|
||||||
|
if (opt_out_oldset) {
|
||||||
|
memcpy(opt_out_oldset, &old, sizeof(old));
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
} else if (IsOpenbsd()) {
|
||||||
|
if (!opt_set) how = 1;
|
||||||
|
if (opt_set) opt_set = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
|
||||||
|
if ((x = sys_sigprocmask(how, opt_set, 0, 0)) != -1) {
|
||||||
|
if (opt_out_oldset) {
|
||||||
|
bzero(opt_out_oldset, sizeof(*opt_out_oldset));
|
||||||
|
memcpy(opt_out_oldset, &x, sizeof(x));
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
} else {
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return -1;
|
if (opt_out_oldset) bzero(opt_out_oldset, sizeof(*opt_out_oldset));
|
||||||
|
rc = 0; /* TODO(jart): Implement me! */
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return 0; /* TODO(jart): Implement me! */
|
rc = efault();
|
||||||
}
|
}
|
||||||
|
STRACE("sigprocmask(%s, %s, [%s]) → %d% m", DescribeHow(howbuf, how),
|
||||||
|
__strace_sigset(buf[0], sizeof(buf[0]), 0, opt_set),
|
||||||
|
__strace_sigset(buf[1], sizeof(buf[1]), rc, opt_out_oldset), rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/sigset.h"
|
#include "libc/calls/struct/sigset.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -31,12 +32,18 @@
|
||||||
* @asyncsignalsafe
|
* @asyncsignalsafe
|
||||||
*/
|
*/
|
||||||
int sigsuspend(const sigset_t *ignore) {
|
int sigsuspend(const sigset_t *ignore) {
|
||||||
unsigned x;
|
int rc;
|
||||||
if (IsAsan() && !__asan_is_valid(ignore, sizeof(*ignore))) return efault();
|
char buf[41];
|
||||||
if (!IsWindows()) {
|
if (!ignore || (IsAsan() && !__asan_is_valid(ignore, sizeof(*ignore)))) {
|
||||||
|
rc = efault();
|
||||||
|
} else if (!IsWindows()) {
|
||||||
|
STRACE("sigsuspend(%s)", __strace_sigset(buf, sizeof(buf), 0, ignore));
|
||||||
if (IsOpenbsd()) ignore = (sigset_t *)(uintptr_t)(*(uint32_t *)ignore);
|
if (IsOpenbsd()) ignore = (sigset_t *)(uintptr_t)(*(uint32_t *)ignore);
|
||||||
return sys_sigsuspend(ignore, 8);
|
return sys_sigsuspend(ignore, 8);
|
||||||
} else {
|
} else {
|
||||||
return enosys(); /* TODO(jart): Implement me! */
|
rc = enosys(); /* TODO(jart): Implement me! */
|
||||||
}
|
}
|
||||||
|
STRACE("sigsuspend(%s) → %d% m", __strace_sigset(buf, sizeof(buf), 0, ignore),
|
||||||
|
rc);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/winsize.h"
|
#include "libc/calls/struct/winsize.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/nt/struct/consolescreenbufferinfoex.h"
|
#include "libc/nt/struct/consolescreenbufferinfoex.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
@ -38,8 +38,8 @@ textwindows bool _check_sigwinch(struct Fd *fd) {
|
||||||
if (old.ws_col != ws.ws_col || old.ws_row != ws.ws_row) {
|
if (old.ws_col != ws.ws_col || old.ws_row != ws.ws_row) {
|
||||||
__ws = ws;
|
__ws = ws;
|
||||||
if (old.ws_col | old.ws_row) {
|
if (old.ws_col | old.ws_row) {
|
||||||
SYSDEBUG("SIGWINCH %hhu×%hhu → %hhu×%hhu", old.ws_col, old.ws_row,
|
STRACE("SIGWINCH %hhu×%hhu → %hhu×%hhu", old.ws_col, old.ws_row,
|
||||||
ws.ws_col, ws.ws_row);
|
ws.ws_col, ws.ws_row);
|
||||||
if (__sighandrvas[SIGWINCH] >= kSigactionMinRva) {
|
if (__sighandrvas[SIGWINCH] >= kSigactionMinRva) {
|
||||||
bzero(&si, sizeof(si));
|
bzero(&si, sizeof(si));
|
||||||
((sigaction_f)(_base + __sighandrvas[SIGWINCH]))(SIGWINCH, &si, 0);
|
((sigaction_f)(_base + __sighandrvas[SIGWINCH]))(SIGWINCH, &si, 0);
|
||||||
|
|
34
libc/calls/strace.internal.h
Normal file
34
libc/calls/strace.internal.h
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#ifndef COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
||||||
|
#define COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_
|
||||||
|
#include "libc/calls/struct/rlimit.h"
|
||||||
|
#include "libc/calls/struct/sigaction.h"
|
||||||
|
#include "libc/calls/struct/stat.h"
|
||||||
|
|
||||||
|
#define STRACE_PROLOGUE "%rSYS %5P %'18T "
|
||||||
|
|
||||||
|
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||||
|
COSMOPOLITAN_C_START_
|
||||||
|
|
||||||
|
#ifdef SYSDEBUG
|
||||||
|
#define STRACE(FMT, ...) \
|
||||||
|
do { \
|
||||||
|
if (__strace > 0) { \
|
||||||
|
__stracef(STRACE_PROLOGUE FMT "%n", ##__VA_ARGS__); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#define STRACE(FMT, ...) (void)0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int __strace;
|
||||||
|
|
||||||
|
void __stracef(const char *, ...);
|
||||||
|
const char *__strace_stat(int, const struct stat *);
|
||||||
|
const char *__strace_sigaction(char *, size_t, int, const struct sigaction *);
|
||||||
|
const char *__strace_sigset(char[41], size_t, int, const sigset_t *);
|
||||||
|
const char *__strace_rlimit_name(int);
|
||||||
|
const char *__strace_rlimit(char[41], size_t, int, const struct rlimit *);
|
||||||
|
|
||||||
|
COSMOPOLITAN_C_END_
|
||||||
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
#endif /* COSMOPOLITAN_LIBC_CALLS_STRACE_INTERNAL_H_ */
|
40
libc/calls/strace_rlimit.c
Normal file
40
libc/calls/strace_rlimit.c
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
/*-*- 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 2021 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/strace.internal.h"
|
||||||
|
#include "libc/calls/struct/rlimit.h"
|
||||||
|
#include "libc/fmt/itoa.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
#include "libc/sysv/consts/rlimit.h"
|
||||||
|
|
||||||
|
const char *__strace_rlimit_name(int resource) {
|
||||||
|
static char buf[12];
|
||||||
|
if (resource == RLIMIT_AS) return "RLIMIT_AS";
|
||||||
|
if (resource == RLIMIT_CPU) return "RLIMIT_CPU";
|
||||||
|
if (resource == RLIMIT_FSIZE) return "RLIMIT_FSIZE";
|
||||||
|
FormatInt32(buf, resource);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
privileged const char *__strace_rlimit(char buf[64], size_t bufsize, int rc,
|
||||||
|
const struct rlimit *rlim) {
|
||||||
|
if (rc == -1) return "n/a";
|
||||||
|
if (!rlim) return "NULL";
|
||||||
|
ksnprintf(buf, bufsize, "{%'lu, %'lu}", rlim->rlim_cur, rlim->rlim_max);
|
||||||
|
return buf;
|
||||||
|
}
|
31
libc/calls/strace_sigaction.greg.c
Normal file
31
libc/calls/strace_sigaction.greg.c
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/*-*- 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 2021 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/strace.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
|
||||||
|
privileged const char *__strace_sigaction(char *buf, size_t bufsize, int rc,
|
||||||
|
const struct sigaction *sa) {
|
||||||
|
char maskbuf[41];
|
||||||
|
if (rc == -1) return "n/a";
|
||||||
|
if (!sa) return "NULL";
|
||||||
|
ksnprintf(buf, bufsize, "{.sa_handler=%p, .sa_flags=%#lx, .sa_mask=%s}",
|
||||||
|
sa->sa_handler, sa->sa_flags,
|
||||||
|
__strace_sigset(maskbuf, sizeof(maskbuf), rc, &sa->sa_mask));
|
||||||
|
return buf;
|
||||||
|
}
|
28
libc/calls/strace_sigset.greg.c
Normal file
28
libc/calls/strace_sigset.greg.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*-*- 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 2021 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/strace.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
|
||||||
|
privileged const char *__strace_sigset(char buf[41], size_t bufsize, int rc,
|
||||||
|
const sigset_t *ss) {
|
||||||
|
if (rc == -1) return "n/a";
|
||||||
|
if (!ss) return "NULL";
|
||||||
|
ksnprintf(buf, bufsize, "{%#lx, %#lx}", ss->__bits[0], ss->__bits[1]);
|
||||||
|
return buf;
|
||||||
|
}
|
29
libc/calls/strace_stat.greg.c
Normal file
29
libc/calls/strace_stat.greg.c
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*-*- 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 2021 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/strace.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
|
||||||
|
privileged const char *__strace_stat(int rc, const struct stat *st) {
|
||||||
|
static char buf[256];
|
||||||
|
if (rc == -1) return "n/a";
|
||||||
|
if (!st) return "NULL";
|
||||||
|
ksnprintf(buf, sizeof(buf), "{.st_size=%'ld, .st_mode=%#o, .st_ino=%'lu}",
|
||||||
|
st->st_size, st->st_mode, st->st_ino);
|
||||||
|
return buf;
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_
|
|
||||||
#define COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_
|
|
||||||
#include "libc/log/libfatal.internal.h"
|
|
||||||
|
|
||||||
#ifndef DEBUGSYS
|
|
||||||
#define DEBUGSYS 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DEBUGSYS
|
|
||||||
#define SYSDEBUG(FMT, ...) kprintf("SYS: " FMT "\n", ##__VA_ARGS__)
|
|
||||||
#else
|
|
||||||
#define SYSDEBUG(FMT, ...) (void)0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_ */
|
|
|
@ -19,8 +19,8 @@
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/rusage.h"
|
#include "libc/calls/struct/rusage.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
|
||||||
#include "libc/fmt/conv.h"
|
#include "libc/fmt/conv.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/accounting.h"
|
#include "libc/nt/accounting.h"
|
||||||
|
@ -71,12 +71,12 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options,
|
||||||
i = WaitForMultipleObjects(count, handles, false, -1);
|
i = WaitForMultipleObjects(count, handles, false, -1);
|
||||||
}
|
}
|
||||||
if (i == kNtWaitFailed) {
|
if (i == kNtWaitFailed) {
|
||||||
SYSDEBUG("WaitForMultipleObjects failed %d", GetLastError());
|
STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError());
|
||||||
return __winerr();
|
return __winerr();
|
||||||
}
|
}
|
||||||
assert(__isfdkind(pids[i], kFdProcess));
|
assert(__isfdkind(pids[i], kFdProcess));
|
||||||
if (!GetExitCodeProcess(handles[i], &dwExitCode)) {
|
if (!GetExitCodeProcess(handles[i], &dwExitCode)) {
|
||||||
SYSDEBUG("GetExitCodeProcess failed %d", GetLastError());
|
STRACE("%s failed %u", "GetExitCodeProcess", GetLastError());
|
||||||
return __winerr();
|
return __winerr();
|
||||||
}
|
}
|
||||||
if (dwExitCode == kNtStillActive) continue;
|
if (dwExitCode == kNtStillActive) continue;
|
||||||
|
@ -92,7 +92,7 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options,
|
||||||
opt_out_rusage->ru_stime =
|
opt_out_rusage->ru_stime =
|
||||||
WindowsDurationToTimeVal(ReadFileTime(kernelfiletime));
|
WindowsDurationToTimeVal(ReadFileTime(kernelfiletime));
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("GetProcessTimes failed %d", GetLastError());
|
STRACE("%s failed %u", "GetProcessTimes", GetLastError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CloseHandle(g_fds.p[pids[i]].handle);
|
CloseHandle(g_fds.p[pids[i]].handle);
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/wait4.h"
|
#include "libc/calls/wait4.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -38,21 +38,20 @@
|
||||||
*/
|
*/
|
||||||
int wait4(int pid, int *opt_out_wstatus, int options,
|
int wait4(int pid, int *opt_out_wstatus, int options,
|
||||||
struct rusage *opt_out_rusage) {
|
struct rusage *opt_out_rusage) {
|
||||||
int rc, ws;
|
int rc, ws = 0;
|
||||||
if (IsAsan() &&
|
if (IsAsan() &&
|
||||||
((opt_out_wstatus &&
|
((opt_out_wstatus &&
|
||||||
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) ||
|
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) ||
|
||||||
(opt_out_rusage &&
|
(opt_out_rusage &&
|
||||||
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))))) {
|
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))))) {
|
||||||
return efault();
|
rc = efault();
|
||||||
}
|
} else if (!IsWindows()) {
|
||||||
ws = 0;
|
|
||||||
if (!IsWindows()) {
|
|
||||||
rc = sys_wait4(pid, &ws, options, opt_out_rusage);
|
rc = sys_wait4(pid, &ws, options, opt_out_rusage);
|
||||||
} else {
|
} else {
|
||||||
rc = sys_wait4_nt(pid, &ws, options, opt_out_rusage);
|
rc = sys_wait4_nt(pid, &ws, options, opt_out_rusage);
|
||||||
}
|
}
|
||||||
SYSDEBUG("waitpid(%d, [0x%x], %d) -> [%d]", pid, ws, options, rc);
|
if (rc != -1 && opt_out_wstatus) *opt_out_wstatus = ws;
|
||||||
if (opt_out_wstatus) *opt_out_wstatus = ws;
|
STRACE("wait4(%d, [%#x], %d, %p) → %d% m", pid, ws, options, opt_out_rusage,
|
||||||
|
rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/typedef/sigaction_f.h"
|
#include "libc/calls/typedef/sigaction_f.h"
|
||||||
#include "libc/calls/ucontext.h"
|
#include "libc/calls/ucontext.h"
|
||||||
#include "libc/nt/enum/exceptionhandleractions.h"
|
#include "libc/nt/enum/exceptionhandleractions.h"
|
||||||
|
@ -31,7 +31,7 @@ textwindows unsigned __wincrash(struct NtExceptionPointers *ep) {
|
||||||
ucontext_t ctx;
|
ucontext_t ctx;
|
||||||
struct siginfo si;
|
struct siginfo si;
|
||||||
} g;
|
} g;
|
||||||
SYSDEBUG("__wincrash");
|
STRACE("__wincrash");
|
||||||
switch (ep->ExceptionRecord->ExceptionCode) {
|
switch (ep->ExceptionRecord->ExceptionCode) {
|
||||||
case kNtSignalBreakpoint:
|
case kNtSignalBreakpoint:
|
||||||
sig = SIGTRAP;
|
sig = SIGTRAP;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/calls/struct/iovec.h"
|
#include "libc/calls/struct/iovec.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -1378,6 +1379,7 @@ textstartup void __asan_init(int argc, char **argv, char **envp,
|
||||||
__asan_shadow_string_list(envp);
|
__asan_shadow_string_list(envp);
|
||||||
__asan_shadow_auxv(auxv);
|
__asan_shadow_auxv(auxv);
|
||||||
__asan_install_malloc_hooks();
|
__asan_install_malloc_hooks();
|
||||||
|
STRACE("cosmopolitan memory safety module initialized");
|
||||||
}
|
}
|
||||||
|
|
||||||
static textstartup void __asan_ctor(void) {
|
static textstartup void __asan_ctor(void) {
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#define ShouldUseMsabiAttribute() 1
|
#define ShouldUseMsabiAttribute() 1
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/intrin/kprintf.h"
|
#include "libc/intrin/kprintf.h"
|
||||||
#include "libc/nexgen32e/vendor.internal.h"
|
#include "libc/nexgen32e/vendor.internal.h"
|
||||||
|
@ -37,6 +38,7 @@
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
privileged noinstrument noasan noubsan wontreturn void _Exit(int exitcode) {
|
privileged noinstrument noasan noubsan wontreturn void _Exit(int exitcode) {
|
||||||
|
STRACE("_Exit(%d)", exitcode);
|
||||||
if ((!IsWindows() && !IsMetal()) || (IsMetal() && IsGenuineCosmo())) {
|
if ((!IsWindows() && !IsMetal()) || (IsMetal() && IsGenuineCosmo())) {
|
||||||
asm volatile("syscall"
|
asm volatile("syscall"
|
||||||
: /* no outputs */
|
: /* no outputs */
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
│ 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/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
|
@ -63,6 +63,6 @@ char *getenv(const char *s) {
|
||||||
} else {
|
} else {
|
||||||
r = GetEnv(s, ToUpper);
|
r = GetEnv(s, ToUpper);
|
||||||
}
|
}
|
||||||
SYSDEBUG("getenv(%#s) → %#s", s, r);
|
STRACE("getenv(%#s) → %#s", s, r);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
* @mayalias
|
* @mayalias
|
||||||
*/
|
*/
|
||||||
void(psrldq)(uint8_t b[16], const uint8_t a[16], unsigned long n) {
|
void(psrldq)(uint8_t b[16], const uint8_t a[16], unsigned long n) {
|
||||||
unsigned i;
|
|
||||||
if (n > 16) n = 16;
|
if (n > 16) n = 16;
|
||||||
__builtin_memcpy(b, a + n, 16 - n);
|
__builtin_memcpy(b, a + n, 16 - n);
|
||||||
__builtin_memset(b + (16 - n), 0, n);
|
__builtin_memset(b + (16 - n), 0, n);
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/nt/console.h"
|
#include "libc/nt/console.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
|
@ -35,6 +36,7 @@ const char kConsoleHandles[2] = {kNtStdInputHandle, kNtStdOutputHandle};
|
||||||
wontreturn void quick_exit(int exitcode) {
|
wontreturn void quick_exit(int exitcode) {
|
||||||
int i;
|
int i;
|
||||||
const uintptr_t *p;
|
const uintptr_t *p;
|
||||||
|
STRACE("quick_exit(%d)", exitcode);
|
||||||
if (weaken(fflush)) {
|
if (weaken(fflush)) {
|
||||||
weaken(fflush)(0);
|
weaken(fflush)(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -184,7 +184,7 @@ __asan_version_mismatch_check_v8:
|
||||||
.endfn __asan_version_mismatch_check_v8,globl
|
.endfn __asan_version_mismatch_check_v8,globl
|
||||||
|
|
||||||
// Initializes Address Sanitizer runtime earlier if linked.
|
// Initializes Address Sanitizer runtime earlier if linked.
|
||||||
.init.start 301,_init_asan
|
.init.start 303,_init_asan
|
||||||
push %rdi
|
push %rdi
|
||||||
push %rsi
|
push %rsi
|
||||||
mov %r12,%rdi
|
mov %r12,%rdi
|
||||||
|
@ -194,7 +194,7 @@ __asan_version_mismatch_check_v8:
|
||||||
call __asan_init
|
call __asan_init
|
||||||
pop %rsi
|
pop %rsi
|
||||||
pop %rdi
|
pop %rdi
|
||||||
.init.end 301,_init_asan
|
.init.end 303,_init_asan
|
||||||
|
|
||||||
__asan_before_dynamic_init:
|
__asan_before_dynamic_init:
|
||||||
push %rbp
|
push %rbp
|
||||||
|
|
28
libc/intrin/stracef.greg.c
Normal file
28
libc/intrin/stracef.greg.c
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
/*-*- 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 2021 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/strace.internal.h"
|
||||||
|
#include "libc/intrin/kprintf.h"
|
||||||
|
|
||||||
|
privileged void __stracef(const char *fmt, ...) {
|
||||||
|
va_list v;
|
||||||
|
if (__strace <= 0) return;
|
||||||
|
va_start(v, fmt);
|
||||||
|
kvprintf(fmt, v);
|
||||||
|
va_end(v);
|
||||||
|
}
|
|
@ -242,6 +242,26 @@ forceinline char *__strstr(const char *haystack, const char *needle) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
forceinline char *__getenv(char **p, const char *s) {
|
||||||
|
size_t i, j;
|
||||||
|
if (p) {
|
||||||
|
for (i = 0; p[i]; ++i) {
|
||||||
|
for (j = 0;; ++j) {
|
||||||
|
if (!s[j]) {
|
||||||
|
if (p[i][j] == '=') {
|
||||||
|
return p[i] + j + 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((s[j] & 255) != __ToUpper(p[i][j] & 255)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
forceinline const char *__strchr(const char *s, unsigned char c) {
|
forceinline const char *__strchr(const char *s, unsigned char c) {
|
||||||
char *r;
|
char *r;
|
||||||
for (;; ++s) {
|
for (;; ++s) {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/alg/alg.h"
|
#include "libc/alg/alg.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/mem/internal.h"
|
#include "libc/mem/internal.h"
|
||||||
|
@ -121,6 +121,6 @@ void __freeenv(void *p) {
|
||||||
int putenv(char *s) {
|
int putenv(char *s) {
|
||||||
int rc;
|
int rc;
|
||||||
rc = PutEnvImpl(strdup(s), true);
|
rc = PutEnvImpl(strdup(s), true);
|
||||||
SYSDEBUG("putenv(%#s) → %d", s, rc);
|
STRACE("putenv(%#s) → %d", s, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
│ 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/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/mem/internal.h"
|
#include "libc/mem/internal.h"
|
||||||
#include "libc/mem/mem.h"
|
#include "libc/mem/mem.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
@ -37,6 +37,6 @@ int setenv(const char *name, const char *value, int overwrite) {
|
||||||
s = malloc(namelen + valuelen + 2);
|
s = malloc(namelen + valuelen + 2);
|
||||||
memcpy(mempcpy(mempcpy(s, name, namelen), "=", 1), value, valuelen + 1);
|
memcpy(mempcpy(mempcpy(s, name, namelen), "=", 1), value, valuelen + 1);
|
||||||
rc = PutEnvImpl(s, overwrite);
|
rc = PutEnvImpl(s, overwrite);
|
||||||
SYSDEBUG("setenv(%#s, %#s, %d) → %d", name, value, overwrite, rc);
|
STRACE("setenv(%#s, %#s, %d) → %d", name, value, overwrite, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
│ 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/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
|
|
||||||
noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) {
|
noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) {
|
||||||
|
@ -24,7 +24,7 @@ noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < mm->i; ++i) {
|
for (i = 0; i < mm->i; ++i) {
|
||||||
if (mm->p[i].y < mm->p[i].x) {
|
if (mm->p[i].y < mm->p[i].x) {
|
||||||
SYSDEBUG("AreMemoryIntervalsOk() y should be >= x!");
|
STRACE("AreMemoryIntervalsOk() y should be >= x!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (i) {
|
if (i) {
|
||||||
|
@ -34,7 +34,7 @@ noasan bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!(mm->p[i - 1].y + 1 <= mm->p[i].x)) {
|
if (!(mm->p[i - 1].y + 1 <= mm->p[i].x)) {
|
||||||
SYSDEBUG("AreMemoryIntervalsOk() out of order or overlap!");
|
STRACE("AreMemoryIntervalsOk() out of order or overlap!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,14 @@
|
||||||
│ 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/strace.internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes all environment variables.
|
* Removes all environment variables.
|
||||||
*/
|
*/
|
||||||
int clearenv(void) {
|
int clearenv(void) {
|
||||||
|
STRACE("clearenv() → 0");
|
||||||
environ = NULL;
|
environ = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "libc/notice.inc"
|
#include "libc/notice.inc"
|
||||||
#include "libc/sysv/consts/prot.h"
|
#include "libc/sysv/consts/prot.h"
|
||||||
#include "libc/sysv/consts/map.h"
|
#include "libc/sysv/consts/map.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
.text.startup
|
.text.startup
|
||||||
|
|
||||||
|
@ -37,6 +38,10 @@ cosmo: push %rbp
|
||||||
mov %rsi,%r13
|
mov %rsi,%r13
|
||||||
mov %rdx,%r14
|
mov %rdx,%r14
|
||||||
mov %rcx,%r15
|
mov %rcx,%r15
|
||||||
|
#ifdef SYSDEBUG
|
||||||
|
call __strace_init
|
||||||
|
mov %eax,%r12d
|
||||||
|
#endif /* SYSDEBUG */
|
||||||
#ifdef __FAST_MATH__
|
#ifdef __FAST_MATH__
|
||||||
push %rax
|
push %rax
|
||||||
stmxcsr (%rsp)
|
stmxcsr (%rsp)
|
||||||
|
@ -72,7 +77,7 @@ cosmo: push %rbp
|
||||||
.endfn cosmo,weak
|
.endfn cosmo,weak
|
||||||
|
|
||||||
#ifdef __PG__
|
#ifdef __PG__
|
||||||
.init.start 800,_init_ftrace
|
.init.start 306,_init_ftrace
|
||||||
push %rdi
|
push %rdi
|
||||||
push %rsi
|
push %rsi
|
||||||
mov %r12d,%edi
|
mov %r12d,%edi
|
||||||
|
@ -86,5 +91,21 @@ cosmo: push %rbp
|
||||||
mov %eax,%r12d
|
mov %eax,%r12d
|
||||||
pop %rsi
|
pop %rsi
|
||||||
pop %rdi
|
pop %rdi
|
||||||
.init.end 800,_init_ftrace
|
.init.end 306,_init_ftrace
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if IsModeDbg()
|
||||||
|
#ifdef SYSDEBUG
|
||||||
|
.init.start 307,_init_printargs
|
||||||
|
push %rdi
|
||||||
|
push %rsi
|
||||||
|
mov %r12d,%edi
|
||||||
|
mov %r13,%rsi
|
||||||
|
mov %r14,%rdx
|
||||||
|
mov %r15,%rcx
|
||||||
|
call __printargs
|
||||||
|
pop %rsi
|
||||||
|
pop %rdi
|
||||||
|
.init.end 307,_init_printargs
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,7 +19,9 @@
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/notice.inc"
|
#include "libc/notice.inc"
|
||||||
|
|
||||||
|
.underrun
|
||||||
// Uniquely identifies each artifact linked in an address space.
|
// Uniquely identifies each artifact linked in an address space.
|
||||||
__dso_handle:
|
__dso_handle:
|
||||||
.quad __dso_handle
|
.quad __dso_handle
|
||||||
.endobj __dso_handle,globl,hidden
|
.endobj __dso_handle,globl,hidden
|
||||||
|
.overrun
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/runtime/internal.h"
|
#include "libc/runtime/internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@
|
||||||
* @noreturn
|
* @noreturn
|
||||||
*/
|
*/
|
||||||
wontreturn void exit(int exitcode) {
|
wontreturn void exit(int exitcode) {
|
||||||
|
STRACE("exit(%d)", exitcode);
|
||||||
if (weaken(__cxa_finalize)) {
|
if (weaken(__cxa_finalize)) {
|
||||||
weaken(__cxa_finalize)(NULL);
|
weaken(__cxa_finalize)(NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,46 +22,37 @@
|
||||||
#include "libc/runtime/symbols.internal.h"
|
#include "libc/runtime/symbols.internal.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
static char *g_comdbg;
|
|
||||||
static char g_comdbg_buf[PATH_MAX + 1];
|
|
||||||
|
|
||||||
static optimizesize textstartup void g_comdbg_init() {
|
|
||||||
char *p;
|
|
||||||
size_t n;
|
|
||||||
static bool once;
|
|
||||||
if (!once) {
|
|
||||||
if (!(g_comdbg = getenv("COMDBG"))) {
|
|
||||||
p = program_executable_name;
|
|
||||||
n = strlen(p);
|
|
||||||
if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg")) {
|
|
||||||
g_comdbg = p;
|
|
||||||
} else if (n > 4 && READ32LE(p + n - 4) == READ32LE(".com") &&
|
|
||||||
n + 4 <= PATH_MAX) {
|
|
||||||
mempcpy(mempcpy(g_comdbg_buf, p, n), ".dbg", 5);
|
|
||||||
if (fileexists(g_comdbg_buf)) {
|
|
||||||
g_comdbg = g_comdbg_buf;
|
|
||||||
}
|
|
||||||
} else if (n + 8 <= PATH_MAX) {
|
|
||||||
mempcpy(mempcpy(g_comdbg_buf, p, n), ".com.dbg", 9);
|
|
||||||
if (fileexists(g_comdbg_buf)) {
|
|
||||||
g_comdbg = g_comdbg_buf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
once = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns path of binary with the debug information, or null.
|
* Returns path of binary with the debug information, or null.
|
||||||
*
|
*
|
||||||
* @return path to debug binary, or NULL
|
* @return path to debug binary, or NULL
|
||||||
*/
|
*/
|
||||||
const char *FindDebugBinary(void) {
|
const char *FindDebugBinary(void) {
|
||||||
g_comdbg_init();
|
static bool once;
|
||||||
return g_comdbg;
|
static char *res;
|
||||||
|
static char buf[PATH_MAX + 1];
|
||||||
|
char *p;
|
||||||
|
size_t n;
|
||||||
|
if (!once) {
|
||||||
|
if (!(res = getenv("COMDBG"))) {
|
||||||
|
p = program_executable_name;
|
||||||
|
n = strlen(p);
|
||||||
|
if (n > 4 && READ32LE(p + n - 4) == READ32LE(".dbg")) {
|
||||||
|
res = p;
|
||||||
|
} else if (n > 4 && READ32LE(p + n - 4) == READ32LE(".com") &&
|
||||||
|
n + 4 <= PATH_MAX) {
|
||||||
|
mempcpy(mempcpy(buf, p, n), ".dbg", 5);
|
||||||
|
if (fileexists(buf)) {
|
||||||
|
res = buf;
|
||||||
|
}
|
||||||
|
} else if (n + 8 <= PATH_MAX) {
|
||||||
|
mempcpy(mempcpy(buf, p, n), ".com.dbg", 9);
|
||||||
|
if (fileexists(buf)) {
|
||||||
|
res = buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
once = true;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *const g_comdbg_ctor[] initarray = {
|
|
||||||
g_comdbg_init,
|
|
||||||
};
|
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/ntspawn.h"
|
#include "libc/calls/ntspawn.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/fmt/itoa.h"
|
#include "libc/fmt/itoa.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nexgen32e/nt2sysv.h"
|
#include "libc/nexgen32e/nt2sysv.h"
|
||||||
|
@ -60,7 +60,7 @@ static textwindows noasan char16_t *ParseInt(char16_t *p, int64_t *x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static dontinline textwindows noasan bool ForkIo(int64_t h, void *buf, size_t n,
|
static dontinline textwindows noasan bool ForkIo(int64_t h, void *buf, size_t n,
|
||||||
bool32 (*f)()) {
|
bool32 (*f)()) {
|
||||||
char *p;
|
char *p;
|
||||||
size_t i;
|
size_t i;
|
||||||
uint32_t x;
|
uint32_t x;
|
||||||
|
@ -73,17 +73,15 @@ static dontinline textwindows noasan bool ForkIo(int64_t h, void *buf, size_t n,
|
||||||
}
|
}
|
||||||
|
|
||||||
static dontinline textwindows noasan void WriteAll(int64_t h, void *buf,
|
static dontinline textwindows noasan void WriteAll(int64_t h, void *buf,
|
||||||
size_t n) {
|
size_t n) {
|
||||||
if (!ForkIo(h, buf, n, WriteFile)) {
|
bool rc = ForkIo(h, buf, n, WriteFile);
|
||||||
SYSDEBUG("fork() WriteFile(%zu) failed %d\n", n, GetLastError());
|
STRACE("%s(%ld, %'zu) %d% m", "WriteFile", h, n);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static textwindows dontinline noasan void ReadAll(int64_t h, void *buf,
|
static textwindows dontinline noasan void ReadAll(int64_t h, void *buf,
|
||||||
size_t n) {
|
size_t n) {
|
||||||
if (!ForkIo(h, buf, n, ReadFile)) {
|
bool rc = ForkIo(h, buf, n, ReadFile);
|
||||||
SYSDEBUG("fork() ReadFile(%zu) failed %d\n", n, GetLastError());
|
STRACE("%s(%ld, %'zu) %d% m", "ReadFile", h, n);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
textwindows noasan noinstrument void WinMainForked(void) {
|
textwindows noasan noinstrument void WinMainForked(void) {
|
||||||
|
@ -99,6 +97,7 @@ textwindows noasan noinstrument void WinMainForked(void) {
|
||||||
varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var));
|
varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var));
|
||||||
if (!varlen) return;
|
if (!varlen) return;
|
||||||
if (varlen >= ARRAYLEN(var)) ExitProcess(123);
|
if (varlen >= ARRAYLEN(var)) ExitProcess(123);
|
||||||
|
STRACE("WinMainForked()");
|
||||||
SetEnvironmentVariable(u"_FORK", NULL);
|
SetEnvironmentVariable(u"_FORK", NULL);
|
||||||
ParseInt(ParseInt(var, &reader), &writer);
|
ParseInt(ParseInt(var, &reader), &writer);
|
||||||
ReadAll(reader, jb, sizeof(jb));
|
ReadAll(reader, jb, sizeof(jb));
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/internal.h"
|
#include "libc/calls/internal.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/nt/process.h"
|
#include "libc/nt/process.h"
|
||||||
|
|
||||||
|
@ -55,12 +55,12 @@ int fork(void) {
|
||||||
}
|
}
|
||||||
parent = __pid;
|
parent = __pid;
|
||||||
__pid = dx;
|
__pid = dx;
|
||||||
SYSDEBUG("fork() → 0 (child of %d)", parent);
|
STRACE("fork() → 0 (child of %d)", parent);
|
||||||
if (weaken(__onfork)) {
|
if (weaken(__onfork)) {
|
||||||
weaken(__onfork)();
|
weaken(__onfork)();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
SYSDEBUG("fork() → %d% m", ax);
|
STRACE("fork() → %d% m", ax);
|
||||||
}
|
}
|
||||||
return ax;
|
return ax;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
ftrace_hook:
|
ftrace_hook:
|
||||||
cmp $0,g_ftrace(%rip)
|
cmp $0,g_ftrace(%rip)
|
||||||
je 1f
|
jg 1f
|
||||||
ret
|
ret
|
||||||
1: push %rbp
|
1: push %rbp
|
||||||
mov %rsp,%rbp
|
mov %rsp,%rbp
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
│ 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/runtime/internal.h"
|
||||||
#include "libc/runtime/runtime.h"
|
#include "libc/runtime/runtime.h"
|
||||||
#include "libc/str/str.h"
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
@ -31,26 +32,10 @@
|
||||||
*
|
*
|
||||||
* @see libc/runtime/_init.S for documentation
|
* @see libc/runtime/_init.S for documentation
|
||||||
*/
|
*/
|
||||||
textstartup int ftrace_init(int argc, char *argv[]) {
|
textstartup int ftrace_init(void) {
|
||||||
int i;
|
if (__intercept_flag(&__argc, __argv, "--ftrace")) {
|
||||||
bool foundflag;
|
|
||||||
foundflag = false;
|
|
||||||
for (i = 1; i <= argc; ++i) {
|
|
||||||
if (!foundflag) {
|
|
||||||
if (argv[i]) {
|
|
||||||
if (strcmp(argv[i], "--ftrace") == 0) {
|
|
||||||
foundflag = true;
|
|
||||||
} else if (strcmp(argv[i], "----ftrace") == 0) {
|
|
||||||
strcpy(argv[i], "--ftrace");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
argv[i - 1] = argv[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (foundflag) {
|
|
||||||
--argc;
|
|
||||||
ftrace_install();
|
ftrace_install();
|
||||||
|
++g_ftrace;
|
||||||
}
|
}
|
||||||
return argc;
|
return __argc;
|
||||||
}
|
}
|
46
libc/runtime/interceptflag.greg.c
Normal file
46
libc/runtime/interceptflag.greg.c
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
/*-*- 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 2021 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/log/libfatal.internal.h"
|
||||||
|
#include "libc/runtime/internal.h"
|
||||||
|
#include "libc/str/str.h"
|
||||||
|
|
||||||
|
textstartup bool __intercept_flag(int *argc, char *argv[], const char *flag) {
|
||||||
|
/* asan isn't initialized yet at runlevel 300 */
|
||||||
|
char *a;
|
||||||
|
int i, j;
|
||||||
|
bool found;
|
||||||
|
found = false;
|
||||||
|
for (j = i = 1; i <= *argc;) {
|
||||||
|
a = argv[j++];
|
||||||
|
if (a && !__strcmp(a, flag)) {
|
||||||
|
found = true;
|
||||||
|
--*argc;
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* e.g. turns ----strace → --strace for execve.
|
||||||
|
* todo: update this to allow ------strace etc.
|
||||||
|
*/
|
||||||
|
if (a && a[0] == '-' && a[1] == '-' && !__strcmp(a + 2, flag)) {
|
||||||
|
a = flag;
|
||||||
|
}
|
||||||
|
argv[i++] = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ long _setstack(void *, void *, ...) hidden;
|
||||||
int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden;
|
int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden;
|
||||||
Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden;
|
Elf64_Ehdr *MapElfRead(const char *, struct MappedFile *) hidden;
|
||||||
int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t) hidden;
|
int GetDosEnviron(const char16_t *, char *, size_t, char **, size_t) hidden;
|
||||||
|
bool __intercept_flag(int *, char *[], const char *);
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
COSMOPOLITAN_C_END_
|
||||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
#include "libc/bits/likely.h"
|
#include "libc/bits/likely.h"
|
||||||
#include "libc/bits/weaken.h"
|
#include "libc/bits/weaken.h"
|
||||||
#include "libc/calls/calls.h"
|
#include "libc/calls/calls.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/errno.h"
|
#include "libc/errno.h"
|
||||||
#include "libc/intrin/asan.internal.h"
|
#include "libc/intrin/asan.internal.h"
|
||||||
|
@ -76,13 +76,13 @@ static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
|
||||||
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
||||||
dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0);
|
dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0);
|
||||||
if (!dm.addr) {
|
if (!dm.addr) {
|
||||||
SYSDEBUG("ExtendMemoryIntervals() fail #1");
|
STRACE("ExtendMemoryIntervals() fail #1");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dm = sys_mmap(base, gran, prot, flags, -1, 0);
|
dm = sys_mmap(base, gran, prot, flags, -1, 0);
|
||||||
if (!dm.addr) {
|
if (!dm.addr) {
|
||||||
SYSDEBUG("ExtendMemoryIntervals() fail #2");
|
STRACE("ExtendMemoryIntervals() fail #2");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
MoveMemoryIntervals(dm.addr, mm->p, mm->i);
|
MoveMemoryIntervals(dm.addr, mm->p, mm->i);
|
||||||
|
@ -95,13 +95,13 @@ static noasan bool ExtendMemoryIntervals(struct MemoryIntervals *mm) {
|
||||||
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
shad = (char *)(((intptr_t)base >> 3) + 0x7fff8000);
|
||||||
dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0);
|
dm = sys_mmap(shad, gran >> 3, prot, flags, -1, 0);
|
||||||
if (!dm.addr) {
|
if (!dm.addr) {
|
||||||
SYSDEBUG("ExtendMemoryIntervals() fail #3");
|
STRACE("ExtendMemoryIntervals() fail #3");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dm = sys_mmap(base, gran, prot, flags, -1, 0);
|
dm = sys_mmap(base, gran, prot, flags, -1, 0);
|
||||||
if (!dm.addr) {
|
if (!dm.addr) {
|
||||||
SYSDEBUG("ExtendMemoryIntervals() fail #4");
|
STRACE("ExtendMemoryIntervals() fail #4");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
mm->n = (size + gran) / sizeof(*mm->p);
|
mm->n = (size + gran) / sizeof(*mm->p);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
#ifndef COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
||||||
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
#define COSMOPOLITAN_LIBC_RUNTIME_MEMTRACK_H_
|
||||||
|
#include "libc/assert.h"
|
||||||
#include "libc/dce.h"
|
#include "libc/dce.h"
|
||||||
#include "libc/macros.internal.h"
|
#include "libc/macros.internal.h"
|
||||||
#include "libc/nt/enum/version.h"
|
#include "libc/nt/enum/version.h"
|
||||||
|
@ -164,6 +165,7 @@ forceinline unsigned FindMemoryInterval(const struct MemoryIntervals *mm,
|
||||||
r = m;
|
r = m;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(l == mm->i || x <= mm->p[l].y);
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +173,7 @@ forceinline bool IsMemtracked(int x, int y) {
|
||||||
unsigned i;
|
unsigned i;
|
||||||
i = FindMemoryInterval(&_mmi, x);
|
i = FindMemoryInterval(&_mmi, x);
|
||||||
if (i == _mmi.i) return false;
|
if (i == _mmi.i) return false;
|
||||||
if (!(_mmi.p[i].x <= x && x <= _mmi.p[i].y)) return false;
|
if (x < _mmi.p[i].x) return false;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (y <= _mmi.p[i].y) return true;
|
if (y <= _mmi.p[i].y) return true;
|
||||||
if (++i == _mmi.i) return false;
|
if (++i == _mmi.i) return false;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||||
#include "libc/assert.h"
|
#include "libc/assert.h"
|
||||||
#include "libc/calls/sysdebug.internal.h"
|
#include "libc/calls/strace.internal.h"
|
||||||
#include "libc/nt/memory.h"
|
#include "libc/nt/memory.h"
|
||||||
#include "libc/nt/runtime.h"
|
#include "libc/nt/runtime.h"
|
||||||
#include "libc/runtime/memtrack.internal.h"
|
#include "libc/runtime/memtrack.internal.h"
|
||||||
|
@ -37,8 +37,8 @@ noasan void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) {
|
||||||
for (i = l; i <= r; ++i) {
|
for (i = l; i <= r; ++i) {
|
||||||
addr = GetFrameAddr(mm->p[i].x);
|
addr = GetFrameAddr(mm->p[i].x);
|
||||||
last = GetFrameAddr(mm->p[i].y);
|
last = GetFrameAddr(mm->p[i].y);
|
||||||
SYSDEBUG("UnmapViewOfFile(addr:0x%x, size:0x%x, hand:0x%x)", addr,
|
STRACE("UnmapViewOfFile(%p, size:%'zu, hand:%ld)", addr,
|
||||||
last - addr + FRAMESIZE, mm->p[i].h);
|
last - addr + FRAMESIZE, mm->p[i].h);
|
||||||
ok = UnmapViewOfFile(addr);
|
ok = UnmapViewOfFile(addr);
|
||||||
assert(ok);
|
assert(ok);
|
||||||
ok = CloseHandle(mm->p[i].h);
|
ok = CloseHandle(mm->p[i].h);
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue