diff --git a/ape/ape.S b/ape/ape.S index 5b4e74dd..d8fff87e 100644 --- a/ape/ape.S +++ b/ape/ape.S @@ -225,9 +225,14 @@ pc: cld 3: call pcread dec %di jnz 3b -6: mov %ax,XLM(LOADSTATE)+0 - mov %cx,XLM(LOADSTATE)+2 - mov %dx,XLM(LOADSTATE)+4 +6: mov $XLM(LOADSTATE),%di # ax,cx,dx,es + stosw + xchg %cx,%ax + stosw + xchg %dx,%ax + stosw + mov %es,%ax + stosw ljmp $0,$REAL(realmodeloader) .endfn pc,globl,hidden diff --git a/ape/config.h b/ape/config.h index f51cc072..2451203a 100644 --- a/ape/config.h +++ b/ape/config.h @@ -126,7 +126,7 @@ #define XLM_BADIDT 0x2230 #define XLM_BADIDT_SIZE 6 #define XLM_LOADSTATE 0x2240 -#define XLM_LOADSTATE_SIZE 6 +#define XLM_LOADSTATE_SIZE 8 #define XLM_SIZE ROUNDUP(XLM_LOADSTATE + XLM_LOADSTATE_SIZE, 0x1000) #define IMAGE_BASE_REAL (XLM_BASE_REAL + XLM_SIZE) diff --git a/build/compile b/build/compile index b97e36f5..197518fc 100755 --- a/build/compile +++ b/build/compile @@ -280,5 +280,5 @@ if "$@"; then exit 0 fi -printf "$LOGFMT" "$CCNAME $CCVERSION: compile $REASON:" "$*" >&2 +printf "\n$LOGFMT" "$CCNAME $CCVERSION: compile $REASON:" "$*" >&2 exit 1 diff --git a/dsp/core/core.mk b/dsp/core/core.mk index a3ea303e..151829f9 100644 --- a/dsp/core/core.mk +++ b/dsp/core/core.mk @@ -58,11 +58,11 @@ o/$(MODE)/dsp/core/det3.o: \ OVERRIDE_CFLAGS += \ -ffast-math -ifeq (,$(MODE)) -$(DSP_CORE_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif +# ifeq (,$(MODE)) +# $(DSP_CORE_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif DSP_CORE_LIBS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x))) DSP_CORE_SRCS = $(foreach x,$(DSP_CORE_ARTIFACTS),$($(x)_SRCS)) diff --git a/dsp/tty/tty.mk b/dsp/tty/tty.mk index 85344fa6..d237c3d2 100644 --- a/dsp/tty/tty.mk +++ b/dsp/tty/tty.mk @@ -59,11 +59,11 @@ o/$(MODE)/dsp/tty/ttyraster.o: \ OVERRIDE_CFLAGS += \ $(MATHEMATICAL) -ifeq (,$(MODE)) -$(DSP_TTY_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif +# ifeq (,$(MODE)) +# $(DSP_TTY_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif DSP_TTY_LIBS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x))) DSP_TTY_SRCS = $(foreach x,$(DSP_TTY_ARTIFACTS),$($(x)_SRCS)) diff --git a/examples/forkrand.c b/examples/forkrand.c index 725e7d81..a6d810dc 100644 --- a/examples/forkrand.c +++ b/examples/forkrand.c @@ -7,18 +7,20 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif +#include "libc/calls/calls.h" +#include "libc/log/check.h" #include "libc/log/log.h" #include "libc/nt/nt/process.h" #include "libc/rand/rand.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" -#include "libc/calls/calls.h" #include "libc/time/time.h" noinline void dostuff(void) { + int i, us; srand(rand64()); /* seeds rand() w/ intel rdrnd, auxv, etc. */ - for (unsigned i = 0; i < 5; ++i) { - int us = rand() % 500000; + for (i = 0; i < 5; ++i) { + us = rand() % 500000; usleep(us); printf("%s%u%s%u [%s=%d]\n", "hello no. ", i, " from ", getpid(), "us", us); fflush(stdout); @@ -26,9 +28,8 @@ noinline void dostuff(void) { } int main(int argc, char *argv[]) { - fprintf(stderr, "%p\n", RtlCloneUserProcess); - int child; - if ((child = fork()) == -1) perror("fork"), exit(1); + int rc, child, wstatus; + CHECK_NE(-1, (child = fork())); if (!child) { /* child process */ dostuff(); @@ -37,8 +38,7 @@ int main(int argc, char *argv[]) { /* parent process */ dostuff(); /* note: abandoned children become zombies */ - int rc, wstatus; - if ((rc = wait(&wstatus)) == -1) perror("wait"), exit(1); + CHECK_NE(-1, (rc = wait(&wstatus))); return WEXITSTATUS(wstatus); } } diff --git a/examples/forky.c b/examples/forky.c deleted file mode 100644 index 7863f5c0..00000000 --- a/examples/forky.c +++ /dev/null @@ -1,51 +0,0 @@ -#if 0 -/*─────────────────────────────────────────────────────────────────╗ -│ To the extent possible under law, Justine Tunney has waived │ -│ all copyright and related or neighboring rights to this file, │ -│ as it is written in the following disclaimers: │ -│ • http://unlicense.org/ │ -│ • http://creativecommons.org/publicdomain/zero/1.0/ │ -╚─────────────────────────────────────────────────────────────────*/ -#endif -#include "libc/calls/calls.h" -#include "libc/calls/hefty/spawn.h" -#include "libc/calls/internal.h" -#include "libc/conv/conv.h" -#include "libc/log/check.h" -#include "libc/mem/mem.h" -#include "libc/nt/enum/filemapflags.h" -#include "libc/nt/enum/pageflags.h" -#include "libc/nt/memory.h" -#include "libc/runtime/gc.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/fileno.h" -#include "libc/x/x.h" - -int main(int argc, char *argv[]) { - int pid; - long *addr; - int64_t fh; - if (argc == 1) { - fh = CreateFileMappingNuma(-1, &kNtIsInheritable, kNtPageReadwrite, 0, - FRAMESIZE, NULL, kNtNumaNoPreferredNode); - addr = MapViewOfFileExNuma(fh, kNtFileMapRead | kNtFileMapWrite, 0, 0, - FRAMESIZE, NULL, kNtNumaNoPreferredNode); - *addr = 0x31337; - CHECK_NE(-1, (pid = spawnve( - 0, (int[3]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO}, - "o/examples/forky.com", - (char *const[]){"o/examples/forky.com", - gc(xasprintf("%#lx", (intptr_t)addr)), - gc(xasprintf("%#lx", fh)), NULL}, - environ))); - CHECK_NE(-1, waitpid(pid, NULL, 0)); - } else { - addr = (long *)(intptr_t)strtoul(argv[1], NULL, 0); - fh = strtoul(argv[2], NULL, 0); - addr = MapViewOfFileExNuma(fh, kNtFileMapRead | kNtFileMapWrite, 0, 0, - FRAMESIZE, addr, kNtNumaNoPreferredNode); - printf("%#lx\n", *addr); - } - return 0; -} diff --git a/examples/hello.c b/examples/hello.c index 0a367ca1..90d952c7 100644 --- a/examples/hello.c +++ b/examples/hello.c @@ -7,8 +7,6 @@ │ • http://creativecommons.org/publicdomain/zero/1.0/ │ ╚─────────────────────────────────────────────────────────────────*/ #endif -#include "libc/errno.h" -#include "libc/log/log.h" #include "libc/stdio/stdio.h" int main() { diff --git a/libc/calls/commandv.c b/libc/calls/commandv.c index 578e7a5f..4b6cfab4 100644 --- a/libc/calls/commandv.c +++ b/libc/calls/commandv.c @@ -24,6 +24,7 @@ #include "libc/dce.h" #include "libc/errno.h" #include "libc/nt/ntdll.h" +#include "libc/runtime/missioncritical.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/ok.h" @@ -32,7 +33,7 @@ static int accessexe(char pathname[hasatleast PATH_MAX], size_t len, const char *ext) { len = stpcpy(&pathname[len], ext) - &pathname[0]; - if (access(pathname, X_OK) != -1) { + if (isexecutable(pathname)) { return len; } else { return -1; @@ -48,7 +49,7 @@ static int accesscmd(char pathname[hasatleast PATH_MAX], const char *path, pathlen = strlen(path); if (pathlen + 1 + namelen + 1 + 4 + 1 > PATH_MAX) return -1; p = mempcpy(pathname, path, pathlen); - if (pathlen) *p++ = '/'; + if (pathlen && pathname[pathlen - 1] != '/') *p++ = '/'; p = mempcpy(p, name, namelen); len = p - &pathname[0]; hasdot = !!memchr(basename(name), '.', namelen); diff --git a/libc/calls/dup-nt.c b/libc/calls/dup-nt.c index c7fbbf6f..14f7fe42 100644 --- a/libc/calls/dup-nt.c +++ b/libc/calls/dup-nt.c @@ -44,7 +44,7 @@ textwindows int dup$nt(int oldfd, int newfd, int flags) { } if (DuplicateHandle(GetCurrentProcess(), g_fds.p[oldfd].handle, GetCurrentProcess(), &g_fds.p[newfd].handle, 0, - (flags & O_CLOEXEC), kNtDuplicateSameAccess)) { + flags & O_CLOEXEC, kNtDuplicateSameAccess)) { g_fds.p[newfd].kind = g_fds.p[oldfd].kind; g_fds.p[newfd].flags = flags; return newfd; diff --git a/libc/calls/hefty/dirstream.c b/libc/calls/hefty/dirstream.c index 57f46f15..845993b5 100644 --- a/libc/calls/hefty/dirstream.c +++ b/libc/calls/hefty/dirstream.c @@ -134,7 +134,7 @@ DIR *opendir(const char *name) { DIR *res; if (!IsWindows() && !IsXnu()) { res = NULL; - if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC, 0)) != -1) { + if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC)) != -1) { if (!(res = fdopendir(fd))) close(fd); } return res; diff --git a/libc/calls/hefty/fork-nt.c b/libc/calls/hefty/fork-nt.c new file mode 100644 index 00000000..5fd8faf7 --- /dev/null +++ b/libc/calls/hefty/fork-nt.c @@ -0,0 +1,158 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/calls.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/calls/internal.h" +#include "libc/conv/itoa.h" +#include "libc/nt/enum/filemapflags.h" +#include "libc/nt/enum/pageflags.h" +#include "libc/nt/ipc.h" +#include "libc/nt/memory.h" +#include "libc/nt/process.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/memtrack.h" +#include "libc/runtime/missioncritical.h" +#include "libc/runtime/runtime.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" +#include "libc/sysv/errfuns.h" + +static textwindows int64_t ParseInt(char16_t **p) { + uint64_t x = 0; + while ('0' <= **p && **p <= '9') { + x *= 10; + x += *(*p)++ - '0'; + } + return x; +} + +static textwindows void WriteAll(int64_t h, void *buf, size_t n) { + char *p; + size_t i; + uint32_t wrote; + for (p = buf, i = 0; i < n; i += wrote) { + WriteFile(h, p + i, n - i, &wrote, NULL); + } +} + +static textwindows void ReadAll(int64_t h, void *buf, size_t n) { + char *p; + size_t i; + uint32_t got; + for (p = buf, i = 0; i < n; i += got) { + ReadFile(h, p + i, n - i, &got, NULL); + } +} + +textwindows void WinMainForked(void) { + int64_t h; + void *addr; + jmp_buf jb; + char16_t *p; + uint64_t size; + char16_t var[21 + 1 + 21 + 1]; + uint32_t i, varlen, protect, access; + varlen = GetEnvironmentVariable(u"_FORK", var, ARRAYLEN(var)); + if (!varlen || varlen >= ARRAYLEN(var)) return; + p = var; + h = ParseInt(&p); + if (*p++ == ' ') CloseHandle(ParseInt(&p)); + ReadAll(h, jb, sizeof(jb)); + ReadAll(h, &_mmi.i, sizeof(_mmi.i)); + for (i = 0; i < _mmi.i; ++i) { + ReadAll(h, &_mmi.p[i], sizeof(_mmi.p[i])); + addr = (void *)((uint64_t)_mmi.p[i].x << 16); + size = ((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE; + switch (_mmi.p[i].prot) { + case PROT_READ | PROT_WRITE | PROT_EXEC: + protect = kNtPageExecuteReadwrite; + access = kNtFileMapRead | kNtFileMapWrite | kNtFileMapExecute; + break; + case PROT_READ | PROT_WRITE: + protect = kNtPageReadwrite; + access = kNtFileMapRead | kNtFileMapWrite; + break; + case PROT_READ: + protect = kNtPageReadonly; + access = kNtFileMapRead; + break; + default: + protect = kNtPageNoaccess; + access = 0; + break; + } + if (_mmi.p[i].flags & MAP_PRIVATE) { + MapViewOfFileExNuma( + (_mmi.p[i].h = CreateFileMappingNuma(-1, NULL, protect, 0, size, NULL, + kNtNumaNoPreferredNode)), + access, 0, 0, size, addr, kNtNumaNoPreferredNode); + ReadAll(h, addr, size); + } else { + MapViewOfFileExNuma(_mmi.p[i].h, access, 0, 0, size, addr, + kNtNumaNoPreferredNode); + } + } + ReadAll(h, _edata, _end - _edata); + CloseHandle(h); + longjmp(jb, 1); +} + +textwindows int fork$nt(void) { + jmp_buf jb; + int64_t reader, writer; + int i, rc, pid, fds[3]; + char *p, buf[21 + 1 + 21 + 1]; + if (!setjmp(jb)) { + if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) { + p = buf; + p += uint64toarray_radix10(reader, p); + *p++ = ' '; + p += uint64toarray_radix10(writer, p); + setenv("_FORK", buf, true); + fds[0] = 0; + fds[1] = 1; + fds[2] = 2; + /* TODO: CloseHandle(g_fds.p[pid].h) if SIGCHLD is SIG_IGN */ + if ((pid = spawnve(0, fds, g_argv[0], g_argv, environ)) != -1) { + CloseHandle(reader); + WriteAll(writer, jb, sizeof(jb)); + WriteAll(writer, &_mmi.i, sizeof(_mmi.i)); + for (i = 0; i < _mmi.i; ++i) { + WriteAll(writer, &_mmi.p[i], sizeof(_mmi.p[i])); + if (_mmi.p[i].flags & MAP_PRIVATE) { + WriteAll(writer, (void *)((uint64_t)_mmi.p[i].x << 16), + ((uint64_t)(_mmi.p[i].y - _mmi.p[i].x) << 16) + FRAMESIZE); + } + } + WriteAll(writer, _edata, _end - _edata); + CloseHandle(writer); + rc = pid; + } else { + rc = -1; + } + unsetenv("_FORK"); + } else { + rc = winerr(); + } + } else { + rc = 0; + } + return rc; +} diff --git a/libc/calls/fork.c b/libc/calls/hefty/fork.c similarity index 94% rename from libc/calls/fork.c rename to libc/calls/hefty/fork.c index f6c9bbe5..49f4043d 100644 --- a/libc/calls/fork.c +++ b/libc/calls/hefty/fork.c @@ -20,6 +20,7 @@ #include "libc/bits/bits.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/dce.h" /** * Creates new process zygote style. @@ -29,7 +30,13 @@ */ int fork(void) { int rc; - rc = fork$sysv(); - if (rc == 0) __onfork(); + if (!IsWindows()) { + rc = fork$sysv(); + } else { + rc = fork$nt(); + } + if (rc == 0) { + __onfork(); + } return rc; } diff --git a/libc/calls/hefty/ntspawn.c b/libc/calls/hefty/ntspawn.c index 1d2fc456..ae315c0c 100644 --- a/libc/calls/hefty/ntspawn.c +++ b/libc/calls/hefty/ntspawn.c @@ -25,8 +25,10 @@ #include "libc/calls/hefty/ntspawn.h" #include "libc/calls/internal.h" #include "libc/conv/conv.h" +#include "libc/nt/enum/processcreationflags.h" #include "libc/nt/process.h" #include "libc/nt/runtime.h" +#include "libc/runtime/missioncritical.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/fileno.h" diff --git a/libc/calls/hefty/spawnlp.c b/libc/calls/hefty/spawnlp.c index c7112cef..04502e1a 100644 --- a/libc/calls/hefty/spawnlp.c +++ b/libc/calls/hefty/spawnlp.c @@ -21,6 +21,7 @@ #include "libc/calls/hefty/mkvarargv.h" #include "libc/calls/hefty/spawn.h" #include "libc/mem/mem.h" +#include "libc/runtime/missioncritical.h" #include "libc/runtime/runtime.h" /** diff --git a/libc/calls/hefty/spawnve-nt.c b/libc/calls/hefty/spawnve-nt.c index 26a500ca..5cedbbce 100644 --- a/libc/calls/hefty/spawnve-nt.c +++ b/libc/calls/hefty/spawnve-nt.c @@ -67,7 +67,7 @@ textwindows int spawnve$nt(unsigned flags, int stdiofds[3], const char *program, } if (handle != -1 && - ntspawn(program, argv, envp, NULL, NULL, + ntspawn(program, argv, envp, &kNtIsInheritable, NULL, (flags & SPAWN_TABULARASA) ? false : true, (flags & SPAWN_DETACH) ? (kNtCreateNewProcessGroup | kNtDetachedProcess | @@ -83,7 +83,7 @@ textwindows int spawnve$nt(unsigned flags, int stdiofds[3], const char *program, if (handle != -1) { stdiofds[i] = tubes[i]; g_fds.p[tubes[i]].kind = kFdFile; - g_fds.p[tubes[i]].flags = O_CLOEXEC; + g_fds.p[tubes[i]].flags = 0; CloseHandle(sti.stdiofds[i]); } else { CloseHandle(tubes[i]); diff --git a/libc/sysv/vfork.S b/libc/calls/hefty/vfork.S similarity index 97% rename from libc/sysv/vfork.S rename to libc/calls/hefty/vfork.S index d44d2631..b0dd7556 100644 --- a/libc/sysv/vfork.S +++ b/libc/calls/hefty/vfork.S @@ -27,7 +27,9 @@ / / @return pid of child process or 0 if forked process / @returnstwice -vfork: mov __NR_vfork(%rip),%eax +vfork: testb IsWindows() + jnz fork$nt + mov __NR_vfork(%rip),%eax cmp $-1,%eax je systemfive.enosys pop %rsi diff --git a/libc/calls/internal.h b/libc/calls/internal.h index ce52ae9b..39c308d6 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -56,11 +56,11 @@ struct Fds { extern const struct Fd kEmptyFd; -extern int g_sighandrvas[NSIG] hidden; -extern struct Fds g_fds hidden; -extern struct NtSystemInfo g_ntsysteminfo hidden; -extern struct NtStartupInfo g_ntstartupinfo hidden; -extern const struct NtSecurityAttributes kNtIsInheritable hidden; +hidden extern int g_sighandrvas[NSIG]; +hidden extern struct Fds g_fds; +hidden extern struct NtSystemInfo g_ntsysteminfo; +hidden extern struct NtStartupInfo g_ntstartupinfo; +hidden extern const struct NtSecurityAttributes kNtIsInheritable; ssize_t createfd(void) hidden; int growfds(void) hidden; @@ -218,6 +218,7 @@ void xnutrampoline(void *, i32, i32, const struct __darwin_siginfo *, int gettimeofday$nt(struct timeval *, struct timezone *) hidden; bool32 isatty$nt(int) hidden; char *getcwd$nt(char *, size_t) hidden; +int fork$nt(void) hidden; int chdir$nt(const char *) hidden; int close$nt(int) hidden; int dup$nt(int, int, int) hidden; @@ -258,6 +259,7 @@ int nanosleep$nt(const struct timespec *, struct timespec *) hidden; │ cosmopolitan § syscalls » windows nt » support ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ +void WinMainForked(void) hidden; int getsetpriority$nt(int, unsigned, int, int (*)(int)); void ntcontext2linux(struct ucontext *, const struct NtContext *) hidden; struct NtOverlapped *offset2overlap(int64_t, struct NtOverlapped *) hidden; diff --git a/libc/calls/wait.c b/libc/calls/wait.c index 0d62216b..dc4ce86a 100644 --- a/libc/calls/wait.c +++ b/libc/calls/wait.c @@ -18,9 +18,6 @@ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/dce.h" -#include "libc/sysv/errfuns.h" /** * Waits for status to change on any child process. @@ -31,9 +28,5 @@ * @asyncsignalsafe */ int wait(int *opt_out_wstatus) { - if (!IsWindows()) { - return wait4$sysv(-1, opt_out_wstatus, 0, NULL); - } else { - return enosys(); /* TODO(jart) */ - } + return wait4(-1, opt_out_wstatus, 0, NULL); } diff --git a/libc/calls/wait4-nt.c b/libc/calls/wait4-nt.c index cfa94ed1..e7fbaace 100644 --- a/libc/calls/wait4-nt.c +++ b/libc/calls/wait4-nt.c @@ -21,11 +21,14 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/rusage.h" #include "libc/conv/conv.h" +#include "libc/macros.h" #include "libc/nt/accounting.h" #include "libc/nt/enum/status.h" +#include "libc/nt/enum/wait.h" #include "libc/nt/runtime.h" #include "libc/nt/struct/filetime.h" #include "libc/nt/synchronization.h" +#include "libc/runtime/missioncritical.h" #include "libc/runtime/runtime.h" #include "libc/str/str.h" #include "libc/sysv/consts/w.h" @@ -33,34 +36,51 @@ textwindows int wait4$nt(int pid, int *opt_out_wstatus, int options, struct rusage *opt_out_rusage) { + int pids[64]; + int64_t handles[64]; uint32_t dwExitCode; + uint32_t i, count, timeout; struct NtFileTime createfiletime, exitfiletime, kernelfiletime, userfiletime; - if (!isfdkind(pid, kFdProcess)) return esrch(); - for (;;) { - dwExitCode = kNtStillActive; - if (!(options & WNOHANG)) { - WaitForSingleObject(g_fds.p[pid].handle, 0xffffffff); + if (pid != -1) { + if (!isfdkind(pid, kFdProcess)) { + return echild(); } - if (GetExitCodeProcess(g_fds.p[pid].handle, &dwExitCode)) { - if (dwExitCode != kNtStillActive) { - if (opt_out_wstatus) { /* @see WEXITSTATUS() */ - *opt_out_wstatus = (dwExitCode & 0xff) << 8; - } - if (opt_out_rusage) { - memset(opt_out_rusage, 0, sizeof(*opt_out_rusage)); - GetProcessTimes(GetCurrentProcess(), &createfiletime, &exitfiletime, - &kernelfiletime, &userfiletime); - FileTimeToTimeVal(&opt_out_rusage->ru_utime, userfiletime); - FileTimeToTimeVal(&opt_out_rusage->ru_stime, kernelfiletime); - } - return pid; - } else if (options & WNOHANG) { - return pid; - } else { - continue; + handles[0] = g_fds.p[pid].handle; + pids[0] = pid; + count = 1; + } else { + for (count = 0, i = g_fds.n; i--;) { + if (g_fds.p[i].kind == kFdProcess) { + pids[count] = i; + handles[count] = g_fds.p[i].handle; + if (++count == ARRAYLEN(handles)) break; } - } else { - return winerr(); + } + if (!count) { + return echild(); } } + for (;;) { + dwExitCode = kNtStillActive; + if (options & WNOHANG) { + i = WaitForMultipleObjects(count, handles, false, 0); + if (i == kNtWaitTimeout) return 0; + } else { + i = WaitForMultipleObjects(count, handles, false, -1); + } + if (i == kNtWaitFailed) return winerr(); + if (!GetExitCodeProcess(handles[i], &dwExitCode)) return winerr(); + if (dwExitCode == kNtStillActive) continue; + if (opt_out_wstatus) { /* @see WEXITSTATUS() */ + *opt_out_wstatus = (dwExitCode & 0xff) << 8; + } + if (opt_out_rusage) { + memset(opt_out_rusage, 0, sizeof(*opt_out_rusage)); + GetProcessTimes(GetCurrentProcess(), &createfiletime, &exitfiletime, + &kernelfiletime, &userfiletime); + FileTimeToTimeVal(&opt_out_rusage->ru_utime, userfiletime); + FileTimeToTimeVal(&opt_out_rusage->ru_stime, kernelfiletime); + } + return pids[i]; + } } diff --git a/libc/calls/zygote.c b/libc/calls/zygote.c index 600fd431..657c57a5 100644 --- a/libc/calls/zygote.c +++ b/libc/calls/zygote.c @@ -17,8 +17,11 @@ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/nt/struct/securityattributes.h" #include "libc/calls/internal.h" +#include "libc/nt/struct/securityattributes.h" const struct NtSecurityAttributes kNtIsInheritable = { - sizeof(struct NtSecurityAttributes), NULL, true}; + sizeof(struct NtSecurityAttributes), + NULL, + true, +}; diff --git a/libc/isystem/windows.h b/libc/isystem/windows.h index 2219bd37..8d14c7ba 100644 --- a/libc/isystem/windows.h +++ b/libc/isystem/windows.h @@ -69,9 +69,9 @@ #define PINT_PTR intptr_t* #define UINT_PTR uintptr_t #define PUINT_PTR uintptr_t* -#define LONG_PTR int32_t* +#define LONG_PTR intptr_t #define PLONG_PTR int32_t** -#define ULONG_PTR uint32_t* +#define ULONG_PTR uintptr_t #define PULONG_PTR uint32_t** #define POINTER_64_INT int64_t* #define __int3264 int64_t diff --git a/libc/libc.mk b/libc/libc.mk index f02d30dc..fb86662a 100644 --- a/libc/libc.mk +++ b/libc/libc.mk @@ -15,7 +15,6 @@ o/$(MODE)/libc: o/$(MODE)/libc/alg \ o/$(MODE)/libc/crt \ o/$(MODE)/libc/dns \ o/$(MODE)/libc/elf \ - o/$(MODE)/libc/escape \ o/$(MODE)/libc/fmt \ o/$(MODE)/libc/intrin \ o/$(MODE)/libc/linux \ diff --git a/libc/log/asan.c b/libc/log/asan.c index 66e11526..cf70367e 100644 --- a/libc/log/asan.c +++ b/libc/log/asan.c @@ -401,7 +401,8 @@ void __asan_map_shadow(void *p, size_t n) { PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); if (sm.addr == MAP_FAILED || - TrackMemoryInterval(&_mmi, a, a, sm.maphandle) == -1) { + TrackMemoryInterval(&_mmi, a, a, sm.maphandle, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED) == -1) { abort(); } } diff --git a/libc/log/log.mk b/libc/log/log.mk index 5864b411..86ea8fdf 100644 --- a/libc/log/log.mk +++ b/libc/log/log.mk @@ -64,9 +64,9 @@ $(LIBC_LOG_A_OBJS): \ $(NO_MAGIC) \ -fwrapv -ifeq (,$(MODE)) -LIBC_LOG_ASAN = o/$(MODE)/libc/log/asan.o -endif +# ifeq (,$(MODE)) +# LIBC_LOG_ASAN = o/$(MODE)/libc/log/asan.o +# endif LIBC_LOG_ASAN_A = o/$(MODE)/libc/log/log.a LIBC_LOG_LIBS = $(foreach x,$(LIBC_LOG_ARTIFACTS),$($(x))) diff --git a/libc/mem/putenv.c b/libc/mem/putenv.c index f6d79f0b..98135047 100644 --- a/libc/mem/putenv.c +++ b/libc/mem/putenv.c @@ -24,53 +24,49 @@ #include "libc/str/str.h" #include "libc/sysv/errfuns.h" -static size_t g_environcap; +#define MAX_VARS 512 -int PutEnvImpl(char *string, bool overwrite) { - if (!environ) { - g_environcap = 0; - if ((environ = calloc(8, sizeof(char *)))) { - g_environcap = 8; - } - } - char *equalp = strchr(string, '='); - if (!equalp) return einval(); - unsigned namelen = equalp + 1 - string; - unsigned i; +int PutEnvImpl(char *s, bool overwrite) { + char *p; + unsigned i, namelen; + p = strchr(s, '='); + if (!p) goto fail; + namelen = p + 1 - s; for (i = 0; environ[i]; ++i) { - if (strncmp(environ[i], string, namelen) == 0) { + if (strncmp(environ[i], s, namelen) == 0) { if (!overwrite) { - free_s(&string); + free(s); return 0; } goto replace; } } - if (i + 1 >= g_environcap) { - if (!g_environcap) g_environcap = i + 1; - if (!grow(&environ, &g_environcap, sizeof(char *), 0)) { - free_s(&string); - return -1; - } - } + if (i + 1 >= MAX_VARS) goto fail; environ[i + 1] = NULL; replace: - free_s(&environ[i]); - environ[i] = string; + free(environ[i]); + environ[i] = s; return 0; +fail: + free(s); + return einval(); } /** * Emplaces environment key=value. * @see setenv(), getenv() */ -int putenv(char *string) { return PutEnvImpl(string, true); } - -textexit static void putenv_fini(void) { - for (char **envp = environ; *envp; ++envp) free_s(envp); - free_s(&environ); +int putenv(char *string) { + return PutEnvImpl(strdup(string), true); } -textstartup static void putenv_init(void) { atexit(putenv_fini); } +textstartup static void putenv_init(void) { + char **pin, **pout; + pin = environ; + pout = malloc(sizeof(char *) * MAX_VARS); + environ = pout; + while (*pin) *pout++ = strdup(*pin++); + *pout = NULL; +} const void *const putenv_ctor[] initarray = {putenv_init}; diff --git a/libc/nt/dll.h b/libc/nt/dll.h index 50ebea45..b0e19425 100644 --- a/libc/nt/dll.h +++ b/libc/nt/dll.h @@ -34,8 +34,8 @@ int64_t LoadLibraryEx(const char16_t *lpLibFileName, int64_t hFile, uint32_t dwFlags); uint32_t GetModuleFileName(int64_t hModule, char16_t *lpFilename, uint32_t nSize); -intptr_t GetModuleHandle(const char *lpModuleName); -intptr_t GetModuleHandleW(const char16_t *lpModuleName); +intptr_t GetModuleHandle(const char *opt_lpModuleName); +intptr_t GetModuleHandleW(const char16_t *opt_lpModuleName); void *GetProcAddress(int64_t hModule, const char *lpProcName); int32_t FreeResource(int64_t hResData); intptr_t LockResource(int64_t hResData); diff --git a/libc/nt/enum/color.h b/libc/nt/enum/color.h new file mode 100644 index 00000000..2d27ad3c --- /dev/null +++ b/libc/nt/enum/color.h @@ -0,0 +1,35 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_COLOR_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_COLOR_H_ + +#define kNtColorScrollbar 0 +#define kNtColorBackground 1 +#define kNtColorActivecaption 2 +#define kNtColorInactivecaption 3 +#define kNtColorMenu 4 +#define kNtColorWindow 5 +#define kNtColorWindowframe 6 +#define kNtColorMenutext 7 +#define kNtColorWindowtext 8 +#define kNtColorCaptiontext 9 +#define kNtColorActiveborder 10 +#define kNtColorInactiveborder 11 +#define kNtColorAppworkspace 12 +#define kNtColorHighlight 13 +#define kNtColorHighlighttext 14 +#define kNtColorBtnface 15 +#define kNtColorBtnshadow 16 +#define kNtColorGraytext 17 +#define kNtColorBtntext 18 +#define kNtColorInactivecaptiontext 19 +#define kNtColorBtnhighlight 20 +#define kNtColor3ddkshadow 21 +#define kNtColor3dlight 22 +#define kNtColorInfotext 23 +#define kNtColorInfobk 24 +#define kNtColorHotlight 26 +#define kNtColorGradientactivecaption 27 +#define kNtColorGradientinactivecaption 28 +#define kNtColorMenuhilight 29 +#define kNtColorMenubar 30 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_COLOR_H_ */ diff --git a/libc/nt/enum/cw.h b/libc/nt/enum/cw.h new file mode 100644 index 00000000..4382aa7c --- /dev/null +++ b/libc/nt/enum/cw.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_CW_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_CW_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) + +#define kNtCwUsedefault ((int)0x80000000) + +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_CW_H_ */ diff --git a/libc/nt/enum/idc.h b/libc/nt/enum/idc.h new file mode 100644 index 00000000..1cc62593 --- /dev/null +++ b/libc/nt/enum/idc.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_IDC_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_IDC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +#define kNtIdcArrow ((const char16_t *)32512) +#define kNtIdcIbeam ((const char16_t *)32513) +#define kNtIdcWait ((const char16_t *)32514) +#define kNtIdcCross ((const char16_t *)32515) +#define kNtIdcUparrow ((const char16_t *)32516) +#define kNtIdcSizenwse ((const char16_t *)32642) +#define kNtIdcSizenesw ((const char16_t *)32643) +#define kNtIdcSizewe ((const char16_t *)32644) +#define kNtIdcSizens ((const char16_t *)32645) +#define kNtIdcSizeall ((const char16_t *)32646) +#define kNtIdcNo ((const char16_t *)32648) +#define kNtIdcHand ((const char16_t *)32649) +#define kNtIdcHelp ((const char16_t *)32651) +#define kNtIdcPin ((const char16_t *)32671) +#define kNtIdcPerson ((const char16_t *)32672) + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_IDC_H_ */ diff --git a/libc/nt/enum/pwr.h b/libc/nt/enum/pwr.h new file mode 100644 index 00000000..4e86d944 --- /dev/null +++ b/libc/nt/enum/pwr.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_PWR_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_PWR_H_ + +#define kNtPwrOk 1 +#define kNtPwrFail (-1) +#define kNtPwrSuspendrequest 1 +#define kNtPwrSuspendresume 2 +#define kNtPwrCriticalresume 3 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_PWR_H_ */ diff --git a/libc/nt/enum/sw.h b/libc/nt/enum/sw.h new file mode 100644 index 00000000..738d3830 --- /dev/null +++ b/libc/nt/enum/sw.h @@ -0,0 +1,19 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_SW_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_SW_H_ + +#define kNtSwHide 0 +#define kNtSwShownormal 1 +#define kNtSwNormal 1 +#define kNtSwShowminimized 2 +#define kNtSwShowmaximized 3 +#define kNtSwMaximize 3 +#define kNtSwShownoactivate 4 +#define kNtSwShow 5 +#define kNtSwMinimize 6 +#define kNtSwShowminnoactive 7 +#define kNtSwShowna 8 +#define kNtSwRestore 9 +#define kNtSwShowdefault 10 +#define kNtSwForceminimize 11 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_SW_H_ */ diff --git a/libc/nt/enum/wa.h b/libc/nt/enum/wa.h new file mode 100644 index 00000000..8662db28 --- /dev/null +++ b/libc/nt/enum/wa.h @@ -0,0 +1,8 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_WA_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_WA_H_ + +#define kNtWaInactive 0 +#define kNtWaActive 1 +#define kNtWaClickactive 2 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_WA_H_ */ diff --git a/libc/nt/enum/wait.h b/libc/nt/enum/wait.h new file mode 100644 index 00000000..b634edf9 --- /dev/null +++ b/libc/nt/enum/wait.h @@ -0,0 +1,7 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_WAIT_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_WAIT_H_ + +#define kNtWaitFailed 0xffffffffu +#define kNtWaitTimeout 0x00000102u + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_WAIT_H_ */ diff --git a/libc/nt/enum/wm.h b/libc/nt/enum/wm.h new file mode 100644 index 00000000..e825fbcb --- /dev/null +++ b/libc/nt/enum/wm.h @@ -0,0 +1,185 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_WM_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_WM_H_ + +#define kNtWmNull 0x0000 +#define kNtWmCreate 0x0001 +#define kNtWmDestroy 0x0002 +#define kNtWmMove 0x0003 +#define kNtWmSize 0x0005 +#define kNtWmActivate 0x0006 +#define kNtWmSetfocus 0x0007 +#define kNtWmKillfocus 0x0008 +#define kNtWmEnable 0x000A +#define kNtWmSetredraw 0x000B +#define kNtWmSettext 0x000C +#define kNtWmGettext 0x000D +#define kNtWmGettextlength 0x000E +#define kNtWmPaint 0x000F +#define kNtWmClose 0x0010 +#define kNtWmQueryendsession 0x0011 +#define kNtWmQueryopen 0x0013 +#define kNtWmEndsession 0x0016 +#define kNtWmQuit 0x0012 +#define kNtWmErasebkgnd 0x0014 +#define kNtWmSyscolorchange 0x0015 +#define kNtWmShowwindow 0x0018 +#define kNtWmWininichange 0x001A +#define kNtWmSettingchange kNtWmWininichange +#define kNtWmDevmodechange 0x001B +#define kNtWmActivateapp 0x001C +#define kNtWmFontchange 0x001D +#define kNtWmTimechange 0x001E +#define kNtWmCancelmode 0x001F +#define kNtWmSetcursor 0x0020 +#define kNtWmMouseactivate 0x0021 +#define kNtWmChildactivate 0x0022 +#define kNtWmQueuesync 0x0023 +#define kNtWmGetminmaxinfo 0x0024 +#define kNtWmPainticon 0x0026 +#define kNtWmIconerasebkgnd 0x0027 +#define kNtWmNextdlgctl 0x0028 +#define kNtWmSpoolerstatus 0x002A +#define kNtWmDrawitem 0x002B +#define kNtWmMeasureitem 0x002C +#define kNtWmDeleteitem 0x002D +#define kNtWmVkeytoitem 0x002E +#define kNtWmChartoitem 0x002F +#define kNtWmSetfont 0x0030 +#define kNtWmGetfont 0x0031 +#define kNtWmSethotkey 0x0032 +#define kNtWmGethotkey 0x0033 +#define kNtWmQuerydragicon 0x0037 +#define kNtWmCompareitem 0x0039 +#define kNtWmGetobject 0x003D +#define kNtWmCompacting 0x0041 +#define kNtWmWindowposchanging 0x0046 +#define kNtWmWindowposchanged 0x0047 +#define kNtWmPower 0x0048 +#define kNtWmCopydata 0x004A +#define kNtWmCanceljournal 0x004B +#define kNtWmNotify 0x004E +#define kNtWmInputlangchangerequest 0x0050 +#define kNtWmInputlangchange 0x0051 +#define kNtWmTcard 0x0052 +#define kNtWmHelp 0x0053 +#define kNtWmUserchanged 0x0054 +#define kNtWmNotifyformat 0x0055 +#define kNtWmContextmenu 0x007B +#define kNtWmStylechanging 0x007C +#define kNtWmStylechanged 0x007D +#define kNtWmDisplaychange 0x007E +#define kNtWmGeticon 0x007F +#define kNtWmSeticon 0x0080 +#define kNtWmNccreate 0x0081 +#define kNtWmNcdestroy 0x0082 +#define kNtWmNccalcsize 0x0083 +#define kNtWmNchittest 0x0084 +#define kNtWmNcpaint 0x0085 +#define kNtWmNcactivate 0x0086 +#define kNtWmGetdlgcode 0x0087 +#define kNtWmNcmousemove 0x00A0 +#define kNtWmNclbuttondown 0x00A1 +#define kNtWmNclbuttonup 0x00A2 +#define kNtWmNclbuttondblclk 0x00A3 +#define kNtWmNcrbuttondown 0x00A4 +#define kNtWmNcrbuttonup 0x00A5 +#define kNtWmNcrbuttondblclk 0x00A6 +#define kNtWmNcmbuttondown 0x00A7 +#define kNtWmNcmbuttonup 0x00A8 +#define kNtWmNcmbuttondblclk 0x00A9 +#define kNtWmNcxbuttondown 0x00AB +#define kNtWmNcxbuttonup 0x00AC +#define kNtWmNcxbuttondblclk 0x00AD +#define kNtWmKeyfirst 0x0100 +#define kNtWmKeydown 0x0100 +#define kNtWmKeyup 0x0101 +#define kNtWmChar 0x0102 +#define kNtWmDeadchar 0x0103 +#define kNtWmSyskeydown 0x0104 +#define kNtWmSyskeyup 0x0105 +#define kNtWmSyschar 0x0106 +#define kNtWmSysdeadchar 0x0107 +#define kNtWmUnichar 0x0109 +#define kNtWmKeylast 0x0109 +#define kNtWmInitdialog 0x0110 +#define kNtWmCommand 0x0111 +#define kNtWmSyscommand 0x0112 +#define kNtWmTimer 0x0113 +#define kNtWmHscroll 0x0114 +#define kNtWmVscroll 0x0115 +#define kNtWmInitmenu 0x0116 +#define kNtWmInitmenupopup 0x0117 +#define kNtWmGesture 0x0119 +#define kNtWmGesturenotify 0x011A +#define kNtWmMenuselect 0x011F +#define kNtWmMenuchar 0x0120 +#define kNtWmEnteridle 0x0121 +#define kNtWmMenurbuttonup 0x0122 +#define kNtWmMenudrag 0x0123 +#define kNtWmMenugetobject 0x0124 +#define kNtWmUninitmenupopup 0x0125 +#define kNtWmMenucommand 0x0126 +#define kNtWmChangeuistate 0x0127 +#define kNtWmUpdateuistate 0x0128 +#define kNtWmQueryuistate 0x0129 +#define kNtWmMousefirst 0x0200 +#define kNtWmMousemove 0x0200 +#define kNtWmLbuttondown 0x0201 +#define kNtWmLbuttonup 0x0202 +#define kNtWmLbuttondblclk 0x0203 +#define kNtWmRbuttondown 0x0204 +#define kNtWmRbuttonup 0x0205 +#define kNtWmRbuttondblclk 0x0206 +#define kNtWmMbuttondown 0x0207 +#define kNtWmMbuttonup 0x0208 +#define kNtWmMbuttondblclk 0x0209 +#define kNtWmMousewheel 0x020A +#define kNtWmXbuttondown 0x020B +#define kNtWmXbuttonup 0x020C +#define kNtWmXbuttondblclk 0x020D +#define kNtWmMousehwheel 0x020E +#define kNtWmMouselast 0x020E +#define kNtWmParentnotify 0x0210 +#define kNtWmEntermenuloop 0x0211 +#define kNtWmExitmenuloop 0x0212 +#define kNtWmNextmenu 0x0213 +#define kNtWmSizing 0x0214 +#define kNtWmCapturechanged 0x0215 +#define kNtWmMoving 0x0216 +#define kNtWmPowerbroadcast 0x0218 +#define kNtWmMdicreate 0x0220 +#define kNtWmMdidestroy 0x0221 +#define kNtWmMdiactivate 0x0222 +#define kNtWmMdirestore 0x0223 +#define kNtWmMdinext 0x0224 +#define kNtWmMdimaximize 0x0225 +#define kNtWmMditile 0x0226 +#define kNtWmMdicascade 0x0227 +#define kNtWmMdiiconarrange 0x0228 +#define kNtWmMdigetactive 0x0229 +#define kNtWmMdisetmenu 0x0230 +#define kNtWmEntersizemove 0x0231 +#define kNtWmExitsizemove 0x0232 +#define kNtWmDropfiles 0x0233 +#define kNtWmMdirefreshmenu 0x0234 +#define kNtWmCut 0x0300 +#define kNtWmCopy 0x0301 +#define kNtWmPaste 0x0302 +#define kNtWmClear 0x0303 +#define kNtWmUndo 0x0304 +#define kNtWmRenderformat 0x0305 +#define kNtWmRenderallformats 0x0306 +#define kNtWmDestroyclipboard 0x0307 +#define kNtWmDrawclipboard 0x0308 +#define kNtWmPaintclipboard 0x0309 +#define kNtWmVscrollclipboard 0x030A +#define kNtWmSizeclipboard 0x030B +#define kNtWmAskcbformatname 0x030C +#define kNtWmChangecbchain 0x030D +#define kNtWmHscrollclipboard 0x030E +#define kNtWmQuerynewpalette 0x030F +#define kNtWmPaletteischanging 0x0310 +#define kNtWmPalettechanged 0x0311 +#define kNtWmHotkey 0x0312 + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_WM_H_ */ diff --git a/libc/nt/enum/ws.h b/libc/nt/enum/ws.h new file mode 100644 index 00000000..47590100 --- /dev/null +++ b/libc/nt/enum/ws.h @@ -0,0 +1,62 @@ +#ifndef COSMOPOLITAN_LIBC_NT_ENUM_WS_H_ +#define COSMOPOLITAN_LIBC_NT_ENUM_WS_H_ + +#define kNtWsOverlapped 0x00000000 +#define kNtWsPopup 0x80000000 +#define kNtWsChild 0x40000000 +#define kNtWsMinimize 0x20000000 +#define kNtWsVisible 0x10000000 +#define kNtWsDisabled 0x08000000 +#define kNtWsClipsiblings 0x04000000 +#define kNtWsClipchildren 0x02000000 +#define kNtWsMaximize 0x01000000 +#define kNtWsCaption 0x00C00000 +#define kNtWsBorder 0x00800000 +#define kNtWsDlgframe 0x00400000 +#define kNtWsVscroll 0x00200000 +#define kNtWsHscroll 0x00100000 +#define kNtWsSysmenu 0x00080000 +#define kNtWsThickframe 0x00040000 +#define kNtWsGroup 0x00020000 +#define kNtWsTabstop 0x00010000 +#define kNtWsMinimizebox 0x00020000 +#define kNtWsMaximizebox 0x00010000 +#define kNtWsTiled kNtWsOverlapped +#define kNtWsIconic kNtWsMinimize +#define kNtWsSizebox kNtWsThickframe +#define kNtWsTiledwindow kNtWsOverlappedwindow +#define kNtWsOverlappedwindow \ + (kNtWsOverlapped | kNtWsCaption | kNtWsSysmenu | kNtWsThickframe | \ + kNtWsMinimizebox | kNtWsMaximizebox) +#define kNtWsPopupwindow (kNtWsPopup | kNtWsBorder | kNtWsSysmenu) + +#define kNtWsExDlgmodalframe 0x00000001 +#define kNtWsExNoparentnotify 0x00000004 +#define kNtWsExTopmost 0x00000008 +#define kNtWsExAcceptfiles 0x00000010 +#define kNtWsExTransparent 0x00000020 +#define kNtWsExMdichild 0x00000040 +#define kNtWsExToolwindow 0x00000080 +#define kNtWsExWindowedge 0x00000100 +#define kNtWsExClientedge 0x00000200 +#define kNtWsExContexthelp 0x00000400 +#define kNtWsExRight 0x00001000 +#define kNtWsExLeft 0x00000000 +#define kNtWsExRtlreading 0x00002000 +#define kNtWsExLtrreading 0x00000000 +#define kNtWsExLeftscrollbar 0x00004000 +#define kNtWsExRightscrollbar 0x00000000 +#define kNtWsExControlparent 0x00010000 +#define kNtWsExStaticedge 0x00020000 +#define kNtWsExAppwindow 0x00040000 +#define kNtWsExNoinheritlayout 0x00100000 +#define kNtWsExNoredirectionbitmap 0x00200000 +#define kNtWsExLayoutrtl 0x00400000 +#define kNtWsExComposited 0x02000000 +#define kNtWsExNoactivate 0x08000000 + +#define kNtWsExOverlappedwindow (kNtWsExWindowedge | kNtWsExClientedge) +#define kNtWsExPalettewindow \ + (kNtWsExWindowedge | kNtWsExToolwindow | kNtWsExTopmost) + +#endif /* COSMOPOLITAN_LIBC_NT_ENUM_WS_H_ */ diff --git a/libc/nt/events.h b/libc/nt/events.h index 683b3486..28f086a6 100644 --- a/libc/nt/events.h +++ b/libc/nt/events.h @@ -1,5 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_NT_EVENTS_H_ #define COSMOPOLITAN_LIBC_NT_EVENTS_H_ +#include "libc/nt/struct/msg.h" +#include "libc/nt/struct/point.h" #if 0 /* ░░░░ ▒▒▒░░░▒▒▒▒▒▒▒▓▓▓░ @@ -27,64 +29,61 @@ ╚────────────────────────────────────────────────────────────────────────────│*/ #endif -#define NT_EVENT_SYSTEM_SOUND 0x0001 -#define NT_EVENT_SYSTEM_ALERT 0x0002 -#define NT_EVENT_SYSTEM_FOREGROUND 0x0003 -#define NT_EVENT_SYSTEM_MENUSTART 0x0004 -#define NT_EVENT_SYSTEM_MENUEND 0x0005 -#define NT_EVENT_SYSTEM_MENUPOPUPSTART 0x0006 -#define NT_EVENT_SYSTEM_MENUPOPUPEND 0x0007 -#define NT_EVENT_SYSTEM_CAPTURESTART 0x0008 -#define NT_EVENT_SYSTEM_CAPTUREEND 0x0009 -#define NT_EVENT_SYSTEM_MOVESIZESTART 0x000A -#define NT_EVENT_SYSTEM_MOVESIZEEND 0x000B +#define NT_EVENT_SYSTEM_SOUND 0x0001 +#define NT_EVENT_SYSTEM_ALERT 0x0002 +#define NT_EVENT_SYSTEM_FOREGROUND 0x0003 +#define NT_EVENT_SYSTEM_MENUSTART 0x0004 +#define NT_EVENT_SYSTEM_MENUEND 0x0005 +#define NT_EVENT_SYSTEM_MENUPOPUPSTART 0x0006 +#define NT_EVENT_SYSTEM_MENUPOPUPEND 0x0007 +#define NT_EVENT_SYSTEM_CAPTURESTART 0x0008 +#define NT_EVENT_SYSTEM_CAPTUREEND 0x0009 +#define NT_EVENT_SYSTEM_MOVESIZESTART 0x000A +#define NT_EVENT_SYSTEM_MOVESIZEEND 0x000B #define NT_EVENT_SYSTEM_CONTEXTHELPSTART 0x000C -#define NT_EVENT_SYSTEM_CONTEXTHELPEND 0x000D -#define NT_EVENT_SYSTEM_DRAGDROPSTART 0x000E -#define NT_EVENT_SYSTEM_DRAGDROPEND 0x000F -#define NT_EVENT_SYSTEM_DIALOGSTART 0x0010 -#define NT_EVENT_SYSTEM_DIALOGEND 0x0011 -#define NT_EVENT_SYSTEM_SCROLLINGSTART 0x0012 -#define NT_EVENT_SYSTEM_SCROLLINGEND 0x0013 -#define NT_EVENT_SYSTEM_SWITCHSTART 0x0014 -#define NT_EVENT_SYSTEM_SWITCHEND 0x0015 -#define NT_EVENT_SYSTEM_MINIMIZESTART 0x0016 -#define NT_EVENT_SYSTEM_MINIMIZEEND 0x0017 +#define NT_EVENT_SYSTEM_CONTEXTHELPEND 0x000D +#define NT_EVENT_SYSTEM_DRAGDROPSTART 0x000E +#define NT_EVENT_SYSTEM_DRAGDROPEND 0x000F +#define NT_EVENT_SYSTEM_DIALOGSTART 0x0010 +#define NT_EVENT_SYSTEM_DIALOGEND 0x0011 +#define NT_EVENT_SYSTEM_SCROLLINGSTART 0x0012 +#define NT_EVENT_SYSTEM_SCROLLINGEND 0x0013 +#define NT_EVENT_SYSTEM_SWITCHSTART 0x0014 +#define NT_EVENT_SYSTEM_SWITCHEND 0x0015 +#define NT_EVENT_SYSTEM_MINIMIZESTART 0x0016 +#define NT_EVENT_SYSTEM_MINIMIZEEND 0x0017 -#define NT_EVENT_CONSOLE_CARET 0x4001 -#define NT_EVENT_CONSOLE_UPDATE_REGION 0x4002 -#define NT_EVENT_CONSOLE_UPDATE_SIMPLE 0x4003 -#define NT_EVENT_CONSOLE_UPDATE_SCROLL 0x4004 -#define NT_EVENT_CONSOLE_LAYOUT 0x4005 +#define NT_EVENT_CONSOLE_CARET 0x4001 +#define NT_EVENT_CONSOLE_UPDATE_REGION 0x4002 +#define NT_EVENT_CONSOLE_UPDATE_SIMPLE 0x4003 +#define NT_EVENT_CONSOLE_UPDATE_SCROLL 0x4004 +#define NT_EVENT_CONSOLE_LAYOUT 0x4005 #define NT_EVENT_CONSOLE_START_APPLICATION 0x4006 -#define NT_EVENT_CONSOLE_END_APPLICATION 0x4007 +#define NT_EVENT_CONSOLE_END_APPLICATION 0x4007 -#define NT_EVENT_OBJECT_CREATE 0x8000 -#define NT_EVENT_OBJECT_DESTROY 0x8001 -#define NT_EVENT_OBJECT_SHOW 0x8002 -#define NT_EVENT_OBJECT_HIDE 0x8003 -#define NT_EVENT_OBJECT_REORDER 0x8004 -#define NT_EVENT_OBJECT_FOCUS 0x8005 -#define NT_EVENT_OBJECT_SELECTION 0x8006 -#define NT_EVENT_OBJECT_SELECTIONADD 0x8007 -#define NT_EVENT_OBJECT_SELECTIONREMOVE 0x8008 -#define NT_EVENT_OBJECT_SELECTIONWITHIN 0x8009 -#define NT_EVENT_OBJECT_STATECHANGE 0x800A -#define NT_EVENT_OBJECT_LOCATIONCHANGE 0x800B -#define NT_EVENT_OBJECT_NAMECHANGE 0x800C +#define NT_EVENT_OBJECT_CREATE 0x8000 +#define NT_EVENT_OBJECT_DESTROY 0x8001 +#define NT_EVENT_OBJECT_SHOW 0x8002 +#define NT_EVENT_OBJECT_HIDE 0x8003 +#define NT_EVENT_OBJECT_REORDER 0x8004 +#define NT_EVENT_OBJECT_FOCUS 0x8005 +#define NT_EVENT_OBJECT_SELECTION 0x8006 +#define NT_EVENT_OBJECT_SELECTIONADD 0x8007 +#define NT_EVENT_OBJECT_SELECTIONREMOVE 0x8008 +#define NT_EVENT_OBJECT_SELECTIONWITHIN 0x8009 +#define NT_EVENT_OBJECT_STATECHANGE 0x800A +#define NT_EVENT_OBJECT_LOCATIONCHANGE 0x800B +#define NT_EVENT_OBJECT_NAMECHANGE 0x800C #define NT_EVENT_OBJECT_DESCRIPTIONCHANGE 0x800D -#define NT_EVENT_OBJECT_VALUECHANGE 0x800E -#define NT_EVENT_OBJECT_PARENTCHANGE 0x800F -#define NT_EVENT_OBJECT_HELPCHANGE 0x8010 -#define NT_EVENT_OBJECT_DEFACTIONCHANGE 0x8011 +#define NT_EVENT_OBJECT_VALUECHANGE 0x800E +#define NT_EVENT_OBJECT_PARENTCHANGE 0x800F +#define NT_EVENT_OBJECT_HELPCHANGE 0x8010 +#define NT_EVENT_OBJECT_DEFACTIONCHANGE 0x8011 #define NT_EVENT_OBJECT_ACCELERATORCHANGE 0x8012 #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -struct NtMsg; -struct NtPoint; - int32_t GetMessage(struct NtMsg *lpMsg, int64_t hWnd, uint32_t wMsgFilterMin, uint32_t wMsgFilterMax); int32_t TranslateMessage(const struct NtMsg *lpMsg); diff --git a/libc/nt/master.sh b/libc/nt/master.sh index aeaf143b..55f3b0f8 100755 --- a/libc/nt/master.sh +++ b/libc/nt/master.sh @@ -1635,7 +1635,7 @@ imp 'FillConsoleOutputAttribute' FillConsoleOutputAttribute KernelBase 354 imp 'FillConsoleOutputCharacter' FillConsoleOutputCharacterW KernelBase 356 5 imp 'FillConsoleOutputCharacterA' FillConsoleOutputCharacterA KernelBase 355 5 imp 'FillPath' FillPath gdi32 1479 -imp 'FillRect' FillRect user32 1780 +imp 'FillRect' FillRect user32 1780 3 imp 'FillRgn' FillRgn gdi32 1480 imp 'FindActCtxSectionGuid' FindActCtxSectionGuid KernelBase 357 imp 'FindActCtxSectionGuidWorker' FindActCtxSectionGuidWorker kernel32 372 @@ -3191,17 +3191,17 @@ imp 'LoadAlterBitmap' LoadAlterBitmap comdlg32 117 imp 'LoadAppInitDlls' LoadAppInitDlls KernelBase 971 imp 'LoadBitmapA' LoadBitmapA user32 2096 imp 'LoadBitmap' LoadBitmapW user32 2097 -imp 'LoadCursorA' LoadCursorA user32 2098 +imp 'LoadCursorA' LoadCursorA user32 2098 2 imp 'LoadCursorFromFileA' LoadCursorFromFileA user32 2099 imp 'LoadCursorFromFile' LoadCursorFromFileW user32 2100 -imp 'LoadCursor' LoadCursorW user32 2101 +imp 'LoadCursor' LoadCursorW user32 2101 2 imp 'LoadEnclaveData' LoadEnclaveData KernelBase 972 imp 'LoadEnclaveImageA' LoadEnclaveImageA KernelBase 973 imp 'LoadEnclaveImage' LoadEnclaveImageW KernelBase 974 imp 'LoadIcon' LoadIconW user32 2103 2 imp 'LoadIconA' LoadIconA user32 2102 2 -imp 'LoadImageA' LoadImageA user32 2104 -imp 'LoadImage' LoadImageW user32 2105 +imp 'LoadImageA' LoadImageA user32 2104 6 +imp 'LoadImage' LoadImageW user32 2105 6 imp 'LoadKeyboardLayoutA' LoadKeyboardLayoutA user32 2106 imp 'LoadKeyboardLayoutEx' LoadKeyboardLayoutEx user32 2107 imp 'LoadKeyboardLayout' LoadKeyboardLayoutW user32 2108 @@ -3996,6 +3996,8 @@ imp 'NtWriteFileGather' NtWriteFileGather ntdll 656 imp 'NtWriteRequestData' NtWriteRequestData ntdll 657 imp 'NtWriteVirtualMemory' NtWriteVirtualMemory ntdll 658 5 imp 'NtYieldExecution' NtYieldExecution ntdll 659 0 +imp 'DefWindowProcA' DefWindowProcA user32 173 4 +imp 'DefWindowProc' DefWindowProcW user32 174 4 imp 'NtdllDefWindowProc_A' NtdllDefWindowProc_A ntdll 660 imp 'NtdllDefWindowProc_W' NtdllDefWindowProc_W ntdll 661 imp 'NtdllDialogWndProc_A' NtdllDialogWndProc_A ntdll 662 @@ -4644,10 +4646,10 @@ imp 'RegisterApplicationRecoveryCallback' RegisterApplicationRecoveryCallback imp 'RegisterApplicationRestart' RegisterApplicationRestart kernel32 1185 imp 'RegisterBSDRWindow' RegisterBSDRWindow user32 2247 imp 'RegisterBadMemoryNotification' RegisterBadMemoryNotification KernelBase 1384 -imp 'RegisterClassA' RegisterClassA user32 2248 -imp 'RegisterClassExA' RegisterClassExA user32 2249 -imp 'RegisterClassEx' RegisterClassExW user32 2250 -imp 'RegisterClass' RegisterClassW user32 2251 +imp 'RegisterClassA' RegisterClassA user32 2248 1 +imp 'RegisterClassExA' RegisterClassExA user32 2249 1 +imp 'RegisterClassEx' RegisterClassExW user32 2250 1 +imp 'RegisterClass' RegisterClassW user32 2251 1 imp 'RegisterClipboardFormatA' RegisterClipboardFormatA user32 2252 imp 'RegisterClipboardFormat' RegisterClipboardFormatW user32 2253 imp 'RegisterConsoleIME' RegisterConsoleIME kernel32 1187 @@ -6482,9 +6484,9 @@ imp 'ShipAssert' ShipAssert ntdll 1612 imp 'ShipAssertGetBufferInfo' ShipAssertGetBufferInfo ntdll 1613 imp 'ShipAssertMsgA' ShipAssertMsgA ntdll 1614 imp 'ShipAssertMsg' ShipAssertMsgW ntdll 1615 -imp 'ShowCaret' ShowCaret user32 2411 +imp 'ShowCaret' ShowCaret user32 2411 1 imp 'ShowConsoleCursor' ShowConsoleCursor kernel32 1409 -imp 'ShowCursor' ShowCursor user32 2412 +imp 'ShowCursor' ShowCursor user32 2412 1 imp 'ShowOwnedPopups' ShowOwnedPopups user32 2413 imp 'ShowScrollBar' ShowScrollBar user32 2414 imp 'ShowStartGlass' ShowStartGlass user32 2415 diff --git a/libc/nt/paint.h b/libc/nt/paint.h index 699213fa..725e80c5 100644 --- a/libc/nt/paint.h +++ b/libc/nt/paint.h @@ -1,5 +1,8 @@ #ifndef COSMOPOLITAN_LIBC_NT_PAINT_H_ #define COSMOPOLITAN_LIBC_NT_PAINT_H_ +#include "libc/nt/struct/drawtextparams.h" +#include "libc/nt/struct/paintstruct.h" +#include "libc/nt/struct/rect.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ #if 0 @@ -8,50 +11,22 @@ COSMOPOLITAN_C_START_ ╚────────────────────────────────────────────────────────────────────────────│*/ #endif -struct NtSize { - int32_t cx; - int32_t cy; -}; - -struct NtRectangle { - int32_t left; - int32_t top; - int32_t right; - int32_t bottom; -}; - -struct NtDrawTextParams { - uint32_t cbSize; - int32_t iTabLength; - int32_t iLeftMargin; - int32_t iRightMargin; - uint32_t uiLengthDrawn; -}; - -struct NtPaintStruct { - int64_t hdc; - int32_t fErase; - struct NtRectangle rcPaint; - int32_t fRestore; - int32_t fIncUpdate; - unsigned char rgbReserved[32]; -}; - int64_t BeginPaint(int64_t hWnd, struct NtPaintStruct *lpPaint); int32_t EndPaint(int64_t hWnd, const struct NtPaintStruct *lpPaint); int32_t BitBlt(int64_t hdc, int x, int y, int cx, int cy, int64_t hdcSrc, int x1, int y1, uint32_t rop); -int32_t GetClientRect(int64_t hWnd, struct NtRectangle *lpRect); -int32_t GetWindowRect(int64_t hWnd, struct NtRectangle *lpRect); +int32_t GetClientRect(int64_t hWnd, struct NtRect *lpRect); +int32_t GetWindowRect(int64_t hWnd, struct NtRect *lpRect); int32_t SetBkMode(int64_t hdc, int mode); uint32_t SetTextColor(int64_t hdc, uint32_t color); uint32_t SetTextAlign(int64_t hdc, uint32_t align); int32_t SetTextJustification(int64_t hdc, int extra, int count); int32_t DrawText(int64_t hdc, const char16_t *lpchText, int cchText, - struct NtRectangle *lprc, uint32_t format); + struct NtRect *lprc, uint32_t format); int32_t DrawTextEx(int64_t hdc, char16_t *lpchText, int cchText, - struct NtRectangle *lprc, uint32_t format, + struct NtRect *lprc, uint32_t format, struct NtDrawTextParams *lpdtp); +int32_t FillRect(int64_t hDC, const struct NtRect *lpRC, int64_t hBrush); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/nt/struct/drawtextparams.h b/libc/nt/struct/drawtextparams.h new file mode 100644 index 00000000..2be46c2f --- /dev/null +++ b/libc/nt/struct/drawtextparams.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_DRAWTEXTPARAMS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_DRAWTEXTPARAMS_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtDrawTextParams { + uint32_t cbSize; + int32_t iTabLength; + int32_t iLeftMargin; + int32_t iRightMargin; + uint32_t uiLengthDrawn; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_DRAWTEXTPARAMS_H_ */ diff --git a/libc/nt/struct/msg.h b/libc/nt/struct/msg.h index a0790fad..3009d30d 100644 --- a/libc/nt/struct/msg.h +++ b/libc/nt/struct/msg.h @@ -6,8 +6,8 @@ struct NtMsg { int64_t hwnd; uint32_t message; - uintptr_t wParam; - intptr_t lParam; + uint64_t wParam; + int64_t lParam; uint32_t time; struct NtPoint pt; }; diff --git a/libc/nt/struct/paintstruct.h b/libc/nt/struct/paintstruct.h new file mode 100644 index 00000000..688f72f8 --- /dev/null +++ b/libc/nt/struct/paintstruct.h @@ -0,0 +1,18 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_PAINTSTRUCT_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_PAINTSTRUCT_H_ +#include "libc/nt/struct/rect.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtPaintStruct { + int64_t hdc; + bool32 fErase; + struct NtRect rcPaint; + bool32 fRestore; + bool32 fIncUpdate; + uint8_t rgbReserved[32]; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_PAINTSTRUCT_H_ */ diff --git a/libc/nt/struct/rect.h b/libc/nt/struct/rect.h new file mode 100644 index 00000000..b3d21579 --- /dev/null +++ b/libc/nt/struct/rect.h @@ -0,0 +1,15 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_RECT_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_RECT_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtRect { + int32_t left; + int32_t top; + int32_t right; + int32_t bottom; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_RECT_H_ */ diff --git a/libc/nt/struct/size.h b/libc/nt/struct/size.h new file mode 100644 index 00000000..3476162a --- /dev/null +++ b/libc/nt/struct/size.h @@ -0,0 +1,13 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_SIZE_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_SIZE_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtSize { + int32_t cx; + int32_t cy; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_SIZE_H_ */ diff --git a/libc/nt/struct/wndclass.h b/libc/nt/struct/wndclass.h new file mode 100644 index 00000000..fd064265 --- /dev/null +++ b/libc/nt/struct/wndclass.h @@ -0,0 +1,22 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_WNDCLASS_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_WNDCLASS_H_ +#include "libc/nt/typedef/wndproc.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtWndClass { + uint32_t style; + NtWndProc lpfnWndProc; + int32_t cbClsExtra; + int32_t cbWndExtra; + int64_t hInstance; + int64_t hIcon; + int64_t hCursor; + int64_t hbrBackground; + const char16_t *lpszMenuName; + const char16_t *lpszClassName; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_WNDCLASS_H_ */ diff --git a/libc/nt/struct/wndclassex.h b/libc/nt/struct/wndclassex.h new file mode 100644 index 00000000..033f6a51 --- /dev/null +++ b/libc/nt/struct/wndclassex.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_NT_STRUCT_WNDCLASSEX_H_ +#define COSMOPOLITAN_LIBC_NT_STRUCT_WNDCLASSEX_H_ +#include "libc/nt/typedef/wndproc.h" +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct NtWndClassEx { + uint32_t cbSize; + uint32_t style; + NtWndProc lpfnWndProc; + int32_t cbClsExtra; + int32_t cbWndExtra; + int64_t hInstance; + int64_t hIcon; + int64_t hCursor; + int64_t hbrBackground; + const char16_t *lpszMenuName; + const char16_t *lpszClassName; + int64_t hIconSm; +}; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_STRUCT_WNDCLASSEX_H_ */ diff --git a/libc/nt/synchronization.h b/libc/nt/synchronization.h index ceb32bfe..7f841791 100644 --- a/libc/nt/synchronization.h +++ b/libc/nt/synchronization.h @@ -48,11 +48,11 @@ void GetSystemTimeAsFileTime(struct NtFileTime *); // win8+ void GetSystemTimePreciseAsFileTime(struct NtFileTime *); // win8+ uint32_t WaitForSingleObject(int64_t hHandle, uint32_t dwMilliseconds); -uint32_t WaitForMultipleObjects(uint32_t nCount, const void **lpHandles, +uint32_t WaitForMultipleObjects(uint32_t nCount, const int64_t *lpHandles, bool32 bWaitAll, uint32_t dwMilliseconds); uint32_t WaitForSingleObjectEx(int64_t hHandle, uint32_t dwMilliseconds, bool32 bAlertable); -uint32_t WaitForMultipleObjectsEx(unsigned int nCount, const void **lpHandles, +uint32_t WaitForMultipleObjectsEx(unsigned int nCount, const int64_t *lpHandles, bool32 bWaitAll, uint32_t dwMilliseconds, bool32 bAlertable); diff --git a/libc/nt/typedef/wndproc.h b/libc/nt/typedef/wndproc.h new file mode 100644 index 00000000..37a256a1 --- /dev/null +++ b/libc/nt/typedef/wndproc.h @@ -0,0 +1,10 @@ +#ifndef COSMOPOLITAN_LIBC_NT_TYPEDEF_WNDPROC_H_ +#define COSMOPOLITAN_LIBC_NT_TYPEDEF_WNDPROC_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +typedef int64_t (*NtWndProc)(int64_t, uint32_t, uint64_t, int64_t); + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_NT_TYPEDEF_WNDPROC_H_ */ diff --git a/libc/nt/user32/DefWindowProcA.s b/libc/nt/user32/DefWindowProcA.s new file mode 100644 index 00000000..4ceb4441 --- /dev/null +++ b/libc/nt/user32/DefWindowProcA.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DefWindowProcA,DefWindowProcA,173 + + .text.windows +DefWindowProcA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DefWindowProcA(%rip),%rax + jmp __sysv2nt + .endfn DefWindowProcA,globl + .previous diff --git a/libc/nt/user32/DefWindowProcW.s b/libc/nt/user32/DefWindowProcW.s new file mode 100644 index 00000000..54ee0d24 --- /dev/null +++ b/libc/nt/user32/DefWindowProcW.s @@ -0,0 +1,12 @@ +.include "o/libc/nt/codegen.inc" +.imp user32,__imp_DefWindowProcW,DefWindowProcW,174 + + .text.windows +DefWindowProc: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_DefWindowProcW(%rip),%rax + jmp __sysv2nt + .endfn DefWindowProc,globl + .previous diff --git a/libc/nt/user32/FillRect.s b/libc/nt/user32/FillRect.s index d1a4886a..43f6f590 100644 --- a/libc/nt/user32/FillRect.s +++ b/libc/nt/user32/FillRect.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_FillRect,FillRect,1780 + + .text.windows +FillRect: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_FillRect(%rip),%rax + jmp __sysv2nt + .endfn FillRect,globl + .previous diff --git a/libc/nt/user32/LoadCursorA.s b/libc/nt/user32/LoadCursorA.s index 15ce8b49..2be2ab67 100644 --- a/libc/nt/user32/LoadCursorA.s +++ b/libc/nt/user32/LoadCursorA.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_LoadCursorA,LoadCursorA,2098 + + .text.windows +LoadCursorA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadCursorA(%rip),%rax + jmp __sysv2nt + .endfn LoadCursorA,globl + .previous diff --git a/libc/nt/user32/LoadCursorW.s b/libc/nt/user32/LoadCursorW.s index 9562838d..67d7f197 100644 --- a/libc/nt/user32/LoadCursorW.s +++ b/libc/nt/user32/LoadCursorW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_LoadCursorW,LoadCursorW,2101 + + .text.windows +LoadCursor: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadCursorW(%rip),%rax + jmp __sysv2nt + .endfn LoadCursor,globl + .previous diff --git a/libc/nt/user32/LoadImageA.s b/libc/nt/user32/LoadImageA.s index d802b412..9a7767a1 100644 --- a/libc/nt/user32/LoadImageA.s +++ b/libc/nt/user32/LoadImageA.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_LoadImageA,LoadImageA,2104 + + .text.windows +LoadImageA: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadImageA(%rip),%rax + jmp __sysv2nt6 + .endfn LoadImageA,globl + .previous diff --git a/libc/nt/user32/LoadImageW.s b/libc/nt/user32/LoadImageW.s index ce0e5ebc..3b30f030 100644 --- a/libc/nt/user32/LoadImageW.s +++ b/libc/nt/user32/LoadImageW.s @@ -1,2 +1,12 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_LoadImageW,LoadImageW,2105 + + .text.windows +LoadImage: + push %rbp + mov %rsp,%rbp + .profilable + mov __imp_LoadImageW(%rip),%rax + jmp __sysv2nt6 + .endfn LoadImage,globl + .previous diff --git a/libc/nt/user32/RegisterClassA.s b/libc/nt/user32/RegisterClassA.s index bdc2267f..3303a552 100644 --- a/libc/nt/user32/RegisterClassA.s +++ b/libc/nt/user32/RegisterClassA.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_RegisterClassA,RegisterClassA,2248 + + .text.windows +RegisterClassA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegisterClassA(%rip) + leave + ret + .endfn RegisterClassA,globl + .previous diff --git a/libc/nt/user32/RegisterClassExA.s b/libc/nt/user32/RegisterClassExA.s index 8a8c75e3..8ba6005f 100644 --- a/libc/nt/user32/RegisterClassExA.s +++ b/libc/nt/user32/RegisterClassExA.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_RegisterClassExA,RegisterClassExA,2249 + + .text.windows +RegisterClassExA: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegisterClassExA(%rip) + leave + ret + .endfn RegisterClassExA,globl + .previous diff --git a/libc/nt/user32/RegisterClassExW.s b/libc/nt/user32/RegisterClassExW.s index dbd2c382..55305cd2 100644 --- a/libc/nt/user32/RegisterClassExW.s +++ b/libc/nt/user32/RegisterClassExW.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_RegisterClassExW,RegisterClassExW,2250 + + .text.windows +RegisterClassEx: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegisterClassExW(%rip) + leave + ret + .endfn RegisterClassEx,globl + .previous diff --git a/libc/nt/user32/RegisterClassW.s b/libc/nt/user32/RegisterClassW.s index 308f050e..08d3b62c 100644 --- a/libc/nt/user32/RegisterClassW.s +++ b/libc/nt/user32/RegisterClassW.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_RegisterClassW,RegisterClassW,2251 + + .text.windows +RegisterClass: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_RegisterClassW(%rip) + leave + ret + .endfn RegisterClass,globl + .previous diff --git a/libc/nt/user32/ShowCaret.s b/libc/nt/user32/ShowCaret.s index a56d01dc..375b4c3c 100644 --- a/libc/nt/user32/ShowCaret.s +++ b/libc/nt/user32/ShowCaret.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_ShowCaret,ShowCaret,2411 + + .text.windows +ShowCaret: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ShowCaret(%rip) + leave + ret + .endfn ShowCaret,globl + .previous diff --git a/libc/nt/user32/ShowCursor.s b/libc/nt/user32/ShowCursor.s index 2fa3a525..e07897a7 100644 --- a/libc/nt/user32/ShowCursor.s +++ b/libc/nt/user32/ShowCursor.s @@ -1,2 +1,15 @@ .include "o/libc/nt/codegen.inc" .imp user32,__imp_ShowCursor,ShowCursor,2412 + + .text.windows +ShowCursor: + push %rbp + mov %rsp,%rbp + .profilable + mov %rdi,%rcx + sub $32,%rsp + call *__imp_ShowCursor(%rip) + leave + ret + .endfn ShowCursor,globl + .previous diff --git a/libc/nt/windows.h b/libc/nt/windows.h index 43b8ea91..2291e81a 100644 --- a/libc/nt/windows.h +++ b/libc/nt/windows.h @@ -1,5 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_NT_WINDOWS_H_ #define COSMOPOLITAN_LIBC_NT_WINDOWS_H_ +#include "libc/nt/struct/rect.h" +#include "libc/nt/struct/wndclass.h" #include "libc/nt/typedef/timerproc.h" #if 0 /* ░░░░ @@ -27,322 +29,25 @@ │ cosmopolitan § new technology » windows ─╬─│┼ ╚────────────────────────────────────────────────────────────────────────────│*/ #endif - -#define NT_WM_NULL 0x0000 -#define NT_WM_CREATE 0x0001 -#define NT_WM_DESTROY 0x0002 -#define NT_WM_MOVE 0x0003 -#define NT_WM_SIZE 0x0005 -#define NT_WM_ACTIVATE 0x0006 -#define NT_WA_INACTIVE 0 -#define NT_WA_ACTIVE 1 -#define NT_WA_CLICKACTIVE 2 -#define NT_WM_SETFOCUS 0x0007 -#define NT_WM_KILLFOCUS 0x0008 -#define NT_WM_ENABLE 0x000A -#define NT_WM_SETREDRAW 0x000B -#define NT_WM_SETTEXT 0x000C -#define NT_WM_GETTEXT 0x000D -#define NT_WM_GETTEXTLENGTH 0x000E -#define NT_WM_PAINT 0x000F -#define NT_WM_CLOSE 0x0010 -#define NT_WM_QUIT 0x0012 -#define NT_WM_ERASEBKGND 0x0014 -#define NT_WM_SYSCOLORCHANGE 0x0015 -#define NT_WM_SHOWWINDOW 0x0018 -#define NT_WM_WININICHANGE 0x001A -#define NT_WM_SETTINGCHANGE WM_WININICHANGE -#define NT_WM_DEVMODECHANGE 0x001B -#define NT_WM_ACTIVATEAPP 0x001C -#define NT_WM_FONTCHANGE 0x001D -#define NT_WM_TIMECHANGE 0x001E -#define NT_WM_CANCELMODE 0x001F -#define NT_WM_SETCURSOR 0x0020 -#define NT_WM_MOUSEACTIVATE 0x0021 -#define NT_WM_CHILDACTIVATE 0x0022 -#define NT_WM_QUEUESYNC 0x0023 -#define NT_WM_GETMINMAXINFO 0x0024 - -#define NT_WS_OVERLAPPED 0x00000000 -#define NT_WS_POPUP 0x80000000 -#define NT_WS_CHILD 0x40000000 -#define NT_WS_MINIMIZE 0x20000000 -#define NT_WS_VISIBLE 0x10000000 -#define NT_WS_DISABLED 0x08000000 -#define NT_WS_CLIPSIBLINGS 0x04000000 -#define NT_WS_CLIPCHILDREN 0x02000000 -#define NT_WS_MAXIMIZE 0x01000000 -#define NT_WS_CAPTION 0x00C00000 -#define NT_WS_BORDER 0x00800000 -#define NT_WS_DLGFRAME 0x00400000 -#define NT_WS_VSCROLL 0x00200000 -#define NT_WS_HSCROLL 0x00100000 -#define NT_WS_SYSMENU 0x00080000 -#define NT_WS_THICKFRAME 0x00040000 -#define NT_WS_GROUP 0x00020000 -#define NT_WS_TABSTOP 0x00010000 -#define NT_WS_MINIMIZEBOX 0x00020000 -#define NT_WS_MAXIMIZEBOX 0x00010000 -#define NT_WS_TILED WS_OVERLAPPED -#define NT_WS_ICONIC WS_MINIMIZE -#define NT_WS_SIZEBOX WS_THICKFRAME -#define NT_WS_TILEDWINDOW WS_OVERLAPPEDWINDOW -#define NT_WS_OVERLAPPEDWINDOW \ - (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | \ - WS_MAXIMIZEBOX) -#define NT_WS_POPUPWINDOW (WS_POPUP | WS_BORDER | WS_SYSMENU) -#define NT_WS_CHILDWINDOW (WS_CHILD) - -#define NT_WS_EX_DLGMODALFRAME 0x00000001 -#define NT_WS_EX_NOPARENTNOTIFY 0x00000004 -#define NT_WS_EX_TOPMOST 0x00000008 -#define NT_WS_EX_ACCEPTFILES 0x00000010 -#define NT_WS_EX_TRANSPARENT 0x00000020 -#define NT_WS_EX_MDICHILD 0x00000040 -#define NT_WS_EX_TOOLWINDOW 0x00000080 -#define NT_WS_EX_WINDOWEDGE 0x00000100 -#define NT_WS_EX_CLIENTEDGE 0x00000200 -#define NT_WS_EX_CONTEXTHELP 0x00000400 -#define NT_WS_EX_RIGHT 0x00001000 -#define NT_WS_EX_LEFT 0x00000000 -#define NT_WS_EX_RTLREADING 0x00002000 -#define NT_WS_EX_LTRREADING 0x00000000 -#define NT_WS_EX_LEFTSCROLLBAR 0x00004000 -#define NT_WS_EX_RIGHTSCROLLBAR 0x00000000 -#define NT_WS_EX_CONTROLPARENT 0x00010000 -#define NT_WS_EX_STATICEDGE 0x00020000 -#define NT_WS_EX_APPWINDOW 0x00040000 -#define NT_WS_EX_OVERLAPPEDWINDOW (WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE) -#define NT_WS_EX_PALETTEWINDOW \ - (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW | WS_EX_TOPMOST) -#define NT_WS_EX_LAYERED 0x00080000 -#define NT_WS_EX_NOINHERITLAYOUT 0x00100000 -#define NT_WS_EX_LAYOUTRTL 0x00400000 -#define NT_WS_EX_COMPOSITED 0x02000000 -#define NT_WS_EX_NOACTIVATE 0x08000000 - -#define NT_CS_VREDRAW 0x0001 -#define NT_CS_HREDRAW 0x0002 -#define NT_CS_DBLCLKS 0x0008 -#define NT_CS_OWNDC 0x0020 -#define NT_CS_CLASSDC 0x0040 -#define NT_CS_PARENTDC 0x0080 -#define NT_CS_NOCLOSE 0x0200 -#define NT_CS_SAVEBITS 0x0800 -#define NT_CS_BYTEALIGNCLIENT 0x1000 -#define NT_CS_BYTEALIGNWINDOW 0x2000 -#define NT_CS_GLOBALCLASS 0x4000 -#define NT_CS_IME 0x00010000 -#define NT_CS_DROPSHADOW 0x00020000 - -#define NT_SWP_NOSIZE 0x0001 -#define NT_SWP_NOMOVE 0x0002 -#define NT_SWP_NOZORDER 0x0004 -#define NT_SWP_NOREDRAW 0x0008 -#define NT_SWP_NOACTIVATE 0x0010 -#define NT_SWP_FRAMECHANGED 0x0020 -#define NT_SWP_SHOWWINDOW 0x0040 -#define NT_SWP_HIDEWINDOW 0x0080 -#define NT_SWP_NOCOPYBITS 0x0100 -#define NT_SWP_NOOWNERZORDER 0x0200 -#define NT_SWP_NOSENDCHANGING 0x0400 -#define NT_SWP_DRAWFRAME SWP_FRAMECHANGED -#define NT_SWP_NOREPOSITION SWP_NOOWNERZORDER -#define NT_SWP_DEFERERASE 0x2000 -#define NT_SWP_ASYNCWINDOWPOS 0x4000 - -#define NT_RI_MOUSE_LEFT_BUTTON_DOWN 0x0001 -#define NT_RI_MOUSE_LEFT_BUTTON_UP 0x0002 -#define NT_RI_MOUSE_RIGHT_BUTTON_DOWN 0x0004 -#define NT_RI_MOUSE_RIGHT_BUTTON_UP 0x0008 -#define NT_RI_MOUSE_MIDDLE_BUTTON_DOWN 0x0010 -#define NT_RI_MOUSE_MIDDLE_BUTTON_UP 0x0020 -#define NT_RI_MOUSE_BUTTON_1_DOWN RI_MOUSE_LEFT_BUTTON_DOWN -#define NT_RI_MOUSE_BUTTON_1_UP RI_MOUSE_LEFT_BUTTON_UP -#define NT_RI_MOUSE_BUTTON_2_DOWN RI_MOUSE_RIGHT_BUTTON_DOWN -#define NT_RI_MOUSE_BUTTON_2_UP RI_MOUSE_RIGHT_BUTTON_UP -#define NT_RI_MOUSE_BUTTON_3_DOWN RI_MOUSE_MIDDLE_BUTTON_DOWN -#define NT_RI_MOUSE_BUTTON_3_UP RI_MOUSE_MIDDLE_BUTTON_UP -#define NT_RI_MOUSE_BUTTON_4_DOWN 0x0040 -#define NT_RI_MOUSE_BUTTON_4_UP 0x0080 -#define NT_RI_MOUSE_BUTTON_5_DOWN 0x0100 -#define NT_RI_MOUSE_BUTTON_5_UP 0x0200 -#define NT_RI_MOUSE_WHEEL 0x0400 -#define NT_MOUSE_MOVE_RELATIVE 0 -#define NT_MOUSE_MOVE_ABSOLUTE 1 -#define NT_MOUSE_VIRTUAL_DESKTOP 0x02 -#define NT_MOUSE_ATTRIBUTES_CHANGED 0x04 - -#define NT_STATE_SYSTEM_UNAVAILABLE 0x00000001 -#define NT_STATE_SYSTEM_SELECTED 0x00000002 -#define NT_STATE_SYSTEM_FOCUSED 0x00000004 -#define NT_STATE_SYSTEM_PRESSED 0x00000008 -#define NT_STATE_SYSTEM_CHECKED 0x00000010 -#define NT_STATE_SYSTEM_MIXED 0x00000020 -#define NT_STATE_SYSTEM_INDETERMINATE STATE_SYSTEM_MIXED -#define NT_STATE_SYSTEM_READONLY 0x00000040 -#define NT_STATE_SYSTEM_HOTTRACKED 0x00000080 -#define NT_STATE_SYSTEM_DEFAULT 0x00000100 -#define NT_STATE_SYSTEM_EXPANDED 0x00000200 -#define NT_STATE_SYSTEM_COLLAPSED 0x00000400 -#define NT_STATE_SYSTEM_BUSY 0x00000800 -#define NT_STATE_SYSTEM_FLOATING 0x00001000 -#define NT_STATE_SYSTEM_MARQUEED 0x00002000 -#define NT_STATE_SYSTEM_ANIMATED 0x00004000 -#define NT_STATE_SYSTEM_INVISIBLE 0x00008000 -#define NT_STATE_SYSTEM_OFFSCREEN 0x00010000 -#define NT_STATE_SYSTEM_SIZEABLE 0x00020000 -#define NT_STATE_SYSTEM_MOVEABLE 0x00040000 -#define NT_STATE_SYSTEM_SELFVOICING 0x00080000 -#define NT_STATE_SYSTEM_FOCUSABLE 0x00100000 -#define NT_STATE_SYSTEM_SELECTABLE 0x00200000 -#define NT_STATE_SYSTEM_LINKED 0x00400000 -#define NT_STATE_SYSTEM_TRAVERSED 0x00800000 -#define NT_STATE_SYSTEM_MULTISELECTABLE 0x01000000 -#define NT_STATE_SYSTEM_EXTSELECTABLE 0x02000000 -#define NT_STATE_SYSTEM_ALERT_LOW 0x04000000 -#define NT_STATE_SYSTEM_ALERT_MEDIUM 0x08000000 -#define NT_STATE_SYSTEM_ALERT_HIGH 0x10000000 -#define NT_STATE_SYSTEM_PROTECTED 0x20000000 -#define NT_STATE_SYSTEM_VALID 0x3FFFFFFF - -#define NT_IDH_NO_HELP 28440 -#define NT_IDH_MISSING_CONTEXT 28441 -#define NT_IDH_GENERIC_HELP_BUTTON 28442 -#define NT_IDH_OK 28443 -#define NT_IDH_CANCEL 28444 -#define NT_IDH_HELP 28445 - -#define NT_SS_LEFT 0x00000000 -#define NT_SS_CENTER 0x00000001 -#define NT_SS_RIGHT 0x00000002 -#define NT_SS_ICON 0x00000003 -#define NT_SS_BLACKRECT 0x00000004 -#define NT_SS_GRAYRECT 0x00000005 -#define NT_SS_WHITERECT 0x00000006 -#define NT_SS_BLACKFRAME 0x00000007 -#define NT_SS_GRAYFRAME 0x00000008 -#define NT_SS_WHITEFRAME 0x00000009 -#define NT_SS_USERITEM 0x0000000A -#define NT_SS_SIMPLE 0x0000000B -#define NT_SS_LEFTNOWORDWRAP 0x0000000C -#define NT_SS_OWNERDRAW 0x0000000D -#define NT_SS_BITMAP 0x0000000E -#define NT_SS_ENHMETAFILE 0x0000000F -#define NT_SS_ETCHEDHORZ 0x00000010 -#define NT_SS_ETCHEDVERT 0x00000011 -#define NT_SS_ETCHEDFRAME 0x00000012 -#define NT_SS_TYPEMASK 0x0000001F -#define NT_SS_REALSIZECONTROL 0x00000040 -#define NT_SS_NOPREFIX 0x00000080 -#define NT_SS_NOTIFY 0x00000100 -#define NT_SS_CENTERIMAGE 0x00000200 -#define NT_SS_RIGHTJUST 0x00000400 -#define NT_SS_REALSIZEIMAGE 0x00000800 -#define NT_SS_SUNKEN 0x00001000 -#define NT_SS_EDITCONTROL 0x00002000 -#define NT_SS_ENDELLIPSIS 0x00004000 -#define NT_SS_PATHELLIPSIS 0x00008000 -#define NT_SS_WORDELLIPSIS 0x0000C000 -#define NT_SS_ELLIPSISMASK 0x0000C000 - -#define NT_BST_UNCHECKED 0x0000 -#define NT_BST_CHECKED 0x0001 -#define NT_BST_INDETERMINATE 0x0002 -#define NT_BST_PUSHED 0x0004 -#define NT_BST_FOCUS 0x0008 - -#define NT_BS_PUSHBUTTON 0x00000000 -#define NT_BS_DEFPUSHBUTTON 0x00000001 -#define NT_BS_CHECKBOX 0x00000002 -#define NT_BS_AUTOCHECKBOX 0x00000003 -#define NT_BS_RADIOBUTTON 0x00000004 -#define NT_BS_3STATE 0x00000005 -#define NT_BS_AUTO3STATE 0x00000006 -#define NT_BS_GROUPBOX 0x00000007 -#define NT_BS_USERBUTTON 0x00000008 -#define NT_BS_AUTORADIOBUTTON 0x00000009 -#define NT_BS_PUSHBOX 0x0000000A -#define NT_BS_OWNERDRAW 0x0000000B -#define NT_BS_TYPEMASK 0x0000000F -#define NT_BS_LEFTTEXT 0x00000020 -#define NT_BS_TEXT 0x00000000 -#define NT_BS_ICON 0x00000040 -#define NT_BS_BITMAP 0x00000080 -#define NT_BS_LEFT 0x00000100 -#define NT_BS_RIGHT 0x00000200 -#define NT_BS_CENTER 0x00000300 -#define NT_BS_TOP 0x00000400 -#define NT_BS_BOTTOM 0x00000800 -#define NT_BS_VCENTER 0x00000C00 -#define NT_BS_PUSHLIKE 0x00001000 -#define NT_BS_MULTILINE 0x00002000 -#define NT_BS_NOTIFY 0x00004000 -#define NT_BS_FLAT 0x00008000 -#define NT_BS_RIGHTBUTTON BS_LEFTTEXT - -#define NT_BN_CLICKED 0 -#define NT_BN_PAINT 1 -#define NT_BN_HILITE 2 -#define NT_BN_UNHILITE 3 -#define NT_BN_DISABLE 4 -#define NT_BN_DOUBLECLICKED 5 -#define NT_BN_PUSHED BN_HILITE -#define NT_BN_UNPUSHED BN_UNHILITE -#define NT_BN_DBLCLK BN_DOUBLECLICKED -#define NT_BN_SETFOCUS 6 -#define NT_BN_KILLFOCUS 7 - -#define NT_BM_GETCHECK 0x00F0 -#define NT_BM_SETCHECK 0x00F1 -#define NT_BM_GETSTATE 0x00F2 -#define NT_BM_SETSTATE 0x00F3 -#define NT_BM_SETSTYLE 0x00F4 -#define NT_BM_CLICK 0x00F5 -#define NT_BM_GETIMAGE 0x00F6 -#define NT_BM_SETIMAGE 0x00F7 - -#define NT_GUI_CARETBLINKING 0x00000001 -#define NT_GUI_INMOVESIZE 0x00000002 -#define NT_GUI_INMENUMODE 0x00000004 -#define NT_GUI_SYSTEMMENUMODE 0x00000008 -#define NT_GUI_POPUPMENUMODE 0x00000010 -#define NT_GUI_16BITTASK 0x00000020 - -#define NT_ALERT_SYSTEM_INFORMATIONAL 1 -#define NT_ALERT_SYSTEM_WARNING 2 -#define NT_ALERT_SYSTEM_ERROR 3 -#define NT_ALERT_SYSTEM_QUERY 4 -#define NT_ALERT_SYSTEM_CRITICAL 5 - -#define NT_SOUND_SYSTEM_STARTUP 1 -#define NT_SOUND_SYSTEM_SHUTDOWN 2 -#define NT_SOUND_SYSTEM_BEEP 3 -#define NT_SOUND_SYSTEM_ERROR 4 -#define NT_SOUND_SYSTEM_QUESTION 5 -#define NT_SOUND_SYSTEM_WARNING 6 -#define NT_SOUND_SYSTEM_INFORMATION 7 -#define NT_SOUND_SYSTEM_MAXIMIZE 8 -#define NT_SOUND_SYSTEM_MINIMIZE 9 -#define NT_SOUND_SYSTEM_RESTOREUP 10 -#define NT_SOUND_SYSTEM_RESTOREDOWN 11 -#define NT_SOUND_SYSTEM_APPSTART 12 -#define NT_SOUND_SYSTEM_FAULT 13 -#define NT_SOUND_SYSTEM_APPEND 14 -#define NT_SOUND_SYSTEM_MENUCOMMAND 15 -#define NT_SOUND_SYSTEM_MENUPOPUP 16 -#define NT_CSOUND_SYSTEM 16 - #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ int64_t CreateWindowEx(uint32_t dwExStyle, const char16_t *lpClassName, const char16_t *lpWindowName, uint32_t dwStyle, int X, int Y, int nWidth, int nHeight, int64_t hWndParent, - int64_t hMenu, int64_t hInstance, void *lpParam); + int64_t hMenu, int64_t hInstance, int64_t lpParam); + +uint16_t RegisterClass(const struct NtWndClass *lpWndClass); + +int64_t DefWindowProc(int64_t hWnd, uint32_t Msg, uint64_t wParam, + int64_t lParam); + int32_t CloseWindow(int64_t hWnd); int32_t DestroyWindow(int64_t hWnd); -int32_t ShowWindow(int64_t hWnd, int nCmdShow); +int32_t ShowWindow(int64_t hWnd, int sw); +int32_t ShowCursor(bool32 bShow); +int64_t LoadCursor(int64_t opt_hInstance, const char16_t *lpCursorNameOrIdc); +int32_t ShowCaret(bool32 bShow); int32_t AnimateWindow(int64_t hWnd, uint32_t dwTime, uint32_t dwFlags); int64_t LoadIcon(int64_t hInstance, const char16_t *lpIconName); int32_t IsWindow(int64_t hWnd); @@ -360,7 +65,7 @@ int32_t SetWindowPos(int64_t hWnd, int64_t hWndInsertAfter, int X, int Y, uintptr_t SetTimer(int64_t opt_hWnd, uintptr_t nIDEvent, uint32_t uElapseMs, NtTimerProc lpTimerFunc); -int KillTimer(int64_t hWnd, uintptr_t uIDEvent); +int32_t KillTimer(int64_t hWnd, uintptr_t uIDEvent); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/runtime/_exit.S b/libc/runtime/_exit.S index 28192d74..458333d1 100644 --- a/libc/runtime/_exit.S +++ b/libc/runtime/_exit.S @@ -28,10 +28,13 @@ / @param edi is exit code ∈ [0,256) / @note _exit() is same thing / @asyncsignalsafe -_Exit: orl $RUNSTATE_TERMINATE,g_runstate(%rip) +_Exit: push %rbp + mov %rsp,%rbp + orl $RUNSTATE_TERMINATE,g_runstate(%rip) #if SupportsWindows() testb IsWindows() jz 1f + sub $32,%rsp movzbl %dil,%ecx # %ERRORLEVEL% is limitless 4: call *__imp_ExitProcess(%rip) jmp 4b diff --git a/libc/runtime/arememoryintervalsok.c b/libc/runtime/arememoryintervalsok.c index e05fa60e..3695e220 100644 --- a/libc/runtime/arememoryintervalsok.c +++ b/libc/runtime/arememoryintervalsok.c @@ -25,7 +25,7 @@ bool AreMemoryIntervalsOk(const struct MemoryIntervals *mm) { for (i = 0; i < mm->i; ++i) { if (mm->p[i].y < mm->p[i].x) return false; if (i) { - if (mm->h[i] || mm->h[i - 1]) { + if (mm->p[i].h || mm->p[i - 1].h) { if (mm->p[i].x <= mm->p[i - 1].y) return false; } else { if (mm->p[i].x <= mm->p[i - 1].y + 1) return false; diff --git a/libc/runtime/directmap.c b/libc/runtime/directmap.c index 8ffcbeae..c338e666 100644 --- a/libc/runtime/directmap.c +++ b/libc/runtime/directmap.c @@ -17,42 +17,10 @@ │ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ │ 02110-1301 USA │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/calls.h" #include "libc/calls/internal.h" -#include "libc/macros.h" -#include "libc/nt/memory.h" #include "libc/nt/runtime.h" #include "libc/runtime/directmap.h" -static textwindows struct DirectMap DirectMapNt(void *addr, size_t size, - unsigned prot, unsigned flags, - int fd, int64_t off) { - int64_t handle; - struct DirectMap res; - uint32_t protect, access; - if (fd != -1) { - handle = g_fds.p[fd].handle; - } else { - handle = kNtInvalidHandleValue; - } - protect = prot2nt(prot, flags); - access = fprot2nt(prot, flags); - if ((res.maphandle = - CreateFileMappingNuma(handle, NULL, protect, size >> 32, size, NULL, - kNtNumaNoPreferredNode))) { - if (!(res.addr = MapViewOfFileExNuma(res.maphandle, access, off >> 32, off, - size, addr, kNtNumaNoPreferredNode))) { - CloseHandle(res.maphandle); - res.maphandle = kNtInvalidHandleValue; - res.addr = (void *)(intptr_t)winerr(); - } - } else { - res.maphandle = kNtInvalidHandleValue; - res.addr = (void *)(intptr_t)winerr(); - } - return res; -} - struct DirectMap DirectMap(void *addr, size_t size, unsigned prot, unsigned flags, int fd, int64_t off) { if (!IsWindows()) { diff --git a/libc/runtime/directmap.h b/libc/runtime/directmap.h index 204838b9..903aacbb 100644 --- a/libc/runtime/directmap.h +++ b/libc/runtime/directmap.h @@ -9,6 +9,7 @@ struct DirectMap { }; struct DirectMap DirectMap(void *, size_t, unsigned, unsigned, int, int64_t); +struct DirectMap DirectMapNt(void *, size_t, unsigned, unsigned, int, int64_t); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/runtime/directmapnt.c b/libc/runtime/directmapnt.c new file mode 100644 index 00000000..dea746d3 --- /dev/null +++ b/libc/runtime/directmapnt.c @@ -0,0 +1,51 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/nt/memory.h" +#include "libc/nt/runtime.h" +#include "libc/runtime/directmap.h" + +textwindows struct DirectMap DirectMapNt(void *addr, size_t size, unsigned prot, + unsigned flags, int fd, int64_t off) { + int64_t handle; + struct DirectMap res; + uint32_t protect, access; + if (fd != -1) { + handle = g_fds.p[fd].handle; + } else { + handle = kNtInvalidHandleValue; + } + protect = prot2nt(prot, flags); + access = fprot2nt(prot, flags); + if ((res.maphandle = + CreateFileMappingNuma(handle, NULL, protect, size >> 32, size, NULL, + kNtNumaNoPreferredNode))) { + if (!(res.addr = MapViewOfFileExNuma(res.maphandle, access, off >> 32, off, + size, addr, kNtNumaNoPreferredNode))) { + CloseHandle(res.maphandle); + res.maphandle = kNtInvalidHandleValue; + res.addr = (void *)(intptr_t)winerr(); + } + } else { + res.maphandle = kNtInvalidHandleValue; + res.addr = (void *)(intptr_t)winerr(); + } + return res; +} diff --git a/libc/runtime/getdosargv.c b/libc/runtime/getdosargv.c index c48a0c8e..f468dfba 100644 --- a/libc/runtime/getdosargv.c +++ b/libc/runtime/getdosargv.c @@ -27,12 +27,6 @@ #include "libc/str/tpenc.h" #include "libc/str/utf16.h" -/* TODO(jart): Make early-stage data structures happen. */ -#undef isspace -#undef iswspace -#define isspace(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r') -#define iswspace(c) isspace(c) - struct DosArgv { const char16_t *s; char *p; diff --git a/libc/runtime/internal.h b/libc/runtime/internal.h index 34447bed..e1bd32ce 100644 --- a/libc/runtime/internal.h +++ b/libc/runtime/internal.h @@ -25,6 +25,7 @@ void *__cxa_finalize(void *) hidden; void _executive(int, char **, char **, long (*)[2]) hidden noreturn; void __stack_chk_fail(void) noreturn relegated; void __stack_chk_fail_local(void) noreturn relegated hidden; +void _jmpstack(void *, void *, ...) hidden noreturn; long _setstack(void *, void *, ...) hidden; int GetDosArgv(const char16_t *, char *, size_t, char **, size_t) hidden; diff --git a/libc/runtime/jmpstack.S b/libc/runtime/jmpstack.S new file mode 100644 index 00000000..620dc5d8 --- /dev/null +++ b/libc/runtime/jmpstack.S @@ -0,0 +1,38 @@ +/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│ +│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/macros.h" + +/ Switches stack. +/ +/ @param rdi is new rsp, passed as malloc(size) + size +/ @param rsi is function to call in new stack space +/ @param rdx,rcx,r8,r9 get passed as args to rsi +/ @noreturn +_jmpstack: + mov %rdi,%rsp + mov %rsi,%rax + mov %rdx,%rdi + mov %rcx,%rsi + mov %r8,%rdx + mov %r9,%rcx + xor %rbp,%rbp + call *%rax + ud2 + .endfn _jmpstack,globl,hidden diff --git a/libc/runtime/memtrack.c b/libc/runtime/memtrack.c index 953d8691..64bfd1ff 100644 --- a/libc/runtime/memtrack.c +++ b/libc/runtime/memtrack.c @@ -30,8 +30,6 @@ static void RemoveMemoryIntervals(struct MemoryIntervals *mm, int i, int n) { assert(i + n <= mm->i); memcpy(mm->p + i, mm->p + i + n, (intptr_t)(mm->p + mm->i) - (intptr_t)(mm->p + i + n)); - memcpy(mm->h + i, mm->h + i + n, - (intptr_t)(mm->h + mm->i) - (intptr_t)(mm->h + i + n)); mm->i -= n; } @@ -41,8 +39,6 @@ static void CreateMemoryInterval(struct MemoryIntervals *mm, int i) { assert(mm->i < ARRAYLEN(mm->p)); memmove(mm->p + i + 1, mm->p + i, (intptr_t)(mm->p + mm->i) - (intptr_t)(mm->p + i)); - memmove(mm->h + i + 1, mm->h + i, - (intptr_t)(mm->h + mm->i) - (intptr_t)(mm->h + i)); ++mm->i; } @@ -94,25 +90,31 @@ int ReleaseMemoryIntervals(struct MemoryIntervals *mm, int x, int y, return 0; } -int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h) { +int TrackMemoryInterval(struct MemoryIntervals *mm, int x, int y, long h, + int prot, int flags) { unsigned i; assert(y >= x); assert(AreMemoryIntervalsOk(mm)); i = FindMemoryInterval(mm, x); - if (i && x == mm->p[i - 1].y + 1 && h == mm->h[i - 1]) { + if (i && x == mm->p[i - 1].y + 1 && h == mm->p[i - 1].h && + prot == mm->p[i - 1].prot && flags == mm->p[i - 1].flags) { mm->p[i - 1].y = y; - if (i < mm->i && y + 1 == mm->p[i].x && h == mm->h[i]) { + if (i < mm->i && y + 1 == mm->p[i].x && h == mm->p[i].h && + prot == mm->p[i].prot && flags == mm->p[i].flags) { mm->p[i - 1].y = mm->p[i].y; RemoveMemoryIntervals(mm, i, 1); } - } else if (i < mm->i && y + 1 == mm->p[i].x && h == mm->h[i]) { + } else if (i < mm->i && y + 1 == mm->p[i].x && h == mm->p[i].h && + prot == mm->p[i].prot && flags == mm->p[i].flags) { mm->p[i].x = x; } else { if (mm->i == ARRAYLEN(mm->p)) return enomem(); CreateMemoryInterval(mm, i); mm->p[i].x = x; mm->p[i].y = y; - mm->h[i] = h; + mm->p[i].h = h; + mm->p[i].prot = prot; + mm->p[i].flags = flags; } return 0; } diff --git a/libc/runtime/memtrack.h b/libc/runtime/memtrack.h index 3f7e4274..40c734f8 100644 --- a/libc/runtime/memtrack.h +++ b/libc/runtime/memtrack.h @@ -14,8 +14,10 @@ struct MemoryIntervals { struct MemoryInterval { int x; int y; + long h; + int prot; + int flags; } p[128]; - long h[128]; }; extern struct MemoryIntervals _mmi; @@ -23,7 +25,7 @@ extern struct MemoryIntervals _mmi; unsigned FindMemoryInterval(const struct MemoryIntervals *, int) nosideeffect; bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect; void PrintMemoryIntervals(int, const struct MemoryIntervals *); -int TrackMemoryInterval(struct MemoryIntervals *, int, int, long); +int TrackMemoryInterval(struct MemoryIntervals *, int, int, long, int, int); int ReleaseMemoryIntervals(struct MemoryIntervals *, int, int, void (*)(struct MemoryIntervals *, int, int)); void ReleaseMemoryNt(struct MemoryIntervals *, int, int); diff --git a/libc/runtime/memtracknt.c b/libc/runtime/memtracknt.c index eb738e75..81f8aa89 100644 --- a/libc/runtime/memtracknt.c +++ b/libc/runtime/memtracknt.c @@ -35,7 +35,7 @@ void ReleaseMemoryNt(struct MemoryIntervals *mm, int l, int r) { for (i = l; i <= r; ++i) { ok = UnmapViewOfFile(GetFrameAddr(mm->p[i].x)); assert(ok); - ok = CloseHandle(mm->h[i]); + ok = CloseHandle(mm->p[i].h); assert(ok); } } diff --git a/libc/runtime/mmap.c b/libc/runtime/mmap.c index bef9d55e..e16c4c76 100644 --- a/libc/runtime/mmap.c +++ b/libc/runtime/mmap.c @@ -39,8 +39,6 @@ #define ALIGNED(p) (!(IP(p) & (FRAMESIZE - 1))) #define CANONICAL(p) (-0x800000000000 <= IP(p) && IP(p) <= 0x7fffffffffff) -struct MemoryIntervals _mmi; - /** * Beseeches system for page-table entries. * @@ -92,7 +90,7 @@ void *mmap(void *addr, size_t size, int prot, int flags, int fd, int64_t off) { } a = ROUNDDOWN((intptr_t)addr, FRAMESIZE) >> 16; b = ROUNDDOWN((intptr_t)addr + size - 1, FRAMESIZE) >> 16; - if (TrackMemoryInterval(&_mmi, a, b, dm.maphandle) == -1) { + if (TrackMemoryInterval(&_mmi, a, b, dm.maphandle, prot, flags) == -1) { abort(); } if (weaken(__asan_map_shadow)) { diff --git a/libc/runtime/mmi.c b/libc/runtime/mmi.c new file mode 100644 index 00000000..170a12ef --- /dev/null +++ b/libc/runtime/mmi.c @@ -0,0 +1,22 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/runtime/memtrack.h" + +struct MemoryIntervals _mmi; diff --git a/libc/runtime/msync-nt.c b/libc/runtime/msync-nt.c index e646b85e..0fc4fd4a 100644 --- a/libc/runtime/msync-nt.c +++ b/libc/runtime/msync-nt.c @@ -30,7 +30,7 @@ textwindows int msync$nt(void *addr, size_t size, int flags) { for (i = FindMemoryInterval(&_mmi, x); i < _mmi.i; ++i) { if ((x >= _mmi.p[i].x && x <= _mmi.p[i].y) || (y >= _mmi.p[i].x && y <= _mmi.p[i].y)) { - FlushFileBuffers(_mmi.h[i]); + FlushFileBuffers(_mmi.p[i].h); } else { break; } diff --git a/libc/runtime/runtime.h b/libc/runtime/runtime.h index a185c093..5ccae782 100644 --- a/libc/runtime/runtime.h +++ b/libc/runtime/runtime.h @@ -12,7 +12,6 @@ extern int g_argc; /* CRT */ extern char **g_argv; /* CRT */ extern char **environ; /* CRT */ extern unsigned long *g_auxv; /* CRT */ -extern jmp_buf g_winmain; /* CRT */ extern char *program_invocation_name; /* RII */ extern char *program_invocation_short_name; /* RII */ extern uint64_t g_syscount; /* RII */ diff --git a/libc/runtime/runtime.mk b/libc/runtime/runtime.mk index 0625f4b0..20a384ba 100644 --- a/libc/runtime/runtime.mk +++ b/libc/runtime/runtime.mk @@ -64,11 +64,6 @@ $(LIBC_RUNTIME_A_OBJS): \ OVERRIDE_CFLAGS += \ $(NO_MAGIC) -# @see ape/ape.s for tuning parameters that make this safe -o/$(MODE)/libc/runtime/winmain.greg.o: \ - DEFAULT_CPPFLAGS += \ - -DSTACK_FRAME_UNLIMITED - LIBC_RUNTIME_LIBS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x))) LIBC_RUNTIME_SRCS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_SRCS)) LIBC_RUNTIME_HDRS = $(foreach x,$(LIBC_RUNTIME_ARTIFACTS),$($(x)_HDRS)) diff --git a/libc/runtime/winmain.greg.c b/libc/runtime/winmain.greg.c index 3b4a099a..012837ac 100644 --- a/libc/runtime/winmain.greg.c +++ b/libc/runtime/winmain.greg.c @@ -20,7 +20,10 @@ #include "libc/bits/bits.h" #include "libc/bits/pushpop.h" #include "libc/bits/weaken.h" +#include "libc/calls/internal.h" #include "libc/dce.h" +#include "libc/fmt/fmt.h" +#include "libc/macros.h" #include "libc/nt/console.h" #include "libc/nt/enum/consolemodeflags.h" #include "libc/nt/enum/filetype.h" @@ -34,8 +37,21 @@ #include "libc/nt/struct/teb.h" #include "libc/runtime/getdosenviron.h" #include "libc/runtime/internal.h" +#include "libc/runtime/memtrack.h" #include "libc/runtime/missioncritical.h" #include "libc/runtime/runtime.h" +#include "libc/runtime/winmain.h" +#include "libc/sock/internal.h" +#include "libc/sysv/consts/map.h" +#include "libc/sysv/consts/prot.h" + +struct WinArgs { + char *argv[512]; + char *envp[512]; + long auxv[1][2]; + char argblock[ARG_MAX]; + char envblock[ENV_MAX]; +}; static struct CmdExe { bool result; @@ -46,13 +62,7 @@ static struct CmdExe { } oldin, oldout; } g_cmdexe; -static textwindows void MitigateDriveByDownloads(void) { - unsigned wrote; - if (!SetDefaultDllDirectories(kNtLoadLibrarySearchSearchSystem32)) { - WriteFile(GetStdHandle(kNtStdErrorHandle), "nodll\n", 6, &wrote, NULL); - ExitProcess(1); - } -} +struct WinMain g_winmain; static textwindows void RestoreCmdExe(void) { if (g_cmdexe.oldin.handle) { @@ -104,6 +114,53 @@ static textwindows void NormalizeCmdExe(void) { } } +static textwindows char *AllocateMemory(void *addr, size_t size, int64_t *h) { + return MapViewOfFileExNuma( + (*h = CreateFileMappingNuma(-1, NULL, pushpop(kNtPageReadwrite), 0, size, + NULL, kNtNumaNoPreferredNode)), + kNtFileMapRead | kNtFileMapWrite, 0, 0, size, addr, + kNtNumaNoPreferredNode); +} + +static textwindows noreturn void WinMainNew(int64_t hInstance, + int64_t hPrevInstance, + const char *lpCmdLine, + int nCmdShow) { + int64_t h; + size_t size; + int i, count; + uint64_t data; + struct WinArgs *wa; + const char16_t *env16; + g_winmain.nCmdShow = nCmdShow; + g_winmain.hInstance = hInstance; + g_winmain.hPrevInstance = hPrevInstance; + NormalizeCmdExe(); + *(/*unconst*/ int *)&hostos = WINDOWS; + size = ROUNDUP(STACKSIZE + sizeof(struct WinArgs), FRAMESIZE); + data = 0x777000000000; + data = (intptr_t)AllocateMemory((char *)data, size, &_mmi.p[0].h); + _mmi.p[0].x = data >> 16; + _mmi.p[0].y = (data >> 16) + ((size >> 16) - 1); + _mmi.p[0].prot = PROT_READ | PROT_WRITE; + _mmi.p[0].flags = MAP_PRIVATE | MAP_ANONYMOUS; + _mmi.i = pushpop(1L); + wa = (struct WinArgs *)(data + size - sizeof(struct WinArgs)); + count = GetDosArgv(GetCommandLine(), wa->argblock, ARG_MAX, wa->argv, 512); + for (i = 0; wa->argv[0][i]; ++i) { + if (wa->argv[0][i] == '\\') { + wa->argv[0][i] = '/'; + } + } + env16 = GetEnvironmentStrings(); + GetDosEnviron(env16, wa->envblock, ENV_MAX, wa->envp, 512); + FreeEnvironmentStrings(env16); + wa->auxv[0][0] = pushpop(0L); + wa->auxv[0][1] = pushpop(0L); + _jmpstack((char *)data + STACKSIZE, _executive, count, wa->argv, wa->envp, + wa->auxv); +} + /** * Main function on Windows NT. * @@ -130,30 +187,15 @@ static textwindows void NormalizeCmdExe(void) { * the downloads folder. Since we don't even use dynamic linking, * we've cargo culted some API calls, that may harden against it. * + * 6. Finally, we need fork. Microsoft designed Windows to prevent us + * from having fork() so we pass pipe handles in an environment + * variable literally copy all the memory. + * */ -textwindows int WinMain(void *hInstance, void *hPrevInstance, - const char *lpCmdLine, int nCmdShow) { - char *stack; - int i, count; - const char16_t *cmd16, *env16; - char *argv[512], *envp[512]; - char argblock[ARG_MAX], envblock[ENV_MAX]; - long auxv[][2] = {{pushpop(0L), pushpop(0L)}}; - MitigateDriveByDownloads(); - NormalizeCmdExe(); - *(/*unconst*/ int *)&hostos = WINDOWS; - cmd16 = GetCommandLine(); - env16 = GetEnvironmentStrings(); - count = GetDosArgv(cmd16, argblock, ARG_MAX, argv, 512); - for (i = 0; argv[0][i]; ++i) { - if (argv[0][i] == '\\') argv[0][i] = '/'; - } - GetDosEnviron(env16, envblock, ENV_MAX, envp, 512); - FreeEnvironmentStrings(env16); - stack = MapViewOfFileExNuma( - CreateFileMappingNuma(-1, NULL, pushpop(kNtPageReadwrite), 0, STACKSIZE, - NULL, kNtNumaNoPreferredNode), - kNtFileMapRead | kNtFileMapWrite, 0, 0, STACKSIZE, - (char *)0x777000000000 - STACKSIZE, kNtNumaNoPreferredNode); - return _setstack(stack + STACKSIZE, _executive, count, argv, envp, auxv); +textwindows int64_t WinMain(int64_t hInstance, int64_t hPrevInstance, + const char *lpCmdLine, int nCmdShow) { + SetDefaultDllDirectories(kNtLoadLibrarySearchSearchSystem32); + if (weaken(winsockinit)) weaken(winsockinit)(); + if (weaken(WinMainForked)) weaken(WinMainForked)(); + WinMainNew(hInstance, hPrevInstance, lpCmdLine, nCmdShow); } diff --git a/libc/runtime/winmain.h b/libc/runtime/winmain.h new file mode 100644 index 00000000..7a65c779 --- /dev/null +++ b/libc/runtime/winmain.h @@ -0,0 +1,16 @@ +#ifndef COSMOPOLITAN_LIBC_RUNTIME_WINMAIN_H_ +#define COSMOPOLITAN_LIBC_RUNTIME_WINMAIN_H_ +#if !(__ASSEMBLER__ + __LINKER__ + 0) +COSMOPOLITAN_C_START_ + +struct WinMain { + int nCmdShow; + int64_t hInstance; + int64_t hPrevInstance; +}; + +extern struct WinMain g_winmain; + +COSMOPOLITAN_C_END_ +#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ +#endif /* COSMOPOLITAN_LIBC_RUNTIME_WINMAIN_H_ */ diff --git a/libc/sock/accept-nt.c b/libc/sock/accept-nt.c index 0fb01eac..577daa23 100644 --- a/libc/sock/accept-nt.c +++ b/libc/sock/accept-nt.c @@ -34,9 +34,6 @@ textwindows int accept$nt(struct Fd *fd, void *addr, uint32_t *addrsize, if ((client = createfd()) == -1) return -1; if ((g_fds.p[client].handle = WSAAccept(fd->handle, addr, (int32_t *)addrsize, NULL, NULL)) != -1) { - if (flags & SOCK_CLOEXEC) { - SetHandleInformation(g_fds.p[client].handle, kNtHandleFlagInherit, 0); - } if (flags & SOCK_NONBLOCK) { yes = 1; if (__ioctlsocket$nt(g_fds.p[client].handle, FIONBIO, &yes) == -1) { diff --git a/libc/sock/internal.h b/libc/sock/internal.h index 0f4af900..7e767ec8 100644 --- a/libc/sock/internal.h +++ b/libc/sock/internal.h @@ -112,6 +112,7 @@ ssize_t sendto$nt(struct Fd *, const struct iovec *, size_t, uint32_t, void *, ssize_t recvfrom$nt(struct Fd *, const struct iovec *, size_t, uint32_t, void *, uint32_t *) hidden; +void winsockinit(void) hidden; int64_t winsockerr(void) nocallback hidden; int fixupnewsockfd$sysv(int, int) hidden; ssize_t WinSendRecv(int64_t, void *, size_t, uint32_t, struct sockaddr *, diff --git a/libc/sock/kntwsadata.c b/libc/sock/kntwsadata.c index 7f81fb13..a3782736 100644 --- a/libc/sock/kntwsadata.c +++ b/libc/sock/kntwsadata.c @@ -33,15 +33,15 @@ */ struct NtWsaData kNtWsaData; -textwindows static void winsockfini(void) { WSACleanup(); } -textstartup static void winsockinit(void) { - if (!IsWindows()) return; - atexit(winsockfini); +textwindows static void winsockfini(void) { + WSACleanup(); +} + +textwindows void winsockinit(void) { int rc; + atexit(winsockfini); if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 || kNtWsaData.wVersion != VERSION) { abort(); } } - -const void *const winsockctor[] initarray = {winsockinit}; diff --git a/libc/stdio/stdio.mk b/libc/stdio/stdio.mk index 8c7d8193..ac5dc334 100644 --- a/libc/stdio/stdio.mk +++ b/libc/stdio/stdio.mk @@ -28,6 +28,7 @@ LIBC_STDIO_A_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ + LIBC_CALLS_HEFTY \ LIBC_CONV \ LIBC_FMT \ LIBC_MEM \ diff --git a/libc/stdio/system.c b/libc/stdio/system.c index cadd81da..34bd4b3e 100644 --- a/libc/stdio/system.c +++ b/libc/stdio/system.c @@ -19,126 +19,12 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" -#include "libc/calls/internal.h" -#include "libc/mem/mem.h" -#include "libc/nt/accounting.h" -#include "libc/nt/enum/startf.h" -#include "libc/nt/enum/status.h" -#include "libc/nt/process.h" -#include "libc/nt/runtime.h" -#include "libc/nt/struct/processinformation.h" -#include "libc/nt/synchronization.h" +#include "libc/calls/hefty/spawn.h" +#include "libc/dce.h" +#include "libc/paths.h" +#include "libc/runtime/missioncritical.h" +#include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/fileno.h" -#include "libc/sysv/errfuns.h" - -#define SHELL_BIN "/bin/sh" -#define SHELL_ARG "-c" -#define CMD_C "CMD /C " - -static int system$sysv(const char *cmdline) { - int rc, n, wstatus; - struct mem { - char shell[sizeof(SHELL_BIN)]; - char arg[sizeof(SHELL_ARG)]; - char *args[4]; - char cmdline[]; - } * mem; - if (cmdline != NULL) { - mem = malloc(sizeof(struct mem) + (strlen(cmdline) + 1)); - if (!mem) return enomem(); - strcpy(mem->shell, SHELL_BIN); - strcpy(mem->arg, SHELL_ARG); - mem->args[0] = mem->shell; - mem->args[1] = mem->arg; - mem->args[2] = mem->cmdline; - mem->args[3] = NULL; - strcpy(mem->cmdline, cmdline); - if ((rc = vfork()) != -1) { - if (rc == 0) { - execve$sysv(mem->shell, mem->args, environ); - abort(); - } - if ((rc = wait4$sysv(rc, &wstatus, 0, NULL)) != -1) { - rc = wstatus; - } - } - free(mem); - return rc; - } else { - return fileexists(SHELL_BIN); - } -} - -static textwindows noinline int system$nt(const char *cmdline) { - char *mem; - int rc, status; - uint32_t dwExitCode; - struct NtStartupInfo startinfo; - struct NtProcessInformation *info; - uint16_t *cmdline16, *quotedcmdline16; - unsigned len, dosquotemultiplier, cmdline16bytes, quotedcmdline16bytes; - if (cmdline != NULL) { - rc = -1; - dosquotemultiplier = 2; - len = strlen(cmdline); - cmdline16bytes = (len + 1) * sizeof(uint16_t); - quotedcmdline16bytes = - strlen(CMD_C) * sizeof(uint16_t) + cmdline16bytes * dosquotemultiplier; - if (!(mem = malloc(sizeof(struct NtProcessInformation) + cmdline16bytes + - quotedcmdline16bytes))) { - return enomem(); - } - info = (struct NtProcessInformation *)mem; - cmdline16 = (uint16_t *)(mem + sizeof(struct NtProcessInformation)); - quotedcmdline16 = (uint16_t *)(mem + sizeof(struct NtProcessInformation) + - cmdline16bytes); - strcpyzbw(cmdline16, cmdline); - strcpyzbw(quotedcmdline16, CMD_C); - if (escapedos(quotedcmdline16 + strlen(CMD_C), len * dosquotemultiplier, - cmdline16, len)) { - memset(&startinfo, 0, sizeof(startinfo)); - startinfo.cb = sizeof(struct NtStartupInfo); - startinfo.dwFlags = kNtStartfUsestdhandles; - startinfo.hStdInput = STDIN_FILENO; - startinfo.hStdOutput = STDOUT_FILENO; - startinfo.hStdError = STDERR_FILENO; - if (CreateProcess( - /* lpApplicationName */ NULL, - /* lpCommandLine */ quotedcmdline16, - /* lpProcessAttributes */ NULL, - /* lpThreadAttributes */ NULL, - /* bInheritHandles */ true, - /* dwCreationFlags */ kNtCreateNoWindow, - /* lpEnvironment */ NULL, - /* lpCurrentDirectory */ NULL, - /* lpStartupInfo */ &startinfo, - /* lpProcessInformation */ info)) { - dwExitCode = kNtStillActive; - do { - WaitForSingleObject(info->hProcess, 0xffffffff); - } while ((status = GetExitCodeProcess(info->hProcess, &dwExitCode)) && - dwExitCode == kNtStillActive); - if (weaken(fflush)) { - weaken(fflush)(*weaken(stderr)); - } - rc = (dwExitCode & 0xff) << 8; /* @see WEXITSTATUS() */ - CloseHandle(info->hProcess); - CloseHandle(info->hThread); - } else { - rc = winerr(); - } - } else { - rc = einval(); - } - free(mem); - return rc; - } else { - /* how could cmd.exe not exist? */ - return true; - } -} /** * Launches program with system command interpreter. @@ -148,12 +34,24 @@ static textwindows noinline int system$nt(const char *cmdline) { * status that can be accessed using macros like WEXITSTATUS(s) */ int system(const char *cmdline) { - int rc; + const char *prog, *arg; + int rc, wstatus, fds[3]; if (weaken(fflush)) weaken(fflush)(NULL); - if (!IsWindows()) { - rc = system$sysv(cmdline); + if (cmdline) { + prog = !IsWindows() ? _PATH_BSHELL : "cmd"; + arg = !IsWindows() ? "-c" : "/C"; + fds[0] = 0; + fds[1] = 1; + fds[2] = 2; + if ((rc = spawnlp(0, fds, prog, prog, arg, cmdline, NULL)) != -1) { + if ((rc = wait4(rc, &wstatus, 0, NULL)) != -1) { + rc = wstatus; + } + } + return rc; + } else if (IsWindows()) { + return true; } else { - rc = system$nt(cmdline); + return fileexists(_PATH_BSHELL); } - return rc; } diff --git a/libc/sysv/sysv.mk b/libc/sysv/sysv.mk index 1e4bfa16..2e5ca328 100644 --- a/libc/sysv/sysv.mk +++ b/libc/sysv/sysv.mk @@ -34,7 +34,6 @@ LIBC_SYSV_A_FILES := \ libc/sysv/restorert.S \ libc/sysv/syscall.S \ libc/sysv/systemfive.S \ - libc/sysv/vfork.S \ $(wildcard libc/sysv/stubs/*) \ $(wildcard libc/sysv/consts/*) \ $(wildcard libc/sysv/errfuns/*) diff --git a/net/http/http.mk b/net/http/http.mk index 5b5c7898..50c58f83 100644 --- a/net/http/http.mk +++ b/net/http/http.mk @@ -59,11 +59,11 @@ o/$(MODE)/net/http/formathttpdatetime.o: \ OVERRIDE_CFLAGS += \ -O3 -ifeq (,$(MODE)) -$(NET_HTTP_A_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif +# ifeq (,$(MODE)) +# $(NET_HTTP_A_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif NET_HTTP_LIBS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x))) NET_HTTP_SRCS = $(foreach x,$(NET_HTTP_ARTIFACTS),$($(x)_SRCS)) diff --git a/test/ape/lib/test.mk b/test/ape/lib/test.mk index 58f57e45..77fb7cfe 100644 --- a/test/ape/lib/test.mk +++ b/test/ape/lib/test.mk @@ -50,9 +50,9 @@ o/$(MODE)/test/ape/lib/%.com.dbg: \ $(APE) @$(APELINK) -$(TEST_APE_LIB_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address +# $(TEST_APE_LIB_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address .PHONY: o/$(MODE)/test/ape/lib o/$(MODE)/test/ape/lib: $(TEST_APE_LIB_BINS) \ diff --git a/test/dsp/core/test.mk b/test/dsp/core/test.mk index 4fd9dab0..d30a38e0 100644 --- a/test/dsp/core/test.mk +++ b/test/dsp/core/test.mk @@ -47,13 +47,9 @@ o/$(MODE)/test/dsp/core/%.com.dbg: \ $(APE) @$(APELINK) -$(TEST_DSP_CORE_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address - -o/$(MODE)/test/dsp/core/getintegercoefficients8_test-gcc.asm: \ - OVERRIDE_CFLAGS += \ - -fsanitize=address +# $(TEST_DSP_CORE_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address .PHONY: o/$(MODE)/test/dsp/core o/$(MODE)/test/dsp/core: \ diff --git a/test/libc/intrin/test.mk b/test/libc/intrin/test.mk index 6942926d..bf7010ea 100644 --- a/test/libc/intrin/test.mk +++ b/test/libc/intrin/test.mk @@ -52,9 +52,9 @@ o/$(MODE)/test/libc/intrin/%.com.dbg: \ $(APE) @$(APELINK) -$(TEST_LIBC_INTRIN_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address +# $(TEST_LIBC_INTRIN_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address .PHONY: o/$(MODE)/test/libc/intrin o/$(MODE)/test/libc/intrin: \ diff --git a/test/libc/runtime/memtrack_test.c b/test/libc/runtime/memtrack_test.c index f3b0a524..f48fd275 100644 --- a/test/libc/runtime/memtrack_test.c +++ b/test/libc/runtime/memtrack_test.c @@ -31,7 +31,6 @@ static bool AreMemoryIntervalsEqual(const struct MemoryIntervals *mm1, const struct MemoryIntervals *mm2) { if (mm1->i != mm2->i) return false; if (memcmp(mm1->p, mm2->p, mm1->i * sizeof(*mm2->p)) != 0) return false; - if (memcmp(mm1->h, mm2->h, mm1->i * sizeof(*mm2->h)) != 0) return false; return true; } @@ -67,7 +66,7 @@ static void RunTrackMemoryIntervalTest(const struct MemoryIntervals t[2], int x, struct MemoryIntervals *mm; mm = memcpy(memalign(alignof(*t), sizeof(*t)), t, sizeof(*t)); CheckMemoryIntervalsAreOk(mm); - CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h)); + CHECK_NE(-1, TrackMemoryInterval(mm, x, y, h, 0, 0)); CheckMemoryIntervalsAreOk(mm); CheckMemoryIntervalsEqual(mm, t + 1); free(mm); @@ -86,8 +85,8 @@ static void RunReleaseMemoryIntervalsTest(const struct MemoryIntervals t[2], TEST(TrackMemoryInterval, TestEmpty) { static const struct MemoryIntervals mm[2] = { - {0, {}, {}}, - {1, {{2, 2}}, {0}}, + {0, {}}, + {1, {{2, 2, 0}}}, }; RunTrackMemoryIntervalTest(mm, 2, 2, 0); } @@ -98,10 +97,10 @@ TEST(TrackMemoryInterval, TestFull) { mm = calloc(1, sizeof(struct MemoryIntervals)); for (i = 0; i < ARRAYLEN(mm->p); ++i) { CheckMemoryIntervalsAreOk(mm); - CHECK_NE(-1, TrackMemoryInterval(mm, i, i, i)); + CHECK_NE(-1, TrackMemoryInterval(mm, i, i, i, 0, 0)); CheckMemoryIntervalsAreOk(mm); } - CHECK_EQ(-1, TrackMemoryInterval(mm, i, i, i)); + CHECK_EQ(-1, TrackMemoryInterval(mm, i, i, i, 0, 0)); CHECK_EQ(ENOMEM, errno); CheckMemoryIntervalsAreOk(mm); free(mm); @@ -109,62 +108,63 @@ TEST(TrackMemoryInterval, TestFull) { TEST(TrackMemoryInterval, TestAppend) { static const struct MemoryIntervals mm[2] = { - {1, {{2, 2}}, {0}}, - {1, {{2, 3}}, {0}}, + {1, {{2, 2}}}, + {1, {{2, 3}}}, }; RunTrackMemoryIntervalTest(mm, 3, 3, 0); } TEST(TrackMemoryInterval, TestPrepend) { static const struct MemoryIntervals mm[2] = { - {1, {{2, 2}}, {0}}, - {1, {{1, 2}}, {0}}, + {1, {{2, 2}}}, + {1, {{1, 2}}}, }; RunTrackMemoryIntervalTest(mm, 1, 1, 0); } TEST(TrackMemoryInterval, TestFillHole) { static const struct MemoryIntervals mm[2] = { - {4, {{1, 1}, {3, 4}, {5, 5}, {6, 8}}, {0, 0, 1, 0}}, - {3, {{1, 4}, {5, 5}, {6, 8}}, {0, 1, 0}}, + {4, {{1, 1}, {3, 4}, {5, 5, 1}, {6, 8}}}, + {3, {{1, 4}, {5, 5, 1}, {6, 8}}}, }; RunTrackMemoryIntervalTest(mm, 2, 2, 0); } TEST(TrackMemoryInterval, TestAppend2) { static const struct MemoryIntervals mm[2] = { - {1, {{2, 2}}, {0}}, - {2, {{2, 2}, {3, 3}}, {0, 1}}, + {1, {{2, 2}}}, + {2, {{2, 2}, {3, 3, 1}}}, }; RunTrackMemoryIntervalTest(mm, 3, 3, 1); } TEST(TrackMemoryInterval, TestPrepend2) { static const struct MemoryIntervals mm[2] = { - {1, {{2, 2}}, {0}}, - {2, {{1, 1}, {2, 2}}, {1, 0}}, + {1, {{2, 2}}}, + {2, {{1, 1, 1}, {2, 2}}}, }; RunTrackMemoryIntervalTest(mm, 1, 1, 1); } TEST(TrackMemoryInterval, TestFillHole2) { static const struct MemoryIntervals mm[2] = { - {4, {{1, 1}, {3, 4}, {5, 5}, {6, 8}}, {0, 0, 1, 0}}, - {5, {{1, 1}, {2, 2}, {3, 4}, {5, 5}, {6, 8}}, {0, 1, 0, 1, 0}}, + {4, {{1, 1}, {3, 4}, {5, 5, 1}, {6, 8}}}, + {5, {{1, 1}, {2, 2, 1}, {3, 4}, {5, 5, 1}, {6, 8}}}, }; RunTrackMemoryIntervalTest(mm, 2, 2, 1); } TEST(FindMemoryInterval, Test) { static const struct MemoryIntervals mm[1] = { - {4, - { - [0] = {1, 1}, - [1] = {3, 4}, - [2] = {5, 5}, - [3] = {6, 8}, - }, - {0, 0, 1, 0}}, + { + 4, + { + [0] = {1, 1}, + [1] = {3, 4}, + [2] = {5, 5, 1}, + [3] = {6, 8}, + }, + }, }; EXPECT_EQ(0, FindMemoryInterval(mm, 0)); EXPECT_EQ(0, FindMemoryInterval(mm, 1)); @@ -180,96 +180,96 @@ TEST(FindMemoryInterval, Test) { TEST(ReleaseMemoryIntervals, TestEmpty) { static const struct MemoryIntervals mm[2] = { - {0, {}, {}}, - {0, {}, {}}, + {0, {}}, + {0, {}}, }; RunReleaseMemoryIntervalsTest(mm, 2, 2); } TEST(ReleaseMemoryIntervals, TestRemoveElement_UsesInclusiveRange) { static const struct MemoryIntervals mm[2] = { - {3, {{0, 0}, {2, 2}, {4, 4}}, {}}, - {2, {{0, 0}, {4, 4}}, {}}, + {3, {{0, 0}, {2, 2}, {4, 4}}}, + {2, {{0, 0}, {4, 4}}}, }; RunReleaseMemoryIntervalsTest(mm, 2, 2); } TEST(ReleaseMemoryIntervals, TestPunchHole) { static const struct MemoryIntervals mm[2] = { - {1, {{0, 9}}, {}}, - {2, {{0, 3}, {6, 9}}, {}}, + {1, {{0, 9}}}, + {2, {{0, 3}, {6, 9}}}, }; RunReleaseMemoryIntervalsTest(mm, 4, 5); } TEST(ReleaseMemoryIntervals, TestShortenLeft) { static const struct MemoryIntervals mm[2] = { - {1, {{0, 9}}, {}}, - {1, {{0, 7}}, {}}, + {1, {{0, 9}}}, + {1, {{0, 7}}}, }; RunReleaseMemoryIntervalsTest(mm, 8, 9); } TEST(ReleaseMemoryIntervals, TestShortenRight) { static const struct MemoryIntervals mm[2] = { - {1, {{0, 9}}, {}}, - {1, {{3, 9}}, {}}, + {1, {{0, 9}}}, + {1, {{3, 9}}}, }; RunReleaseMemoryIntervalsTest(mm, 0, 2); } TEST(ReleaseMemoryIntervals, TestShortenLeft2) { static const struct MemoryIntervals mm[2] = { - {1, {{0, 9}}, {}}, - {1, {{0, 7}}, {}}, + {1, {{0, 9}}}, + {1, {{0, 7}}}, }; RunReleaseMemoryIntervalsTest(mm, 8, 11); } TEST(ReleaseMemoryIntervals, TestShortenRight2) { static const struct MemoryIntervals mm[2] = { - {1, {{0, 9}}, {}}, - {1, {{3, 9}}, {}}, + {1, {{0, 9}}}, + {1, {{3, 9}}}, }; RunReleaseMemoryIntervalsTest(mm, -3, 2); } TEST(ReleaseMemoryIntervals, TestZeroZero) { static const struct MemoryIntervals mm[2] = { - {1, {{3, 9}}, {}}, - {1, {{3, 9}}, {}}, + {1, {{3, 9}}}, + {1, {{3, 9}}}, }; RunReleaseMemoryIntervalsTest(mm, 0, 0); } TEST(ReleaseMemoryIntervals, TestNoopLeft) { static const struct MemoryIntervals mm[2] = { - {1, {{3, 9}}, {}}, - {1, {{3, 9}}, {}}, + {1, {{3, 9}}}, + {1, {{3, 9}}}, }; RunReleaseMemoryIntervalsTest(mm, 1, 2); } TEST(ReleaseMemoryIntervals, TestNoopRight) { static const struct MemoryIntervals mm[2] = { - {1, {{3, 9}}, {}}, - {1, {{3, 9}}, {}}, + {1, {{3, 9}}}, + {1, {{3, 9}}}, }; RunReleaseMemoryIntervalsTest(mm, 10, 10); } TEST(ReleaseMemoryIntervals, TestBigFree) { static const struct MemoryIntervals mm[2] = { - {2, {{0, 3}, {6, 9}}, {}}, - {0, {}, {}}, + {2, {{0, 3}, {6, 9}}}, + {0, {}}, }; RunReleaseMemoryIntervalsTest(mm, INT_MIN, INT_MAX); } TEST(ReleaseMemoryIntervals, TestWeirdGap) { static const struct MemoryIntervals mm[2] = { - {3, {{10, 10}, {20, 20}, {30, 30}}, {}}, - {2, {{10, 10}, {30, 30}}, {}}, + {3, {{10, 10}, {20, 20}, {30, 30}}}, + {2, {{10, 10}, {30, 30}}}, }; RunReleaseMemoryIntervalsTest(mm, 15, 25); } @@ -279,7 +279,7 @@ TEST(ReleaseMemoryIntervals, TestOutOfMemory) { struct MemoryIntervals *mm; mm = calloc(1, sizeof(struct MemoryIntervals)); for (i = 0; i < ARRAYLEN(mm->p); ++i) { - CHECK_NE(-1, TrackMemoryInterval(mm, i * 10, i * 10 + 8, 0)); + CHECK_NE(-1, TrackMemoryInterval(mm, i * 10, i * 10 + 8, 0, 0, 0)); } CheckMemoryIntervalsAreOk(mm); CHECK_EQ(-1, ReleaseMemoryIntervals(mm, 4, 4, NULL)); diff --git a/test/libc/runtime/mmap_test.c b/test/libc/runtime/mmap_test.c index 0d3c4797..1128f86e 100644 --- a/test/libc/runtime/mmap_test.c +++ b/test/libc/runtime/mmap_test.c @@ -88,11 +88,6 @@ TEST(mmap, testMapFixed_destroysEverythingInItsPath) { MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); ASSERT_GT(_mmi.i, m1); EXPECT_NE(-1, munmap((void *)kFixedmapStart, FRAMESIZE * 3)); -#ifdef __SANITIZE_ADDRESS__ - ASSERT_EQ(m1 + 1, _mmi.i); -#else - ASSERT_EQ(m1, _mmi.i); -#endif } TEST(isheap, nullPtr) { diff --git a/test/libc/runtime/test.mk b/test/libc/runtime/test.mk index c72e7c6d..5e29ae6e 100644 --- a/test/libc/runtime/test.mk +++ b/test/libc/runtime/test.mk @@ -63,11 +63,11 @@ $(TEST_LIBC_RUNTIME_OBJS): \ DEFAULT_CCFLAGS += \ -fno-builtin -ifeq (,$(MODE)) -$(TEST_LIBC_RUNTIME_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif +# ifeq (,$(MODE)) +# $(TEST_LIBC_RUNTIME_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif o/$(MODE)/test/libc/runtime/getenv_test.com.runs: \ o/$(MODE)/test/libc/runtime/getenv_test.com diff --git a/test/net/http/parsehttprequest_test.c b/test/net/http/parsehttprequest_test.c index eabcfedd..3c6f805a 100644 --- a/test/net/http/parsehttprequest_test.c +++ b/test/net/http/parsehttprequest_test.c @@ -29,7 +29,11 @@ struct HttpRequest req[1]; static char *slice(const char *m, struct HttpRequestSlice s) { - return memcpy(xmalloc(s.b - s.a), m + s.a, s.b - s.a); + char *p; + p = xmalloc(s.b - s.a + 1); + memcpy(p, m + s.a, s.b - s.a); + p[s.b - s.a] = 0; + return p; } TEST(ParseHttpRequest, testEmpty) { diff --git a/test/net/http/test.mk b/test/net/http/test.mk index f6669a15..140337b8 100644 --- a/test/net/http/test.mk +++ b/test/net/http/test.mk @@ -39,9 +39,9 @@ o/$(MODE)/test/net/http/%.com.dbg: \ $(APE) @$(APELINK) -$(TEST_NET_HTTP_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address +# $(TEST_NET_HTTP_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address .PHONY: o/$(MODE)/test/net/http o/$(MODE)/test/net/http: \ diff --git a/third_party/stb/stb.mk b/third_party/stb/stb.mk index 87bb34d6..3e57334e 100644 --- a/third_party/stb/stb.mk +++ b/third_party/stb/stb.mk @@ -63,11 +63,11 @@ $(THIRD_PARTY_STB_A_OBJS): \ -ffunction-sections \ -fdata-sections -o//third_party/stb/stb_image_write.o \ -o//third_party/stb/stb_image.o: \ - OVERRIDE_CFLAGS += \ - -ftrapv \ - -fsanitize=address +# o//third_party/stb/stb_image_write.o \ +# o//third_party/stb/stb_image.o: \ +# OVERRIDE_CFLAGS += \ +# -ftrapv \ +# -fsanitize=address $(THIRD_PARTY_STB_A_OBJS): \ OVERRIDE_CPPFLAGS += \ diff --git a/tool/build/blinkenlights.c b/tool/build/blinkenlights.c index 9ef52f53..8e1823ab 100644 --- a/tool/build/blinkenlights.c +++ b/tool/build/blinkenlights.c @@ -267,7 +267,7 @@ static struct XmmType xmmtype; static struct Elf elf[1]; static struct Dis dis[1]; -long double last_seconds; +static long double last_seconds; static long double statusexpires; static struct termios oldterm; static char logpath[PATH_MAX]; diff --git a/tool/build/build.mk b/tool/build/build.mk index 2537f787..d6293e14 100644 --- a/tool/build/build.mk +++ b/tool/build/build.mk @@ -40,6 +40,8 @@ TOOL_BUILD_DIRECTDEPS = \ LIBC_TINYMATH \ LIBC_MEM \ LIBC_NEXGEN32E \ + LIBC_NT_KERNELBASE \ + LIBC_NT_USER32 \ LIBC_RUNTIME \ LIBC_SOCK \ LIBC_STDIO \ @@ -86,6 +88,12 @@ o/$(MODE)/tool/build/emulator.o: \ OVERRIDE_COPTS += \ -fno-sanitize=pointer-overflow +# ifeq (,$(MODE)) +# $(TOOL_BUILD_OBJS): \ +# OVERRIDE_COPTS += \ +# -fsanitize=address +# endif + .PHONY: o/$(MODE)/tool/build o/$(MODE)/tool/build: \ o/$(MODE)/tool/build/emucrt \ diff --git a/tool/build/lib/buildlib.mk b/tool/build/lib/buildlib.mk index 4685d3ed..e6e41b53 100644 --- a/tool/build/lib/buildlib.mk +++ b/tool/build/lib/buildlib.mk @@ -63,15 +63,11 @@ $(TOOL_BUILD_LIB_A).pkg: \ $(TOOL_BUILD_LIB_A_OBJS) \ $(foreach x,$(TOOL_BUILD_LIB_A_DIRECTDEPS),$($(x)_A).pkg) -ifeq (,$(MODE)) -$(TOOL_BUILD_LIB_A_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif - -o/$(MODE)/tool/build/lib/buffer-gcc.asm: \ - OVERRIDE_CFLAGS += \ - -fsanitize=address +# ifeq (,$(MODE)) +# $(TOOL_BUILD_LIB_A_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif o/$(MODE)/tool/build/lib/ssefloat.o: \ TARGET_ARCH += \ diff --git a/tool/build/lib/disarg.c b/tool/build/lib/disarg.c index 41ccae7d..4bfc3508 100644 --- a/tool/build/lib/disarg.c +++ b/tool/build/lib/disarg.c @@ -50,7 +50,7 @@ static const char kGreg[2][2][2][8][5] = { {{"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"}, {"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}}, {{{"ax", "cx", "dx", "bx", "sp", "bp", "si", "di"}, - {"r8w", "re9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"}}, + {"r8w", "r9w", "r10w", "r11w", "r12w", "r13w", "r14w", "r15w"}}, {{"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi"}, {"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}}}, }; diff --git a/tool/build/winterm.c b/tool/build/winterm.c new file mode 100644 index 00000000..e4fbabc5 --- /dev/null +++ b/tool/build/winterm.c @@ -0,0 +1,89 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ This program is free software; you can redistribute it and/or modify │ +│ it under the terms of the GNU General Public License as published by │ +│ the Free Software Foundation; version 2 of the License. │ +│ │ +│ This program is distributed in the hope that it will be useful, but │ +│ WITHOUT ANY WARRANTY; without even the implied warranty of │ +│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │ +│ General Public License for more details. │ +│ │ +│ You should have received a copy of the GNU General Public License │ +│ along with this program; if not, write to the Free Software │ +│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │ +│ 02110-1301 USA │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/log/check.h" +#include "libc/log/log.h" +#include "libc/nt/dll.h" +#include "libc/nt/enum/color.h" +#include "libc/nt/enum/cw.h" +#include "libc/nt/enum/idc.h" +#include "libc/nt/enum/sw.h" +#include "libc/nt/enum/wm.h" +#include "libc/nt/enum/ws.h" +#include "libc/nt/events.h" +#include "libc/nt/paint.h" +#include "libc/nt/struct/msg.h" +#include "libc/nt/struct/paintstruct.h" +#include "libc/nt/struct/wndclass.h" +#include "libc/nt/windows.h" +#include "libc/runtime/missioncritical.h" +#include "libc/runtime/runtime.h" +#include "libc/runtime/winmain.h" +#include "libc/str/str.h" + +/** + * @fileoverview Incomplete Windows App. + */ + +static const char16_t kClassName[] = u"Sample Window Class"; + +int64_t WindowProcSysv(int64_t hwnd, uint32_t uMsg, uint64_t wParam, + int64_t lParam) { + int64_t hdc; + struct NtPaintStruct ps; + switch (uMsg) { + case kNtWmDestroy: + PostQuitMessage(0); + return 0; + case kNtWmPaint: + hdc = BeginPaint(hwnd, &ps); + FillRect(hdc, &ps.rcPaint, kNtColorWindow + 1); + EndPaint(hwnd, &ps); + return 0; + default: + return DefWindowProc(hwnd, uMsg, wParam, lParam); + } +} + +int64_t WindowProcNt(int64_t, uint32_t, uint64_t, int64_t); +asm("WindowProcNt:\n\t" + "lea\tWindowProcSysv(%rip),%rax\n\t" + "jmp\t__nt2sysv"); + +int main(int argc, char *argv[]) { + int64_t hwnd; + struct NtMsg msg; + struct NtWndClass wc; + memset(&wc, 0, sizeof(wc)); + wc.lpfnWndProc = WindowProcNt; + wc.hInstance = g_winmain.hInstance; + wc.hCursor = LoadCursor(0, kNtIdcIbeam); + wc.lpszClassName = kClassName; + CHECK(RegisterClass(&wc)); + CHECK((hwnd = CreateWindowEx(0, kClassName, u"Learn to Program Windows", + kNtWsOverlappedwindow, kNtCwUsedefault, + kNtCwUsedefault, kNtCwUsedefault, + kNtCwUsedefault, 0, 0, g_winmain.hInstance, 0))); + ShowWindow(hwnd, kNtSwNormal); + while (GetMessage(&msg, 0, 0, 0)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + return 0; +} diff --git a/tool/net/net.mk b/tool/net/net.mk index ae1be877..5163b3a7 100644 --- a/tool/net/net.mk +++ b/tool/net/net.mk @@ -22,8 +22,10 @@ TOOL_NET_DIRECTDEPS = \ LIBC_ALG \ LIBC_BITS \ LIBC_CALLS \ + LIBC_CALLS_HEFTY \ LIBC_CONV \ LIBC_DNS \ + LIBC_RAND \ LIBC_FMT \ LIBC_LOG \ LIBC_LOG_ASAN \ @@ -71,11 +73,11 @@ o/$(MODE)/tool/net/redbean.com.dbg: \ $(APE) @$(APELINK) -ifeq (,$(MODE)) -$(TOOL_NET_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif +# ifeq (,$(MODE)) +# $(TOOL_NET_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif .PHONY: o/$(MODE)/tool/net o/$(MODE)/tool/net: \ diff --git a/tool/net/redbean.c b/tool/net/redbean.c index 362923c4..1f6bd837 100644 --- a/tool/net/redbean.c +++ b/tool/net/redbean.c @@ -36,6 +36,7 @@ #include "libc/math.h" #include "libc/mem/mem.h" #include "libc/nexgen32e/crc32.h" +#include "libc/rand/rand.h" #include "libc/runtime/gc.h" #include "libc/runtime/missioncritical.h" #include "libc/runtime/runtime.h" @@ -650,7 +651,7 @@ static bool OpenZip(const char *path) { map = MAP_FAILED; if ((fd = open(path, O_RDONLY)) != -1 && fstat(fd, &st) != -1 && st.st_size && - (map = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) && + (map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)) && (cdir = zipfindcentraldir(zmap, zmapsize)) && IndexAssets(map, cdir)) { ok = true; zmap = map; @@ -1116,14 +1117,13 @@ void ProcessRequests(void) { void ProcessConnection(void) { int pid; clientaddrsize = sizeof(clientaddr); - client = accept4(server, &clientaddr, &clientaddrsize, SOCK_CLOEXEC); + client = accept4(server, &clientaddr, &clientaddrsize, 0 /* SOCK_CLOEXEC */); if (client != -1) { startconnection = nowl(); if ((pid = uniprocess ? -1 : fork()) > 0) { close(client); return; } - if (!pid) close(server); if (pid == -1) terminated = true; DescribeAddress(clientaddrstr, &clientaddr); DEBUGF("%s accept", clientaddrstr); diff --git a/tool/viz/lib/vizlib.mk b/tool/viz/lib/vizlib.mk index a3b7c1e4..000c4446 100644 --- a/tool/viz/lib/vizlib.mk +++ b/tool/viz/lib/vizlib.mk @@ -92,11 +92,11 @@ $(TOOL_VIZ_LIB_A).pkg: \ $(TOOL_VIZ_LIB_A_OBJS) \ $(foreach x,$(TOOL_VIZ_LIB_A_DIRECTDEPS),$($(x)_A).pkg) -ifeq (,$(MODE)) -$(TOOL_VIZ_LIB_A_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif +# ifeq (,$(MODE)) +# $(TOOL_VIZ_LIB_A_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif $(TOOL_VIZ_LIB_A_OBJS): tool/viz/lib/vizlib.mk diff --git a/tool/viz/viz.mk b/tool/viz/viz.mk index d5b067a1..1bb560fa 100644 --- a/tool/viz/viz.mk +++ b/tool/viz/viz.mk @@ -84,11 +84,11 @@ $(TOOL_VIZ_OBJS): \ $(BUILD_FILES) \ tool/viz/viz.mk -ifeq (,$(MODE)) -$(TOOL_VIZ_OBJS): \ - OVERRIDE_CFLAGS += \ - -fsanitize=address -endif +# ifeq (,$(MODE)) +# $(TOOL_VIZ_OBJS): \ +# OVERRIDE_CFLAGS += \ +# -fsanitize=address +# endif .PHONY: o/$(MODE)/tool/viz o/$(MODE)/tool/viz: \