mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-23 19:10:30 +00:00
Make numerous improvements
- Python static hello world now 1.8mb - Python static fully loaded now 10mb - Python HTTPS client now uses MbedTLS - Python REPL now completes import stmts - Increase stack size for Python for now - Begin synthesizing posixpath and ntpath - Restore Python \N{UNICODE NAME} support - Restore Python NFKD symbol normalization - Add optimized code path for Intel SHA-NI - Get more Python unit tests passing faster - Get Python help() pagination working on NT - Python hashlib now supports MbedTLS PBKDF2 - Make memcpy/memmove/memcmp/bcmp/etc. faster - Add Mersenne Twister and Vigna to LIBC_RAND - Provide privileged __printf() for error code - Fix zipos opendir() so that it reports ENOTDIR - Add basic chmod() implementation for Windows NT - Add Cosmo's best functions to Python cosmo module - Pin function trace indent depth to that of caller - Show memory diagram on invalid access in MODE=dbg - Differentiate stack overflow on crash in MODE=dbg - Add stb_truetype and tools for analyzing font files - Upgrade to UNICODE 13 and reduce its binary footprint - COMPILE.COM now logs resource usage of build commands - Start implementing basic poll() support on bare metal - Set getauxval(AT_EXECFN) to GetModuleFileName() on NT - Add descriptions to strerror() in non-TINY build modes - Add COUNTBRANCH() macro to help with micro-optimizations - Make error / backtrace / asan / memory code more unbreakable - Add fast perfect C implementation of μ-Law and a-Law audio codecs - Make strtol() functions consistent with other libc implementations - Improve Linenoise implementation (see also github.com/jart/bestline) - COMPILE.COM now suppresses stdout/stderr of successful build commands
This commit is contained in:
parent
fa7b4f5bd1
commit
39bf41f4eb
806 changed files with 77494 additions and 63859 deletions
|
@ -17,18 +17,21 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_chdir_nt(const char *path) {
|
||||
uint32_t n;
|
||||
int e, ms, len;
|
||||
char16_t path16[PATH_MAX];
|
||||
char16_t path16[PATH_MAX], var[4];
|
||||
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||
if (path16[len - 1] != u'\\') {
|
||||
if (len + 1 + 1 > PATH_MAX) return enametoolong();
|
||||
if (len && path16[len - 1] != u'\\') {
|
||||
if (len + 2 > PATH_MAX) return enametoolong();
|
||||
path16[len + 0] = u'\\';
|
||||
path16[len + 1] = u'\0';
|
||||
}
|
||||
|
@ -38,7 +41,28 @@ textwindows int sys_chdir_nt(const char *path) {
|
|||
*/
|
||||
for (ms = 1;; ms *= 2) {
|
||||
if (SetCurrentDirectory(path16)) {
|
||||
return 0;
|
||||
/*
|
||||
* Now we need to set a magic environment variable.
|
||||
*/
|
||||
if ((n = GetCurrentDirectory(ARRAYLEN(path16), path16))) {
|
||||
if (n < ARRAYLEN(path16)) {
|
||||
if (!((path16[0] == '/' && path16[1] == '/') ||
|
||||
(path16[0] == '\\' && path16[1] == '\\'))) {
|
||||
var[0] = '=';
|
||||
var[1] = path16[0];
|
||||
var[2] = ':';
|
||||
var[3] = 0;
|
||||
if (!SetEnvironmentVariable(var, path16)) {
|
||||
return __winerr();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return enametoolong();
|
||||
}
|
||||
} else {
|
||||
return __winerr();
|
||||
}
|
||||
} else {
|
||||
e = GetLastError();
|
||||
if (ms <= 512 &&
|
||||
|
|
|
@ -32,8 +32,6 @@
|
|||
* CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit
|
||||
* CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit
|
||||
*
|
||||
* This works on Windows NT if you ignore the error ;-)
|
||||
*
|
||||
* @param pathname must exist
|
||||
* @param mode contains octal flags (base 8)
|
||||
* @errors ENOENT, ENOTDIR, ENOSYS
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -36,6 +37,7 @@
|
|||
*/
|
||||
int close(int fd) {
|
||||
int rc;
|
||||
if (fd == -1) return 0;
|
||||
if (fd < 0) return einval();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
rc = weaken(__zipos_close)(fd);
|
||||
|
@ -59,5 +61,6 @@ int close(int fd) {
|
|||
}
|
||||
}
|
||||
__releasefd(fd);
|
||||
SYSDEBUG("close(%d) -> %d", fd, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -22,8 +22,9 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static bool AccessCommand(char path[hasatleast PATH_MAX], const char *name,
|
||||
size_t namelen, size_t pathlen) {
|
||||
static noasan bool AccessCommand(char path[hasatleast PATH_MAX],
|
||||
const char *name, size_t namelen,
|
||||
size_t pathlen) {
|
||||
if (pathlen + 1 + namelen + 1 + 4 + 1 > PATH_MAX) return -1;
|
||||
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
|
||||
path[pathlen] = !IsWindows() ? '/'
|
||||
|
@ -40,8 +41,8 @@ static bool AccessCommand(char path[hasatleast PATH_MAX], const char *name,
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool SearchPath(char path[hasatleast PATH_MAX], const char *name,
|
||||
size_t namelen) {
|
||||
static noasan bool SearchPath(char path[hasatleast PATH_MAX], const char *name,
|
||||
size_t namelen) {
|
||||
size_t i;
|
||||
const char *p;
|
||||
p = firstnonnull(emptytonull(getenv("PATH")), "/bin:/usr/local/bin:/usr/bin");
|
||||
|
@ -70,7 +71,7 @@ static bool SearchPath(char path[hasatleast PATH_MAX], const char *name,
|
|||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
||||
noasan char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
||||
char *p;
|
||||
size_t namelen;
|
||||
int rc, olderr;
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include "libc/time/time.h"
|
||||
|
||||
static textwindows int sys_copyfile_nt(const char *src, const char *dst,
|
||||
int flags) {
|
||||
int flags) {
|
||||
int64_t fhsrc, fhdst;
|
||||
struct NtFileTime accessed, modified;
|
||||
char16_t src16[PATH_MAX], dst16[PATH_MAX];
|
||||
|
@ -99,6 +99,13 @@ static int sys_copyfile(const char *src, const char *dst, int flags) {
|
|||
|
||||
/**
|
||||
* Copies file.
|
||||
*
|
||||
* This implementation goes 2x faster than the `cp` command that comes
|
||||
* included with most systems since we use the newer copy_file_range()
|
||||
* system call rather than sendfile().
|
||||
*
|
||||
* @param flags may have COPYFILE_PRESERVE_TIMESTAMPS, COPYFILE_NOCLOBBER
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int copyfile(const char *src, const char *dst, int flags) {
|
||||
if (!IsWindows()) {
|
||||
|
|
|
@ -47,6 +47,7 @@ textwindows int sys_dup_nt(int oldfd, int newfd, int flags) {
|
|||
if (DuplicateHandle(proc, g_fds.p[oldfd].handle, proc, &g_fds.p[newfd].handle,
|
||||
0, true, kNtDuplicateSameAccess)) {
|
||||
g_fds.p[newfd].kind = g_fds.p[oldfd].kind;
|
||||
g_fds.p[newfd].extra = g_fds.p[oldfd].extra;
|
||||
g_fds.p[newfd].flags = flags;
|
||||
return newfd;
|
||||
} else {
|
||||
|
|
|
@ -35,7 +35,7 @@ int __ensurefds(int fd) {
|
|||
n2 = MAX(fd + 1, n1 + (n1 << 1));
|
||||
if ((p2 = weaken(malloc)(n2 * sizeof(*p1)))) {
|
||||
memcpy(p2, p1, n1 * sizeof(*p1));
|
||||
memset(p2 + n1, 0, (n2 - n1) * sizeof(*p1));
|
||||
bzero(p2 + n1, (n2 - n1) * sizeof(*p1));
|
||||
if (p1 != g_fds.__init_p && weaken(free)) weaken(free)(p1);
|
||||
if (cmpxchg(&g_fds.p, p1, p2)) {
|
||||
g_fds.n = n2;
|
||||
|
|
|
@ -37,7 +37,7 @@ textwindows int sys_execve_nt(const char *program, char *const argv[],
|
|||
uint32_t dwExitCode;
|
||||
struct NtStartupInfo startinfo;
|
||||
struct NtProcessInformation procinfo;
|
||||
memset(&startinfo, 0, sizeof(startinfo));
|
||||
bzero(&startinfo, sizeof(startinfo));
|
||||
startinfo.cb = sizeof(struct NtStartupInfo);
|
||||
startinfo.dwFlags = kNtStartfUsestdhandles;
|
||||
startinfo.hStdInput = g_fds.p[0].handle;
|
||||
|
|
|
@ -18,8 +18,10 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -44,6 +46,19 @@ int execve(const char *program, char *const argv[], char *const envp[]) {
|
|||
!__asan_is_valid_strlist(envp))) {
|
||||
return efault();
|
||||
}
|
||||
if (DEBUGSYS) {
|
||||
__printf("SYS: execve(%s, {", program);
|
||||
for (i = 0; argv[i]; ++i) {
|
||||
if (i) __printf(", ");
|
||||
__printf("%s", argv[i]);
|
||||
}
|
||||
__printf("}, {");
|
||||
for (i = 0; envp[i]; ++i) {
|
||||
if (i) __printf(", ");
|
||||
__printf("%s", envp[i]);
|
||||
}
|
||||
__printf("})\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);
|
||||
|
|
39
libc/calls/fchmodat-nt.c
Normal file
39
libc/calls/fchmodat-nt.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- 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/internal.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/files.h"
|
||||
|
||||
textwindows int sys_fchmodat_nt(int dirfd, const char *path, uint32_t mode,
|
||||
int flags) {
|
||||
uint32_t attr;
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
if ((attr = GetFileAttributes(path16)) != -1) {
|
||||
if (mode & 0200) {
|
||||
attr &= ~kNtFileAttributeReadonly;
|
||||
} else {
|
||||
attr |= kNtFileAttributeReadonly;
|
||||
}
|
||||
if (SetFileAttributes(path16, attr)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return __winerr();
|
||||
}
|
|
@ -31,8 +31,6 @@
|
|||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "o/default/program.com", 0755));
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "privatefolder/", 0700));
|
||||
*
|
||||
* This works on Windows NT if you ignore the error ;-)
|
||||
*
|
||||
* @param path must exist
|
||||
* @param mode contains octal flags (base 8)
|
||||
* @param flags can have `AT_SYMLINK_NOFOLLOW`
|
||||
|
|
|
@ -29,7 +29,7 @@ textwindows int sys_flock_nt(int fd, int op) {
|
|||
struct NtOverlapped ov;
|
||||
struct NtByHandleFileInformation info;
|
||||
if (!__isfdkind(fd, kFdFile)) return ebadf();
|
||||
memset(&ov, 0, sizeof(ov));
|
||||
bzero(&ov, sizeof(ov));
|
||||
if (GetFileInformationByHandle(g_fds.p[fd].handle, &info) &&
|
||||
((!(op & LOCK_UN) &&
|
||||
LockFileEx(g_fds.p[fd].handle, op, 0, info.nFileSizeLow,
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
int sys_fstat_metal(int fd, struct stat *st) {
|
||||
if (fd < 0) return einval();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdSerial) {
|
||||
memset(st, 0, sizeof(*st));
|
||||
bzero(st, sizeof(*st));
|
||||
st->st_dev = g_fds.p[fd].handle;
|
||||
st->st_rdev = g_fds.p[fd].handle;
|
||||
st->st_nlink = 1;
|
||||
|
|
|
@ -76,7 +76,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) {
|
|||
struct NtByHandleFileInformation wst;
|
||||
if (!st) return efault();
|
||||
if ((filetype = GetFileType(handle))) {
|
||||
memset(st, 0, sizeof(*st));
|
||||
bzero(st, sizeof(*st));
|
||||
switch (filetype) {
|
||||
case kNtFileTypeChar:
|
||||
st->st_mode = S_IFCHR | 0644;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -41,6 +42,7 @@ int32_t sys_fstat(int32_t fd, struct stat *st) {
|
|||
__stat2cosmo(st, &ms);
|
||||
return 0;
|
||||
} else {
|
||||
SYSDEBUG("sys_fstat(%d) failed w/ %m", fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,9 +32,7 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
|||
uint16_t path16[PATH_MAX];
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
if ((fh = CreateFile(
|
||||
path16, kNtFileReadAttributes,
|
||||
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, NULL,
|
||||
kNtOpenExisting,
|
||||
path16, kNtFileReadAttributes, 0, 0, kNtOpenExisting,
|
||||
kNtFileAttributeNormal | kNtFileFlagBackupSemantics |
|
||||
((flags & AT_SYMLINK_NOFOLLOW) ? kNtFileFlagOpenReparsePoint
|
||||
: 0),
|
||||
|
|
|
@ -34,7 +34,7 @@ textwindows int sys_getrusage_nt(int who, struct rusage *usage) {
|
|||
struct NtFileTime UserFileTime;
|
||||
if (!usage) return efault();
|
||||
if (who == 99) return enosys(); /* @see libc/sysv/consts.sh */
|
||||
memset(usage, 0, sizeof(*usage));
|
||||
bzero(usage, sizeof(*usage));
|
||||
if ((who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)(
|
||||
(who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(),
|
||||
&CreationFileTime, &ExitFileTime, &KernelFileTime, &UserFileTime)) {
|
||||
|
|
|
@ -29,6 +29,6 @@ int sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz) {
|
|||
struct NtFileTime ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
if (tv) *tv = FileTimeToTimeVal(ft);
|
||||
if (tz) memset(tz, 0, sizeof(*tz));
|
||||
if (tz) bzero(tz, sizeof(*tz));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -261,6 +261,7 @@ int sys_execve_nt(const char *, char *const[], char *const[]) hidden;
|
|||
int sys_faccessat_nt(int, const char *, int, uint32_t) hidden;
|
||||
int sys_fadvise_nt(int, u64, u64, int) hidden;
|
||||
int sys_fchdir_nt(int) hidden;
|
||||
int sys_fchmodat_nt(int, const char *, uint32_t, int) hidden;
|
||||
int sys_fcntl_nt(int, int, uintptr_t) hidden;
|
||||
int sys_fdatasync_nt(int) hidden;
|
||||
int sys_flock_nt(int, int) hidden;
|
||||
|
|
|
@ -76,7 +76,7 @@ static int ioctl_siocgifconf_sysv(int fd, struct ifconf *ifc) {
|
|||
fam = p[IsBsd() ? 17 : 16] & 255;
|
||||
if (fam != AF_INET) continue;
|
||||
ip = READ32BE(p + 20);
|
||||
memset(req, 0, sizeof(*req));
|
||||
bzero(req, sizeof(*req));
|
||||
memcpy(req->ifr_name, p, 16);
|
||||
memcpy(&req->ifr_addr, p + 16, 16);
|
||||
req->ifr_addr.sa_family = fam;
|
||||
|
|
|
@ -34,7 +34,7 @@ textwindows int ioctl_tcgets_nt(int ignored, struct termios *tio) {
|
|||
inok = GetConsoleMode((in = g_fds.p[0].handle), &inmode);
|
||||
outok = GetConsoleMode((out = g_fds.p[1].handle), &outmode);
|
||||
if (inok | outok) {
|
||||
memset(tio, 0, sizeof(*tio));
|
||||
bzero(tio, sizeof(*tio));
|
||||
if (inok) {
|
||||
if (inmode & kNtEnableLineInput) tio->c_lflag |= ICANON;
|
||||
if (inmode & kNtEnableEchoInput) tio->c_lflag |= ECHO;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
int ioctl_tcgets_nt(int, struct termios *) hidden;
|
||||
|
||||
static int ioctl_tcgets_metal(int fd, struct termios *tio) {
|
||||
memset(tio, 0, sizeof(*tio));
|
||||
bzero(tio, sizeof(*tio));
|
||||
tio->c_iflag = TTYDEF_IFLAG;
|
||||
tio->c_oflag = TTYDEF_OFLAG;
|
||||
tio->c_lflag = TTYDEF_LFLAG;
|
||||
|
|
|
@ -38,7 +38,7 @@ textwindows int ioctl_tiocgwinsz_nt(int fd, struct winsize *ws) {
|
|||
for (i = 0; i < ARRAYLEN(fds); ++i) {
|
||||
if (__isfdkind(fds[i], kFdFile) || __isfdkind(fds[i], kFdConsole)) {
|
||||
if (GetConsoleMode(g_fds.p[fds[i]].handle, &mode)) {
|
||||
memset(&sbinfo, 0, sizeof(sbinfo));
|
||||
bzero(&sbinfo, sizeof(sbinfo));
|
||||
sbinfo.cbSize = sizeof(sbinfo);
|
||||
if (GetConsoleScreenBufferInfoEx(g_fds.p[fds[i]].handle, &sbinfo)) {
|
||||
ws->ws_col = sbinfo.srWindow.Right - sbinfo.srWindow.Left + 1;
|
||||
|
|
|
@ -31,7 +31,9 @@ bool32 isatty(int fd) {
|
|||
bool32 res;
|
||||
struct winsize ws;
|
||||
if (fd >= 0) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
if (__isfdkind(fd, kFdZip)) {
|
||||
return false;
|
||||
} else if (IsMetal()) {
|
||||
return false;
|
||||
} else if (!IsWindows()) {
|
||||
err = errno;
|
||||
|
|
|
@ -19,9 +19,19 @@
|
|||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
bool g_isrunningundermake;
|
||||
|
||||
/**
|
||||
* Returns true if current process was spawned by GNU Make.
|
||||
*/
|
||||
bool IsRunningUnderMake(void) {
|
||||
return !!getenv("MAKEFLAGS");
|
||||
return g_isrunningundermake;
|
||||
}
|
||||
|
||||
textstartup void g_isrunningundermake_init(void) {
|
||||
g_isrunningundermake = !!getenv("MAKEFLAGS");
|
||||
}
|
||||
|
||||
const void *const g_isrunningundermake_ctor[] initarray = {
|
||||
g_isrunningundermake_init,
|
||||
};
|
||||
|
|
|
@ -23,6 +23,22 @@
|
|||
#include "libc/str/utf16.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#define APPEND(c) \
|
||||
do { \
|
||||
cmdline[k++] = c; \
|
||||
if (k == ARG_MAX) return e2big(); \
|
||||
} while (0)
|
||||
|
||||
static noasan bool NeedsQuotes(const char *s) {
|
||||
if (!*s) return true;
|
||||
do {
|
||||
if (*s == ' ' || *s == '\t') {
|
||||
return true;
|
||||
}
|
||||
} while (*s++);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts System V argv to Windows-style command line.
|
||||
*
|
||||
|
@ -34,7 +50,6 @@
|
|||
* @param prog is used as argv[0]
|
||||
* @param argv is an a NULL-terminated array of UTF-8 strings
|
||||
* @return freshly allocated lpCommandLine or NULL w/ errno
|
||||
* @kudos Daniel Colascione for teaching how to quote
|
||||
* @see libc/runtime/dosargv.c
|
||||
*/
|
||||
textwindows noasan int mkntcmdline(char16_t cmdline[ARG_MAX], const char *prog,
|
||||
|
@ -43,36 +58,19 @@ textwindows noasan int mkntcmdline(char16_t cmdline[ARG_MAX], const char *prog,
|
|||
uint64_t w;
|
||||
wint_t x, y;
|
||||
int slashes, n;
|
||||
size_t i, j, k;
|
||||
bool needsquote;
|
||||
char16_t cbuf[2];
|
||||
size_t i, j, k, s;
|
||||
for (arg = prog, k = i = 0; arg; arg = argv[++i]) {
|
||||
if (i) {
|
||||
cmdline[k++] = u' ';
|
||||
if (k == ARG_MAX) return e2big();
|
||||
}
|
||||
needsquote = !arg[0] || arg[strcspn(arg, " \t\n\v\"")];
|
||||
if (needsquote) {
|
||||
cmdline[k++] = u'"';
|
||||
if (k == ARG_MAX) return e2big();
|
||||
}
|
||||
for (j = 0;;) {
|
||||
if (needsquote) {
|
||||
slashes = 0;
|
||||
while (arg[j] && arg[j] == '\\') slashes++, j++;
|
||||
slashes <<= 1;
|
||||
if (arg[j] == '"') slashes++;
|
||||
while (slashes--) {
|
||||
cmdline[k++] = u'\\';
|
||||
if (k == ARG_MAX) return e2big();
|
||||
}
|
||||
}
|
||||
x = arg[j++] & 0xff;
|
||||
if (i) APPEND(u' ');
|
||||
if ((needsquote = NeedsQuotes(arg))) APPEND(u'"');
|
||||
for (slashes = j = 0;;) {
|
||||
x = arg[j++] & 255;
|
||||
if (x >= 0300) {
|
||||
n = ThomPikeLen(x);
|
||||
x = ThomPikeByte(x);
|
||||
while (--n) {
|
||||
if ((y = arg[j++] & 0xff)) {
|
||||
if ((y = arg[j++] & 255)) {
|
||||
x = ThomPikeMerge(x, y);
|
||||
} else {
|
||||
x = 0;
|
||||
|
@ -81,16 +79,34 @@ textwindows noasan int mkntcmdline(char16_t cmdline[ARG_MAX], const char *prog,
|
|||
}
|
||||
}
|
||||
if (!x) break;
|
||||
if (!i && x == '/') x = '\\';
|
||||
w = EncodeUtf16(x);
|
||||
do {
|
||||
cmdline[k++] = w;
|
||||
if (k == ARG_MAX) return e2big();
|
||||
} while ((w >>= 16));
|
||||
if (!i && x == '/') {
|
||||
x = '\\';
|
||||
}
|
||||
if (x == '\\') {
|
||||
++slashes;
|
||||
} else if (x == '"') {
|
||||
for (s = 0; s < slashes * 2; ++s) {
|
||||
APPEND(u'\\');
|
||||
}
|
||||
slashes = 0;
|
||||
APPEND(u'\\');
|
||||
APPEND(u'"');
|
||||
} else {
|
||||
for (s = 0; s < slashes; ++s) {
|
||||
APPEND(u'\\');
|
||||
}
|
||||
slashes = 0;
|
||||
w = EncodeUtf16(x);
|
||||
do {
|
||||
APPEND(w);
|
||||
} while ((w >>= 16));
|
||||
}
|
||||
}
|
||||
for (s = 0; s < (slashes << needsquote); ++s) {
|
||||
APPEND(u'\\');
|
||||
}
|
||||
if (needsquote) {
|
||||
cmdline[k++] = u'"';
|
||||
if (k == ARG_MAX) return e2big();
|
||||
APPEND(u'"');
|
||||
}
|
||||
}
|
||||
cmdline[k] = u'\0';
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_nanosleep_nt(const struct timespec *req, struct timespec *rem) {
|
||||
textwindows int sys_nanosleep_nt(const struct timespec *req,
|
||||
struct timespec *rem) {
|
||||
int64_t millis, hectonanos, relasleep;
|
||||
if (rem) memcpy(rem, req, sizeof(*rem));
|
||||
hectonanos = req->tv_sec * 10000000ull + div100int64(req->tv_nsec);
|
||||
|
@ -38,6 +39,6 @@ textwindows int sys_nanosleep_nt(const struct timespec *req, struct timespec *re
|
|||
return eintr();
|
||||
}
|
||||
}
|
||||
if (rem) memset(rem, 0, sizeof(*rem));
|
||||
if (rem) bzero(rem, sizeof(*rem));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
|
|||
s = (void *)buffer;
|
||||
secsize = sizeof(buffer);
|
||||
privsize = sizeof(privileges);
|
||||
memset(&privileges, 0, sizeof(privileges));
|
||||
bzero(&privileges, sizeof(privileges));
|
||||
mapping.GenericRead = kNtFileGenericRead;
|
||||
mapping.GenericWrite = kNtFileGenericWrite;
|
||||
mapping.GenericExecute = kNtFileGenericExecute;
|
||||
|
|
|
@ -33,6 +33,14 @@ textwindows void ntcontext2linux(ucontext_t *ctx, const struct NtContext *cr) {
|
|||
ctx->uc_mcontext.rbp = cr->Rbp;
|
||||
ctx->uc_mcontext.rsp = cr->Rsp;
|
||||
ctx->uc_mcontext.rip = cr->Rip;
|
||||
ctx->uc_mcontext.r8 = cr->R8;
|
||||
ctx->uc_mcontext.r9 = cr->R9;
|
||||
ctx->uc_mcontext.r10 = cr->R10;
|
||||
ctx->uc_mcontext.r11 = cr->R11;
|
||||
ctx->uc_mcontext.r12 = cr->R12;
|
||||
ctx->uc_mcontext.r13 = cr->R13;
|
||||
ctx->uc_mcontext.r14 = cr->R14;
|
||||
ctx->uc_mcontext.r15 = cr->R15;
|
||||
ctx->uc_mcontext.cs = cr->SegCs;
|
||||
ctx->uc_mcontext.gs = cr->SegGs;
|
||||
ctx->uc_mcontext.fs = cr->SegFs;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ntspawn.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/nt/enum/pageflags.h"
|
||||
|
@ -69,8 +70,10 @@ textwindows int ntspawn(
|
|||
int64_t handle;
|
||||
size_t blocksize;
|
||||
struct SpawnBlock *block;
|
||||
char16_t prog16[PATH_MAX];
|
||||
rc = -1;
|
||||
block = NULL;
|
||||
if (__mkntpath(prog, prog16) == -1) return -1;
|
||||
blocksize = ROUNDUP(sizeof(*block), FRAMESIZE);
|
||||
if ((handle = CreateFileMappingNuma(
|
||||
-1,
|
||||
|
@ -83,7 +86,7 @@ textwindows int ntspawn(
|
|||
blocksize, NULL, kNtNumaNoPreferredNode))) {
|
||||
if (mkntcmdline(block->cmdline, prog, argv) != -1 &&
|
||||
mkntenvblock(block->envvars, envp, extravar) != -1) {
|
||||
if (CreateProcess(NULL, block->cmdline, opt_lpProcessAttributes,
|
||||
if (CreateProcess(prog16, block->cmdline, opt_lpProcessAttributes,
|
||||
opt_lpThreadAttributes, bInheritHandles,
|
||||
dwCreationFlags | kNtCreateUnicodeEnvironment,
|
||||
block->envvars, opt_lpCurrentDirectory, lpStartupInfo,
|
||||
|
@ -92,6 +95,7 @@ textwindows int ntspawn(
|
|||
} else {
|
||||
__winerr();
|
||||
}
|
||||
SYSDEBUG("CreateProcess(`%S`, `%S`) -> %d", prog16, block->cmdline, rc);
|
||||
}
|
||||
} else {
|
||||
__winerr();
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
textwindows struct NtOverlapped *offset2overlap(int64_t opt_offset,
|
||||
struct NtOverlapped *mem) {
|
||||
if (opt_offset == -1) return NULL;
|
||||
memset(mem, 0, sizeof(struct NtOverlapped));
|
||||
bzero(mem, sizeof(struct NtOverlapped));
|
||||
mem->Pointer = (void *)(uintptr_t)opt_offset;
|
||||
return mem;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ textwindows bool32 __onntconsoleevent(uint32_t CtrlType) {
|
|||
case (uintptr_t)SIG_IGN:
|
||||
return true;
|
||||
default:
|
||||
memset(&info, 0, sizeof(info));
|
||||
bzero(&info, sizeof(info));
|
||||
info.si_signo = sig;
|
||||
((sigaction_f)(_base + rva))(sig, &info, NULL);
|
||||
__interrupted = true;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
|
@ -32,7 +33,7 @@ int sys_openat(int dirfd, const char *file, int flags, unsigned mode) {
|
|||
* flag. Other times, it return -530 which makes no sense.
|
||||
*/
|
||||
if (!IsLinux() || !(flags & O_CLOEXEC) || modernize) {
|
||||
return __sys_openat(dirfd, file, flags, mode);
|
||||
d = __sys_openat(dirfd, file, flags, mode);
|
||||
} else if (once) {
|
||||
if ((d = __sys_openat(dirfd, file, flags & ~O_CLOEXEC, mode)) != -1) {
|
||||
e = errno;
|
||||
|
@ -54,8 +55,13 @@ int sys_openat(int dirfd, const char *file, int flags, unsigned mode) {
|
|||
once = true;
|
||||
} else if (errno > 255) {
|
||||
once = true;
|
||||
return sys_openat(dirfd, file, flags, mode);
|
||||
d = sys_openat(dirfd, file, flags, mode);
|
||||
}
|
||||
}
|
||||
if (d != -1) {
|
||||
SYSDEBUG("sys_openat(0x%x, %s, %d, %d) -> %d", dirfd, file, flags, mode, d);
|
||||
} else {
|
||||
SYSDEBUG("sys_openat(0x%x, %s, %d, %d) -> %m", dirfd, file, flags, mode);
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "libc/log/log.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ ssize_t readansi(int fd, char *p, size_t n) {
|
|||
case kCsi1:
|
||||
if (0x20 <= c && c <= 0x2f) {
|
||||
t = kCsi2;
|
||||
} else if (c == '[' && i == 3) {
|
||||
} else if (c == '[' && (i == 3 || (i == 4 && p[1] == '\e'))) {
|
||||
/* linux function keys */
|
||||
} else if (0x40 <= c && c <= 0x7e) {
|
||||
t = kDone;
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
#include "libc/str/str.h"
|
||||
|
||||
static textwindows noinline int sys_sched_setaffinity_nt(int pid,
|
||||
uint64_t bitsetsize,
|
||||
const void *bitset) {
|
||||
uint64_t bitsetsize,
|
||||
const void *bitset) {
|
||||
int rc;
|
||||
uintptr_t mask;
|
||||
int64_t handle;
|
||||
|
|
|
@ -49,12 +49,12 @@
|
|||
autotype((S2).B) b = (typeof((S2).B))(S1).B; \
|
||||
autotype((S2).C) c = (typeof((S2).C))(S1).C; \
|
||||
typeof((S2).D) d; \
|
||||
memset(&d, 0, sizeof(d)); \
|
||||
bzero(&d, sizeof(d)); \
|
||||
memcpy(&d, &((S1).D), MIN(sizeof(d), sizeof((S1).D))); \
|
||||
(S2).A = a; \
|
||||
(S2).B = b; \
|
||||
(S2).C = c; \
|
||||
memset(&((S2).D), 0, sizeof((S2).D)); \
|
||||
bzero(&((S2).D), sizeof((S2).D)); \
|
||||
memcpy(&((S2).D), &d, MIN(sizeof(d), sizeof((S2).D))); \
|
||||
} while (0);
|
||||
#endif
|
||||
|
@ -217,7 +217,7 @@ int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
|||
}
|
||||
} else {
|
||||
if (oldact) {
|
||||
memset(oldact, 0, sizeof(*oldact));
|
||||
bzero(oldact, sizeof(*oldact));
|
||||
}
|
||||
rc = 0;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,6 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int sigemptyset(sigset_t *set) {
|
||||
memset(set->__bits, 0, sizeof(set->__bits));
|
||||
bzero(set->__bits, sizeof(set->__bits));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -124,7 +124,7 @@ void __sigenter_freebsd(int sig, struct siginfo_freebsd *si,
|
|||
ucontext_t uc;
|
||||
rva = __sighandrvas[sig & (NSIG - 1)];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
memset(&uc, 0, sizeof(uc));
|
||||
bzero(&uc, sizeof(uc));
|
||||
if (ctx) {
|
||||
uc.uc_mcontext.fpregs = &uc.__fpustate;
|
||||
uc.uc_stack.ss_sp = ctx->uc_stack.ss_sp;
|
||||
|
@ -155,6 +155,7 @@ void __sigenter_freebsd(int sig, struct siginfo_freebsd *si,
|
|||
uc.uc_mcontext.gs = ctx->uc_mcontext.mc_gs;
|
||||
uc.uc_mcontext.err = ctx->uc_mcontext.mc_err;
|
||||
uc.uc_mcontext.trapno = ctx->uc_mcontext.mc_trapno;
|
||||
memcpy(&uc.__fpustate, &ctx->uc_mcontext.mc_fpstate, 512);
|
||||
}
|
||||
((sigaction_f)(_base + rva))(sig, (void *)si, &uc);
|
||||
if (ctx) {
|
||||
|
@ -186,6 +187,7 @@ void __sigenter_freebsd(int sig, struct siginfo_freebsd *si,
|
|||
ctx->uc_mcontext.mc_err = uc.uc_mcontext.err;
|
||||
ctx->uc_mcontext.mc_rip = uc.uc_mcontext.rip;
|
||||
ctx->uc_mcontext.mc_rsp = uc.uc_mcontext.rsp;
|
||||
memcpy(&ctx->uc_mcontext.mc_fpstate, &uc.__fpustate, 512);
|
||||
}
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -132,8 +132,8 @@ void __sigenter_netbsd(int sig, struct siginfo_netbsd *si,
|
|||
struct siginfo si2;
|
||||
rva = __sighandrvas[sig & (NSIG - 1)];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
memset(&uc, 0, sizeof(uc));
|
||||
memset(&si2, 0, sizeof(si2));
|
||||
bzero(&uc, sizeof(uc));
|
||||
bzero(&si2, sizeof(si2));
|
||||
if (si) {
|
||||
si2.si_signo = si->_signo;
|
||||
si2.si_code = si->_code;
|
||||
|
|
|
@ -97,8 +97,8 @@ void __sigenter_openbsd(int sig, struct siginfo_openbsd *si,
|
|||
struct siginfo si2;
|
||||
rva = __sighandrvas[sig & (NSIG - 1)];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
memset(&uc, 0, sizeof(uc));
|
||||
memset(&si2, 0, sizeof(si2));
|
||||
bzero(&uc, sizeof(uc));
|
||||
bzero(&si2, sizeof(si2));
|
||||
if (si) {
|
||||
si2.si_signo = si->si_signo;
|
||||
si2.si_code = si->si_code;
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
int sigignore(int sig) {
|
||||
struct sigaction sa;
|
||||
memset(&sa, 0, sizeof(sa));
|
||||
bzero(&sa, sizeof(sa));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
return (sigaction)(sig, &sa, 0);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ int sigqueue(int pid, int sig, const union sigval value) {
|
|||
if (IsFreebsd()) {
|
||||
return sys_sigqueue(pid, sig, value);
|
||||
} else {
|
||||
memset(&info, 0, sizeof(info));
|
||||
bzero(&info, sizeof(info));
|
||||
info.si_signo = sig;
|
||||
info.si_code = SI_QUEUE;
|
||||
info.si_pid = getpid();
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_SYSDEBUG_INTERNAL_H_
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
|
||||
#if 0
|
||||
#define SYSDEBUG(FMT, ...) (dprintf)(2, FMT "\n", ##__VA_ARGS__)
|
||||
#ifndef DEBUGSYS
|
||||
#define DEBUGSYS 0
|
||||
#endif
|
||||
|
||||
#if DEBUGSYS
|
||||
#define SYSDEBUG(FMT, ...) __printf("SYS: " FMT "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define SYSDEBUG(FMT, ...) (void)0
|
||||
#endif
|
||||
|
|
|
@ -41,7 +41,7 @@ int sysinfo(struct sysinfo *info) {
|
|||
return efault();
|
||||
}
|
||||
}
|
||||
memset(info, 0, sizeof(*info));
|
||||
bzero(info, sizeof(*info));
|
||||
if (!IsWindows()) {
|
||||
rc = sys_sysinfo(info);
|
||||
} else {
|
||||
|
|
|
@ -29,7 +29,7 @@ int uname(struct utsname *lool) {
|
|||
char *out;
|
||||
size_t i, j, len;
|
||||
char tmp[sizeof(struct utsname)];
|
||||
memset(tmp, 0, sizeof(tmp));
|
||||
bzero(tmp, sizeof(tmp));
|
||||
if (sys_uname(tmp) != -1) {
|
||||
out = (char *)lool;
|
||||
i = 0;
|
||||
|
@ -45,7 +45,7 @@ int uname(struct utsname *lool) {
|
|||
}
|
||||
return 0;
|
||||
} else {
|
||||
memset(lool, 0, sizeof(struct utsname));
|
||||
bzero(lool, sizeof(struct utsname));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,12 +20,11 @@
|
|||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
* Deletes file.
|
||||
* Removes file.
|
||||
*
|
||||
* Please note the deletion process has different interesting properties
|
||||
* on each platform. For example, on System V, if open descriptors exist
|
||||
* then only the name of the file is removed and it's actually deleted
|
||||
* later on when appropriate.
|
||||
* This may be used to delete files but it can't be used to delete
|
||||
* directories. The exception are symlinks, which this will delete
|
||||
* however not the linked directory.
|
||||
*
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
|
|
|
@ -18,17 +18,29 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/io.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/win32fileattributedata.h"
|
||||
#include "libc/nt/struct/win32finddata.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
static textwindows int sys_unlink_nt(const char16_t *path) {
|
||||
if (DeleteFile(path)) {
|
||||
return 0;
|
||||
static textwindows bool IsDirectorySymlink(const char16_t *path) {
|
||||
int64_t h;
|
||||
struct NtWin32FindData data;
|
||||
struct NtWin32FileAttributeData info;
|
||||
if (GetFileAttributesEx(path, 0, &info) &&
|
||||
((info.dwFileAttributes & kNtFileAttributeDirectory) &&
|
||||
(info.dwFileAttributes & kNtFileAttributeReparsePoint)) &&
|
||||
(h = FindFirstFile(path, &data)) != -1) {
|
||||
FindClose(h);
|
||||
return data.dwReserved0 == kNtIoReparseTagSymlink ||
|
||||
data.dwReserved0 == kNtIoReparseTagMountPoint;
|
||||
} else {
|
||||
return __winerr();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +66,11 @@ static textwindows int sys_rmdir_nt(const char16_t *path) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static textwindows int sys_unlink_nt(const char16_t *path) {
|
||||
if (IsDirectorySymlink(path)) return sys_rmdir_nt(path);
|
||||
return DeleteFile(path) ? 0 : __winerr();
|
||||
}
|
||||
|
||||
textwindows int sys_unlinkat_nt(int dirfd, const char *path, int flags) {
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
|
|
|
@ -84,7 +84,7 @@ textwindows int sys_wait4_nt(int pid, int *opt_out_wstatus, int options,
|
|||
*opt_out_wstatus = (dwExitCode & 0xff) << 8;
|
||||
}
|
||||
if (opt_out_rusage) {
|
||||
memset(opt_out_rusage, 0, sizeof(*opt_out_rusage));
|
||||
bzero(opt_out_rusage, sizeof(*opt_out_rusage));
|
||||
if (GetProcessTimes(g_fds.p[pids[i]].handle, &createfiletime,
|
||||
&exitfiletime, &kernelfiletime, &userfiletime)) {
|
||||
opt_out_rusage->ru_utime =
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sysdebug.internal.h"
|
||||
#include "libc/calls/wait4.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
|
@ -37,6 +38,7 @@
|
|||
*/
|
||||
int wait4(int pid, int *opt_out_wstatus, int options,
|
||||
struct rusage *opt_out_rusage) {
|
||||
int rc, ws;
|
||||
if (IsAsan() &&
|
||||
((opt_out_wstatus &&
|
||||
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) ||
|
||||
|
@ -44,9 +46,13 @@ int wait4(int pid, int *opt_out_wstatus, int options,
|
|||
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))))) {
|
||||
return efault();
|
||||
}
|
||||
ws = 0;
|
||||
if (!IsWindows()) {
|
||||
return sys_wait4(pid, opt_out_wstatus, options, opt_out_rusage);
|
||||
rc = sys_wait4(pid, &ws, options, opt_out_rusage);
|
||||
} else {
|
||||
return sys_wait4_nt(pid, opt_out_wstatus, 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 (opt_out_wstatus) *opt_out_wstatus = ws;
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ void __winalarm(void *lpArgToCompletionRoutine, uint32_t dwTimerLowValue,
|
|||
uint32_t dwTimerHighValue) {
|
||||
int rva;
|
||||
siginfo_t info;
|
||||
memset(&info, 0, sizeof(info));
|
||||
bzero(&info, sizeof(info));
|
||||
info.si_signo = SIGALRM;
|
||||
rva = __sighandrvas[SIGALRM];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
|
|
|
@ -70,7 +70,7 @@ textwindows unsigned __wincrash(struct NtExceptionPointers *ep) {
|
|||
default:
|
||||
return kNtExceptionContinueSearch;
|
||||
}
|
||||
memset(&g, 0, sizeof(g));
|
||||
bzero(&g, sizeof(g));
|
||||
rva = __sighandrvas[sig];
|
||||
if (rva >= kSigactionMinRva) {
|
||||
ntcontext2linux(&g.ctx, ep->ContextRecord);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue