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:
Justine Tunney 2021-09-27 22:58:51 -07:00
parent fa7b4f5bd1
commit 39bf41f4eb
806 changed files with 77494 additions and 63859 deletions

View file

@ -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 &&

View file

@ -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

View file

@ -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;
}

View file

@ -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;

View file

@ -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()) {

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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
View 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();
}

View file

@ -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`

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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),

View file

@ -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)) {

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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,
};

View file

@ -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';

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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"

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}
/*

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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();

View file

@ -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

View file

@ -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 {

View file

@ -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;
}
}

View file

@ -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

View file

@ -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;

View file

@ -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 =

View file

@ -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;
}

View file

@ -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) {

View file

@ -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);