From db33973e0aae7ffc2537991e372e3fc5e59608a7 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 13 Nov 2020 01:27:49 -0800 Subject: [PATCH] Get fork() working on Windows This is done without using Microsoft's internal APIs. MAP_PRIVATE mappings are copied to the subprocess via a pipe, since Microsoft doesn't want us to have proper COW pages. MAP_SHARED mappings are remapped without needing to do any copying. Global variables need copying along with the stack and the whole heap of anonymous mem. This actually improves the reliability of the redbean http server although one shouldn't expect 10k+ connections on a home computer that isn't running software built to serve like Linux or FreeBSD. --- ape/ape.S | 11 +- ape/config.h | 2 +- build/compile | 2 +- dsp/core/core.mk | 10 +- dsp/tty/tty.mk | 10 +- examples/forkrand.c | 16 +- examples/forky.c | 51 ---- examples/hello.c | 2 - libc/calls/commandv.c | 5 +- libc/calls/dup-nt.c | 2 +- libc/calls/hefty/dirstream.c | 2 +- libc/calls/hefty/fork-nt.c | 158 +++++++++++++ libc/calls/{ => hefty}/fork.c | 11 +- libc/calls/hefty/ntspawn.c | 2 + libc/calls/hefty/spawnlp.c | 1 + libc/calls/hefty/spawnve-nt.c | 4 +- libc/{sysv => calls/hefty}/vfork.S | 4 +- libc/calls/internal.h | 12 +- libc/calls/wait.c | 9 +- libc/calls/wait4-nt.c | 68 ++++-- libc/calls/zygote.c | 7 +- libc/isystem/windows.h | 4 +- libc/libc.mk | 1 - libc/log/asan.c | 3 +- libc/log/log.mk | 6 +- libc/mem/putenv.c | 54 ++--- libc/nt/dll.h | 4 +- libc/nt/enum/color.h | 35 +++ libc/nt/enum/cw.h | 8 + libc/nt/enum/idc.h | 24 ++ libc/nt/enum/pwr.h | 10 + libc/nt/enum/sw.h | 19 ++ libc/nt/enum/wa.h | 8 + libc/nt/enum/wait.h | 7 + libc/nt/enum/wm.h | 185 +++++++++++++++ libc/nt/enum/ws.h | 62 +++++ libc/nt/events.h | 95 ++++---- libc/nt/master.sh | 24 +- libc/nt/paint.h | 41 +--- libc/nt/struct/drawtextparams.h | 16 ++ libc/nt/struct/msg.h | 4 +- libc/nt/struct/paintstruct.h | 18 ++ libc/nt/struct/rect.h | 15 ++ libc/nt/struct/size.h | 13 ++ libc/nt/struct/wndclass.h | 22 ++ libc/nt/struct/wndclassex.h | 24 ++ libc/nt/synchronization.h | 4 +- libc/nt/typedef/wndproc.h | 10 + libc/nt/user32/DefWindowProcA.s | 12 + libc/nt/user32/DefWindowProcW.s | 12 + libc/nt/user32/FillRect.s | 10 + libc/nt/user32/LoadCursorA.s | 10 + libc/nt/user32/LoadCursorW.s | 10 + libc/nt/user32/LoadImageA.s | 10 + libc/nt/user32/LoadImageW.s | 10 + libc/nt/user32/RegisterClassA.s | 13 ++ libc/nt/user32/RegisterClassExA.s | 13 ++ libc/nt/user32/RegisterClassExW.s | 13 ++ libc/nt/user32/RegisterClassW.s | 13 ++ libc/nt/user32/ShowCaret.s | 13 ++ libc/nt/user32/ShowCursor.s | 13 ++ libc/nt/windows.h | 323 ++------------------------ libc/runtime/_exit.S | 5 +- libc/runtime/arememoryintervalsok.c | 2 +- libc/runtime/directmap.c | 32 --- libc/runtime/directmap.h | 1 + libc/runtime/directmapnt.c | 51 ++++ libc/runtime/getdosargv.c | 6 - libc/runtime/internal.h | 1 + libc/runtime/jmpstack.S | 38 +++ libc/runtime/memtrack.c | 20 +- libc/runtime/memtrack.h | 6 +- libc/runtime/memtracknt.c | 2 +- libc/runtime/mmap.c | 4 +- libc/runtime/mmi.c | 22 ++ libc/runtime/msync-nt.c | 2 +- libc/runtime/runtime.h | 1 - libc/runtime/runtime.mk | 5 - libc/runtime/winmain.greg.c | 106 ++++++--- libc/runtime/winmain.h | 16 ++ libc/sock/accept-nt.c | 3 - libc/sock/internal.h | 1 + libc/sock/kntwsadata.c | 12 +- libc/stdio/stdio.mk | 1 + libc/stdio/system.c | 146 ++---------- libc/sysv/sysv.mk | 1 - net/http/http.mk | 10 +- test/ape/lib/test.mk | 6 +- test/dsp/core/test.mk | 10 +- test/libc/intrin/test.mk | 6 +- test/libc/runtime/memtrack_test.c | 102 ++++---- test/libc/runtime/mmap_test.c | 5 - test/libc/runtime/test.mk | 10 +- test/net/http/parsehttprequest_test.c | 6 +- test/net/http/test.mk | 6 +- third_party/stb/stb.mk | 10 +- tool/build/blinkenlights.c | 2 +- tool/build/build.mk | 8 + tool/build/lib/buildlib.mk | 14 +- tool/build/lib/disarg.c | 2 +- tool/build/winterm.c | 89 +++++++ tool/net/net.mk | 12 +- tool/net/redbean.c | 6 +- tool/viz/lib/vizlib.mk | 10 +- tool/viz/viz.mk | 10 +- 105 files changed, 1476 insertions(+), 912 deletions(-) delete mode 100644 examples/forky.c create mode 100644 libc/calls/hefty/fork-nt.c rename libc/calls/{ => hefty}/fork.c (94%) rename libc/{sysv => calls/hefty}/vfork.S (97%) create mode 100644 libc/nt/enum/color.h create mode 100644 libc/nt/enum/cw.h create mode 100644 libc/nt/enum/idc.h create mode 100644 libc/nt/enum/pwr.h create mode 100644 libc/nt/enum/sw.h create mode 100644 libc/nt/enum/wa.h create mode 100644 libc/nt/enum/wait.h create mode 100644 libc/nt/enum/wm.h create mode 100644 libc/nt/enum/ws.h create mode 100644 libc/nt/struct/drawtextparams.h create mode 100644 libc/nt/struct/paintstruct.h create mode 100644 libc/nt/struct/rect.h create mode 100644 libc/nt/struct/size.h create mode 100644 libc/nt/struct/wndclass.h create mode 100644 libc/nt/struct/wndclassex.h create mode 100644 libc/nt/typedef/wndproc.h create mode 100644 libc/nt/user32/DefWindowProcA.s create mode 100644 libc/nt/user32/DefWindowProcW.s create mode 100644 libc/runtime/directmapnt.c create mode 100644 libc/runtime/jmpstack.S create mode 100644 libc/runtime/mmi.c create mode 100644 libc/runtime/winmain.h create mode 100644 tool/build/winterm.c 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: \