Make improvements

main
Justine Tunney 2020-12-01 03:43:40 -08:00
parent 3e4fd4b0ad
commit e44a0cf6f8
256 changed files with 23100 additions and 2294 deletions

View File

@ -116,6 +116,7 @@ include libc/mem/mem.mk # │
include libc/ohmyplus/ohmyplus.mk # │
include libc/zipos/zipos.mk # │
include third_party/dtoa/dtoa.mk # │
include third_party/gdtoa/gdtoa.mk # │
include libc/time/time.mk # │
include libc/alg/alg.mk # │
include libc/calls/hefty/hefty.mk # │
@ -138,6 +139,7 @@ include dsp/tty/tty.mk # ├──online
include libc/dns/dns.mk # │
include libc/crypto/crypto.mk # │
include net/http/http.mk #─┘
include third_party/chibicc/chibicc.mk
include third_party/lemon/lemon.mk
include third_party/linenoise/linenoise.mk
include third_party/editline/editline.mk

View File

@ -35,7 +35,7 @@
*/
#include "ape/config.h"
#include "ape/lib/pc.h"
#include "ape/macros.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
#include "ape/relocations.h"
#include "libc/elf/def.h"
@ -785,8 +785,8 @@ ape.pe: .ascin "PE",4
.long 0 # Checksum
.short v_ntsubsystem # Subsystem: 0=Neutral,2=GUI,3=Console
.short .LDLLEXE # DllCharacteristics
.quad 0x0000000000080000 # StackReserve
.quad 0x0000000000080000 # StackCommit
.quad 0x0000000000020000 # StackReserve
.quad 0x0000000000020000 # StackCommit
.quad 0 # HeapReserve
.quad 0 # HeapCommit
.long 0 # LoaderFlags

View File

@ -175,7 +175,7 @@
Until then, we can build for those platforms using Linux or WSL. */
#ifdef __LINKER__
#include "ape/macros.h"
#include "ape/macros.internal.h"
#include "ape/config.h"
#include "libc/nt/pedef.internal.h"
#include "libc/zip.h"

View File

@ -17,7 +17,7 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "ape/macros.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__

View File

@ -19,7 +19,7 @@
*/
#include "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__

View File

@ -20,7 +20,7 @@
#include "ape/config.h"
#include "ape/lib/pc.h"
#include "libc/bits/bits.h"
#include "libc/bits/safemacros.internal.h"
#include "libc/macros.h"
/**
* Virtualizes physical memory.
@ -33,27 +33,24 @@
*/
textreal void flattenhighmemory(struct SmapEntry *e820, struct PageTable *pml4t,
uint64_t *ptsp) {
struct SmapEntry *smap = e820;
struct SmapEntry *hole = e820;
uint64_t paddr = IMAGE_BASE_PHYSICAL;
uint64_t vaddr = IMAGE_BASE_VIRTUAL;
while (smap->size) {
uint64_t *entry, paddr, vaddr;
struct SmapEntry *smap, *hole;
for (smap = hole = e820, vaddr = IMAGE_BASE_VIRTUAL; smap->size; ++smap) {
while (smap->size && smap->type != kMemoryUsable) smap++;
paddr = roundup(max(paddr, smap->addr), PAGESIZE);
while (paddr < rounddown(smap->addr + smap->size, PAGESIZE)) {
paddr = ROUNDUP(MAX(IMAGE_BASE_PHYSICAL, smap->addr), PAGESIZE);
while (paddr < ROUNDDOWN(smap->addr + smap->size, PAGESIZE)) {
while (hole->size &&
(hole->type == kMemoryUsable || hole->addr + hole->size < paddr)) {
hole++;
}
if (paddr >= hole->addr && paddr < hole->addr + hole->size) {
paddr = roundup(hole->addr + hole->size, PAGESIZE);
paddr = ROUNDUP(hole->addr + hole->size, PAGESIZE);
} else {
uint64_t *entry = getpagetableentry(vaddr, 3, pml4t, ptsp);
entry = __getpagetableentry(vaddr, 3, pml4t, ptsp);
*entry = paddr | PAGE_V | PAGE_RW;
vaddr += 0x1000;
paddr += 0x1000;
}
}
smap++;
}
}

View File

@ -19,7 +19,7 @@
*/
#include "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__

View File

@ -19,7 +19,7 @@
*/
#include "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__

View File

@ -20,12 +20,13 @@
#include "ape/lib/pc.h"
#include "libc/assert.h"
textreal static uint64_t pushpagetable(uint64_t *ptsp) {
static textreal uint64_t __pushpagetable(uint64_t *ptsp) {
return (*ptsp -= PAGESIZE) | PAGE_V | PAGE_RW;
}
textreal uint64_t *getpagetableentry(int64_t vaddr, unsigned depth,
struct PageTable *pml4t, uint64_t *ptsp) {
textreal uint64_t *__getpagetableentry(int64_t vaddr, unsigned depth,
struct PageTable *pml4t,
uint64_t *ptsp) {
uint64_t *entry;
unsigned char shift;
assert(depth <= 3);
@ -36,7 +37,7 @@ textreal uint64_t *getpagetableentry(int64_t vaddr, unsigned depth,
entry = &pml4t->p[(vaddr >> shift) & 511];
if (!depth--) return entry;
shift -= 9;
if (!*entry) *entry = pushpagetable(ptsp);
if (!*entry) *entry = __pushpagetable(ptsp);
pml4t = (void *)(*entry & PAGE_TA);
}
}

View File

@ -19,7 +19,7 @@
*/
#include "ape/lib/pc.h"
#include "ape/config.h"
#include "ape/macros.h"
#include "ape/macros.internal.h"
#include "ape/notice.inc"
.section .real,"ax",@progbits
.source __FILE__

View File

@ -24,7 +24,7 @@
textreal static void __map_segment(uint64_t k, uint64_t a, uint64_t b) {
uint64_t *e;
for (; a < b; a += 0x1000) {
e = getpagetableentry(IMAGE_BASE_VIRTUAL + a, 3, &g_pml4t, &g_ptsp_xlm);
e = __getpagetableentry(IMAGE_BASE_VIRTUAL + a, 3, &g_pml4t, &g_ptsp_xlm);
*e = (IMAGE_BASE_REAL + a) | k;
}
}

View File

@ -22,7 +22,7 @@
textreal void pageunmap(int64_t vaddr) {
uint64_t *entry;
entry = getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm);
entry = __getpagetableentry(vaddr, 3, &g_pml4t, &g_ptsp_xlm);
*entry &= ~PAGE_V;
invlpg(vaddr);
}

View File

@ -214,7 +214,8 @@ extern uint64_t g_ptsp_xlm;
void bootdr(char drive) noreturn;
void smapsort(struct SmapEntry *);
uint64_t *getpagetableentry(int64_t, unsigned, struct PageTable *, uint64_t *);
uint64_t *__getpagetableentry(int64_t, unsigned, struct PageTable *,
uint64_t *);
void flattenhighmemory(struct SmapEntry *, struct PageTable *, uint64_t *);
void pageunmap(int64_t);

View File

@ -29,7 +29,6 @@
#include "libc/log/log.h"
#include "libc/macros.h"
#include "libc/runtime/gc.h"
#include "libc/runtime/rbx.h"
#include "libc/runtime/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"

View File

@ -1,136 +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/ioctl.h"
#include "libc/calls/struct/termios.h"
#include "libc/fmt/fmt.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/termios.h"
int yn2, xn2;
int yn3, xn3;
char b[128], inbuf[128];
int y, x, yn, xn, my, mx;
struct termios term, oldterm;
int main(int argc, char *argv[]) {
int i;
setvbuf(stdout, inbuf, _IONBF, 128); /* make things slower */
/* raw mode */
ioctl(1, TCGETS, &oldterm);
memcpy(&term, &oldterm, sizeof(term));
term.c_cc[VMIN] = 1;
term.c_cc[VTIME] = 1;
term.c_iflag &= ~(INPCK | ISTRIP | PARMRK | INLCR | IGNCR | ICRNL | IXON);
term.c_lflag &= ~(IEXTEN | ICANON | ECHO | ECHONL);
term.c_cflag &= ~(CSIZE | PARENB);
term.c_oflag &= ~OPOST;
term.c_cflag |= CS8;
term.c_iflag |= IUTF8;
ioctl(1, TCSETSF, &term);
/* get cursor position and display dimensions */
printf("\e7\e[6n\e[9979;9979H\e[6n\e8");
read(0, b, sizeof(b));
sscanf(b, "\e[%d;%dR\e[%d;%dR", &y, &x, &yn, &xn);
printf("\e[1q"); /* turn on led one */
printf("\e[2J"); /* clear display */
printf("\e#8"); /* fill display with E's */
printf("\e[H");
/* clear display again */
printf("\e[2q"); /* turn on led two */
for (i = 0; i < yn; ++i) {
if (i) printf("\n");
printf(" ");
printf("\e[0K");
}
for (i = 0; i < yn - 1; ++i) {
if (i) printf("\eM");
printf("\e[1K");
}
printf("\e(0"); /* line drawing mode */
printf("\e[3q"); /* turn on led three */
printf("\e[H");
/* move to center */
my = yn / 2;
mx = xn / 2 - 7;
if (y > my) {
printf("\e[%dA", y - my);
} else if (y < my) {
printf("\e[%dB", my - y);
}
if (x > mx) {
printf("\e[%dD", x - mx);
} else if (x < mx) {
printf("\e[%dC", mx - x);
}
printf("\e[90;103m"); /* black on yellow */
printf("\e[90;103ma ` a"); /* draw nose */
printf("\e[0m"); /* reset style */
printf("\e(B"); /* ascii mode */
/* draw corners */
printf("\e[H"); /* top left */
printf("A");
printf("\e[9979C"); /* rightmost */
printf("B");
printf("\e[9979;9979H"); /* bottom right corner */
printf("\e[C"); /* move right gets clamped */
printf("D"); /* write, set redzone flag */
printf("\e[2A"); /* move up, unsets redzone */
/* gnu screen now reports out of bounds position */
/* kitty hasnt got a redzone reporting next line */
printf("\e[6n");
read(0, b, sizeof(b));
sscanf(b, "\e[%d;%dR", &yn2, &xn2);
/* writes to (yn-3,xn-1) normally and (yn-2,0) in gnu screen */
printf("!");
/* draw ruler on top */
printf("\e[H");
for (i = 8; i + 1 < xn; i += 8) {
printf("\e[%dG%d", i + 1, i); /* set column */
}
printf("\e[9979;9979H"); /* bottom right */
printf("\e[9979D"); /* leftmost */
printf("C");
/* let's break gnu screen again with multimonospace redzone */
printf("\e[%d;9979H", yn / 2); /* right middle */
printf("\e[D"); /* left */
printf("");
printf("\e[6n");
read(0, b, sizeof(b));
sscanf(b, "\e[%d;%dR", &yn2, &xn2);
printf("\e[%dH", yn / 2);
printf("%d %d vs. %d %d\r\n", yn, xn, yn2, xn2);
printf("%d %d vs. %d %d\r\n", yn / 2, xn, yn2, xn2);
printf("\e#6double width\e#5\r\n");
printf("\e[3mthis text is so \e[1mitalic\e[0m\r\n");
printf("\e[1;20mpress any fraktur exit\e[0m");
printf("\a");
read(0, b, sizeof(b));
printf("\r\n");
ioctl(1, TCSETS, &oldterm);
return 0;
}

View File

@ -33,7 +33,6 @@
* - libc/nexgen32e/bsf.h
* - libc/nexgen32e/tzcnt.h
* - libc/nexgen32e/cpuid4.internal.h
* - libc/nexgen32e/tinystrcmp.internal.h
* - https://gist.github.com/jart/fe8d104ef93149b5ba9b72912820282c
*/

View File

@ -16,13 +16,13 @@
#include "libc/stdio/stdio.h"
#include "libc/time/time.h"
noinline void dostuff(void) {
noinline void dostuff(const char *s) {
int i, us;
srand(rand64()); /* seeds rand() w/ intel rdrnd, auxv, etc. */
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);
printf("hello no. %u from %s %u [us=%d]\n", i, s, getpid(), us);
fflush(stdout);
}
}
@ -32,13 +32,14 @@ int main(int argc, char *argv[]) {
CHECK_NE(-1, (child = fork()));
if (!child) {
/* child process */
dostuff();
dostuff("child");
return 0;
} else {
/* parent process */
dostuff();
dostuff("parent");
/* note: abandoned children become zombies */
CHECK_NE(-1, (rc = wait(&wstatus)));
return WEXITSTATUS(wstatus);
CHECK_EQ(0, WEXITSTATUS(wstatus));
return 0;
}
}

View File

@ -42,7 +42,6 @@
/ @see also glibc static binaries which start at 800kb!!!
/ @see also go where interfaces sadly disempower ld prune
/ @see also the stl where bad linkage is due to tech debt
/ @see libc/macros-cpp.inc forthe getstr macro definition
/ @note libc/elf/elf.lds can be tinier with page align off
/ @note gas is more powerful than nasm due to rms notation
/ @noreturn

View File

@ -6,18 +6,17 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
unsigned long morton(unsigned long, unsigned long) libcesque pureconst;
axdx_t unmorton(unsigned long) libcesque pureconst;
unsigned long morton(unsigned long, unsigned long) libcesque;
axdx_t unmorton(unsigned long) libcesque;
#ifndef __STRICT_ANSI__
#define morton(Y, X) \
(X86_NEED(BMI2) \
? pdep(X, 0x5555555555555555ul) | pdep(Y, 0xAAAAAAAAAAAAAAAAul) \
: morton(Y, X))
#define unmorton(I) \
(X86_NEED(BMI2) ? (axdx_t){pext(I, 0xAAAAAAAAAAAAAAAAul), \
pext(I, 0x5555555555555555ul)} \
: unmorton(I))
#define morton(Y, X) \
(X86_NEED(BMI2) ? pdep(X, 0x5555555555555555) | pdep(Y, 0xAAAAAAAAAAAAAAAA) \
: morton(Y, X))
#define unmorton(I) \
(X86_NEED(BMI2) \
? (axdx_t){pext(I, 0xAAAAAAAAAAAAAAAA), pext(I, 0x5555555555555555)} \
: unmorton(I))
#endif
COSMOPOLITAN_C_END_

View File

@ -32,12 +32,12 @@
* @asyncsignalsafe
*/
int access(const char *path, int mode) {
char16_t path16[PATH_MAX];
if (!path) return efault();
if (!IsWindows()) {
return faccessat$sysv(AT_FDCWD, path, mode, 0);
} else {
char16_t path16[PATH_MAX];
if (mkntpath(path, path16) == -1) return -1;
if (__mkntpath(path, path16) == -1) return -1;
return ntaccesscheck(path16, mode);
}
}

View File

@ -25,7 +25,7 @@
textwindows int chdir$nt(const char *path) {
int len;
char16_t path16[PATH_MAX];
if ((len = mkntpath(path, path16)) == -1) return -1;
if ((len = __mkntpath(path, path16)) == -1) return -1;
if (path16[len - 1] != u'/' && path16[len - 1] != u'\\') {
path16[len + 0] = u'/';
path16[len + 1] = u'\0';

View File

@ -24,22 +24,15 @@
textwindows int close$nt(int fd) {
bool32 ok;
if (__isfdopen(fd)) {
if (g_fds.p[fd].kind == kFdFile) {
/*
* Like Linux, closing a file on Windows doesn't guarantee it's
* immediately synced to disk. But unlike Linux, this could cause
* subsequent operations, e.g. unlink() to break w/ access error.
*/
FlushFileBuffers(g_fds.p[fd].handle);
}
ok = CloseHandle(g_fds.p[fd].handle);
if (g_fds.p[fd].kind == kFdConsole) {
ok &= CloseHandle(g_fds.p[fd].extra);
}
__removefd(fd);
return ok ? 0 : __winerr();
} else {
return ebadf();
if (g_fds.p[fd].kind == kFdFile) {
/*
* Like Linux, closing a file on Windows doesn't guarantee it's
* immediately synced to disk. But unlike Linux, this could cause
* subsequent operations, e.g. unlink() to break w/ access error.
*/
FlushFileBuffers(g_fds.p[fd].handle);
}
ok = CloseHandle(g_fds.p[fd].handle);
if (g_fds.p[fd].kind == kFdConsole) ok &= CloseHandle(g_fds.p[fd].extra);
return ok ? 0 : __winerr();
}

View File

@ -43,7 +43,8 @@ int close(int fd) {
} else if (fd < g_fds.n && g_fds.p[fd].kind == kFdSocket) {
rc = weaken(closesocket$nt)(fd);
} else if (fd < g_fds.n &&
(g_fds.p[fd].kind == kFdFile || g_fds.p[fd].kind == kFdConsole)) {
(g_fds.p[fd].kind == kFdFile || g_fds.p[fd].kind == kFdConsole ||
g_fds.p[fd].kind == kFdProcess)) {
rc = close$nt(fd);
} else {
rc = ebadf();

View File

@ -25,6 +25,6 @@
int faccessat$nt(int dirfd, const char *path, int mode, uint32_t flags) {
char16_t path16[PATH_MAX];
if (dirfd != AT_FDCWD || flags) return einval();
if (mkntpath(path, path16) == -1) return -1;
if (__mkntpath(path, path16) == -1) return -1;
return ntaccesscheck(path16, mode);
}

View File

@ -18,18 +18,16 @@
02110-1301 USA
*/
#include "libc/calls/internal.h"
#include "libc/macros.h"
#include "libc/nt/files.h"
#include "libc/str/str.h"
#include "libc/sysv/errfuns.h"
textwindows char *getcwd$nt(char *buf, size_t size) {
uint16_t name16[PATH_MAX];
if (GetCurrentDirectory(PATH_MAX, name16)) {
if (tprecode16to8(buf, size, name16) < size - 1) {
return buf;
} else {
erange();
}
uint16_t name16[PATH_MAX + 1];
if (GetCurrentDirectory(ARRAYLEN(name16), name16)) {
tprecode16to8(buf, size, name16);
return buf;
} else {
__winerr();
}

View File

@ -31,8 +31,8 @@
int getdomainname(char *name, size_t len) {
uint32_t nSize;
char16_t name16[256];
struct utsname u;
char16_t name16[256];
if (len < 1) return einval();
if (!name) return efault();
if (!IsWindows()) {
@ -44,10 +44,11 @@ int getdomainname(char *name, size_t len) {
return 0;
} else {
nSize = ARRAYLEN(name16);
if (!GetComputerNameEx(kNtComputerNameDnsFullyQualified, name16, &nSize)) {
if (GetComputerNameEx(kNtComputerNameDnsFullyQualified, name16, &nSize)) {
tprecode16to8(name, len, name16);
return 0;
} else {
return __winerr();
}
tprecode16to8(name, MIN(MIN(ARRAYLEN(name16), nSize + 1), len), name16);
return 0;
}
}

View File

@ -49,10 +49,11 @@ int gethostname(char *name, size_t len) {
return 0;
} else {
nSize = ARRAYLEN(name16);
if (!GetComputerNameEx(kNtComputerNameDnsHostname, name16, &nSize)) {
if (GetComputerNameEx(kNtComputerNameDnsHostname, name16, &nSize)) {
tprecode16to8(name, len, name16);
return 0;
} else {
return __winerr();
}
tprecode16to8(name, MIN(MIN(ARRAYLEN(name16), nSize + 1), len), name16);
return 0;
}
}

View File

@ -23,7 +23,7 @@
#include "libc/macros.h"
#include "libc/nt/accounting.h"
#include "libc/runtime/runtime.h"
#include "libc/str/knuthmultiplicativehash.h"
#include "libc/str/knuthmultiplicativehash.internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/auxv.h"

View File

@ -38,8 +38,8 @@ static textwindows int copyfile$nt(const char *src, const char *dst,
int64_t fhsrc, fhdst;
struct NtFileTime accessed, modified;
char16_t src16[PATH_MAX], dst16[PATH_MAX];
if (mkntpath(src, src16) == -1) return -1;
if (mkntpath(dst, dst16) == -1) return -1;
if (__mkntpath(src, src16) == -1) return -1;
if (__mkntpath(dst, dst16) == -1) return -1;
if (CopyFile(src16, dst16, !!(flags & COPYFILE_NOCLOBBER))) {
if (flags & COPYFILE_PRESERVE_TIMESTAMPS) {
fhsrc = CreateFile(src16, kNtFileReadAttributes, kNtFileShareRead, NULL,

View File

@ -62,7 +62,7 @@ static textwindows noinline DIR *opendir$nt(const char *name) {
int len;
DIR *res;
char16_t name16[PATH_MAX];
if ((len = mkntpath(name, name16)) == -1) return NULL;
if ((len = __mkntpath(name, name16)) == -1) return NULL;
if (len + 2 + 1 > PATH_MAX) return PROGN(enametoolong(), NULL);
if (name16[len - 1] == u'/' || name16[len - 1] == u'\\') {
name16[--len] = u'\0';
@ -87,7 +87,8 @@ static textwindows noinline struct dirent *readdir$nt(DIR *dir) {
dir->ent.d_off = dir->tell++;
dir->ent.d_reclen = sizeof(dir->ent) +
tprecode16to8(dir->ent.d_name, sizeof(dir->ent.d_name),
dir->windata.cFileName) +
dir->windata.cFileName)
.ax +
1;
switch (dir->windata.dwFileType) {
case kNtFileTypeDisk:

View File

@ -20,36 +20,49 @@
#include "libc/calls/hefty/internal.h"
#include "libc/calls/hefty/ntspawn.h"
#include "libc/calls/internal.h"
#include "libc/nt/accounting.h"
#include "libc/nt/enum/startf.h"
#include "libc/nt/enum/status.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/processinformation.h"
#include "libc/nt/struct/startupinfo.h"
#include "libc/nt/synchronization.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/sock.h"
static textwindows int64_t passstdhand$nt(int fd) {
if (g_fds.p[fd].kind != kFdEmpty &&
!(g_fds.p[fd].flags &
(g_fds.p[fd].kind == kFdSocket ? SOCK_CLOEXEC : O_CLOEXEC))) {
return g_fds.p[fd].handle;
} else {
return -1;
}
}
textwindows int execve$nt(const char *program, char *const argv[],
char *const envp[]) {
int i;
uint32_t dwExitCode;
struct NtStartupInfo startinfo;
struct NtProcessInformation procinfo;
memset(&startinfo, 0, sizeof(startinfo));
startinfo.cb = sizeof(struct NtStartupInfo);
startinfo.dwFlags = kNtStartfUsestdhandles;
startinfo.hStdInput = passstdhand$nt(STDIN_FILENO);
startinfo.hStdOutput = passstdhand$nt(STDOUT_FILENO);
startinfo.hStdError = passstdhand$nt(STDERR_FILENO);
if (ntspawn(program, argv, envp, NULL, NULL, true, 0, NULL, &startinfo,
NULL) != -1) {
for (;;) TerminateProcess(GetCurrentProcess(), 0);
startinfo.hStdInput = g_fds.p[0].handle;
startinfo.hStdOutput = g_fds.p[1].handle;
startinfo.hStdError = g_fds.p[2].handle;
for (i = 2; i < g_fds.n; ++i) {
if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) {
close(i);
}
}
return -1;
if (ntspawn(program, argv, envp, NULL, NULL, true, 0, NULL, &startinfo,
&procinfo) == -1) {
return -1;
}
CloseHandle(procinfo.hThread);
for (i = 0; i < g_fds.n; ++i) {
if (g_fds.p[i].kind != kFdEmpty) {
close(i);
}
}
do {
WaitForSingleObject(procinfo.hProcess, -1);
dwExitCode = kNtStillActive;
GetExitCodeProcess(procinfo.hProcess, &dwExitCode);
} while (dwExitCode == kNtStillActive);
ExitProcess(dwExitCode);
}

View File

@ -17,20 +17,26 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/hefty/ntspawn.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/enum/startf.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/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
static textwindows int64_t ParseInt(char16_t **p) {
@ -42,8 +48,8 @@ static textwindows int64_t ParseInt(char16_t **p) {
return x;
}
static noinline textwindows void DoAll(int64_t h, void *buf, size_t n,
bool32 (*f)()) {
static noinline textwindows void ForkIo(int64_t h, void *buf, size_t n,
bool32 (*f)()) {
char *p;
size_t i;
uint32_t x;
@ -53,11 +59,11 @@ static noinline textwindows void DoAll(int64_t h, void *buf, size_t n,
}
static noinline textwindows void WriteAll(int64_t h, void *buf, size_t n) {
DoAll(h, buf, n, WriteFile);
ForkIo(h, buf, n, WriteFile);
}
static noinline textwindows void ReadAll(int64_t h, void *buf, size_t n) {
DoAll(h, buf, n, ReadFile);
ForkIo(h, buf, n, ReadFile);
}
textwindows void WinMainForked(void) {
@ -79,7 +85,7 @@ textwindows void WinMainForked(void) {
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) {
switch (_mmi.p[i].prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) {
case PROT_READ | PROT_WRITE | PROT_EXEC:
protect = kNtPageExecuteReadwrite;
access = kNtFileMapRead | kNtFileMapWrite | kNtFileMapExecute;
@ -117,9 +123,12 @@ textwindows void WinMainForked(void) {
textwindows int fork$nt(void) {
jmp_buf jb;
int i, rc, pid;
int64_t reader, writer;
int i, rc, pid, fds[3];
char *p, buf[21 + 1 + 21 + 1];
struct NtStartupInfo startinfo;
struct NtProcessInformation procinfo;
if ((pid = __getemptyfd()) == -1) return -1;
if (!setjmp(jb)) {
if (CreatePipe(&reader, &writer, &kNtIsInheritable, 0)) {
p = buf;
@ -127,12 +136,19 @@ textwindows int fork$nt(void) {
*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) {
memset(&startinfo, 0, sizeof(startinfo));
startinfo.cb = sizeof(struct NtStartupInfo);
startinfo.dwFlags = kNtStartfUsestdhandles;
startinfo.hStdInput = g_fds.p[0].handle;
startinfo.hStdOutput = g_fds.p[1].handle;
startinfo.hStdError = g_fds.p[2].handle;
if (ntspawn(g_argv[0], g_argv, environ, &kNtIsInheritable, NULL, true, 0,
NULL, &startinfo, &procinfo) != -1) {
CloseHandle(reader);
CloseHandle(procinfo.hThread);
g_fds.p[pid].kind = kFdProcess;
g_fds.p[pid].handle = procinfo.hProcess;
g_fds.p[pid].flags = O_CLOEXEC;
WriteAll(writer, jb, sizeof(jb));
WriteAll(writer, &_mmi.i, sizeof(_mmi.i));
for (i = 0; i < _mmi.i; ++i) {
@ -144,11 +160,11 @@ textwindows int fork$nt(void) {
}
WriteAll(writer, _edata, _end - _edata);
CloseHandle(writer);
rc = pid;
} else {
rc = -1;
}
unsetenv("_FORK");
rc = pid;
} else {
rc = __winerr();
}

View File

@ -96,5 +96,3 @@ error:
free(cmdline_p);
return NULL;
}
#undef APPENDCHAR

View File

@ -68,8 +68,8 @@ textwindows int ntspawn(
char16_t program16[PATH_MAX], *lpCommandLine, *lpEnvironment;
lpCommandLine = NULL;
lpEnvironment = NULL;
if (mkntpath(program, program16) != -1 &&
(lpCommandLine = mkntcmdline(argv)) &&
if (__mkntpath(program, program16) != -1 &&
(lpCommandLine = mkntcmdline(&argv[1])) &&
(lpEnvironment = mkntenvblock(envp))) {
if (CreateProcess(program16, lpCommandLine, opt_lpProcessAttributes,
opt_lpThreadAttributes, bInheritHandles,

View File

@ -21,7 +21,6 @@
#include "libc/alg/arraylist.internal.h"
#include "libc/calls/hefty/ntspawn.h"
#include "libc/dce.h"
#include "libc/nexgen32e/tinystrcmp.internal.h"
#include "libc/str/str.h"
static int CompareStrings(const char *l, const char *r) {

View File

@ -94,6 +94,6 @@ textwindows int spawnve$nt(unsigned flags, int stdiofds[3], const char *program,
g_fds.p[pid].kind = kFdProcess;
g_fds.p[pid].handle = handle;
g_fds.p[pid].flags = flags;
g_fds.p[pid].flags = O_CLOEXEC;
return pid;
}

View File

@ -252,6 +252,7 @@ int nanosleep$nt(const struct timespec *, struct timespec *) hidden;
cosmopolitan § syscalls » windows nt » support
*/
int64_t ntreturn(uint32_t);
void WinMainForked(void) hidden;
void *GetProcAddressModule(const char *, const char *) hidden;
int getsetpriority$nt(int, unsigned, int, int (*)(int));
@ -261,19 +262,9 @@ bool32 ntsetprivilege(i64, const char16_t *, u32) hidden;
bool32 onntconsoleevent$nt(u32) hidden;
void __winalarm(void *, uint32_t, uint32_t) hidden;
int ntaccesscheck(const char16_t *, u32) paramsnonnull() hidden;
i64 ntreturn(u32);
i64 __winerr(void) nocallback privileged;
#define mkntpath(PATH, PATH16) mkntpath2(PATH, -1u, PATH16)
#define mkntpath2(PATH, FLAGS, PATH16) \
({ \
int Count; \
asm("call\tmkntpath" \
: "=a"(Count), "=m"(*PATH16) \
: "D"(PATH), "S"(FLAGS), "d"(&PATH16[0]), "m"((PATH)[0]) \
: "cc"); \
Count; \
})
int64_t __winerr(void) nocallback privileged;
int __mkntpath(const char *, char16_t[hasatleast PATH_MAX - 16]) hidden;
int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX - 16], int) hidden;
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § syscalls » drivers

View File

@ -25,8 +25,8 @@
textwindows int link$nt(const char *existingpath, const char *newpath) {
char16_t newpath16[PATH_MAX];
char16_t existingpath16[PATH_MAX];
if (mkntpath(existingpath, existingpath16) != -1 &&
mkntpath(newpath, newpath16) != -1) {
if (__mkntpath(existingpath, existingpath16) != -1 &&
__mkntpath(newpath, newpath16) != -1) {
if (CreateHardLink(newpath16, existingpath16, NULL)) {
return 0;
} else {

View File

@ -27,7 +27,7 @@
static textwindows noinline int mkdir$nt(const char *path, uint32_t mode) {
uint16_t path16[PATH_MAX];
if (mkntpath(path, path16) == -1) return -1;
if (__mkntpath(path, path16) == -1) return -1;
if (CreateDirectory(path16, NULL)) {
return 0;
} else {

View File

@ -17,8 +17,8 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/calls/internal.h"
#include "libc/calls/ntmagicpaths.internal.h"
#include "libc/nexgen32e/tinystrcmp.internal.h"
#include "libc/str/oldutf16.internal.h"
#include "libc/str/str.h"
#include "libc/str/tpdecode.internal.h"
@ -30,19 +30,24 @@ textwindows static const char *FixNtMagicPath(const char *path,
const struct NtMagicPaths *mp = &kNtMagicPaths;
asm("" : "+r"(mp));
if (path[0] != '/') return path;
if (tinystrcmp(path, mp->devtty) == 0) {
if (strcmp(path, mp->devtty) == 0) {
if ((flags & O_ACCMODE) == O_RDONLY) {
return mp->conin;
} else if ((flags & O_ACCMODE) == O_WRONLY) {
return mp->conout;
}
}
if (tinystrcmp(path, mp->devnull) == 0) return mp->nul;
if (tinystrcmp(path, mp->devstdin) == 0) return mp->conin;
if (tinystrcmp(path, mp->devstdout) == 0) return mp->conout;
if (strcmp(path, mp->devnull) == 0) return mp->nul;
if (strcmp(path, mp->devstdin) == 0) return mp->conin;
if (strcmp(path, mp->devstdout) == 0) return mp->conout;
return path;
}
textwindows int __mkntpath(const char *path,
char16_t path16[hasatleast PATH_MAX - 16]) {
return __mkntpath2(path, path16, -1);
}
/**
* Copies path for Windows NT.
*
@ -56,9 +61,9 @@ textwindows static const char *FixNtMagicPath(const char *path,
* @return short count excluding NUL on success, or -1 w/ errno
* @error ENAMETOOLONG
*/
forcealignargpointer textwindows int mkntpath(
const char *path, unsigned flags,
char16_t path16[hasatleast PATH_MAX - 16]) {
textwindows int __mkntpath2(const char *path,
char16_t path16[hasatleast PATH_MAX - 16],
int flags) {
/*
* 1. Reserve +1 for NUL-terminator
* 2. Reserve +1 for UTF-16 overflow
@ -66,31 +71,14 @@ forcealignargpointer textwindows int mkntpath(
* 4. Reserve 10 for CreateNamedPipe "\\.\pipe\" prefix requirement
* 5. Reserve 13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
*/
int rc;
wint_t wc;
size_t i, j;
size_t i, n;
path = FixNtMagicPath(path, flags);
i = 0;
j = 0;
for (;;) {
if ((rc = tpdecode(&path[i], &wc)) == -1) {
path16[0] = u'\0';
return -1;
}
if (!wc) break;
i += (size_t)rc;
if (wc == '/') wc = '\\';
if (j + 1 /* utf-16 */ + 1 /* chdir() */ + 1 /* NUL */ < PATH_MAX - 16) {
if ((rc = pututf16(&path16[j], 2, wc, false)) == -1) {
path16[0] = u'\0';
return -1;
}
j += (size_t)rc;
} else {
path16[0] = u'\0';
return enametoolong();
n = tprecode8to16(path16, PATH_MAX - 16, path).ax;
if (n == PATH_MAX - 16 - 1) return enametoolong();
for (i = 0; i < n; ++i) {
if (path16[i] == '/') {
path16[i] = '\\';
}
}
path16[j] = u'\0';
return j;
return n;
}

View File

@ -20,7 +20,6 @@
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/calls/ntmagicpaths.internal.h"
#include "libc/nexgen32e/tinystrcmp.internal.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h"
@ -31,6 +30,7 @@
#include "libc/nt/errors.h"
#include "libc/nt/files.h"
#include "libc/nt/runtime.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/fileno.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
@ -40,7 +40,7 @@ static textwindows int64_t open$nt$impl(const char *file, uint32_t flags,
uint32_t br;
int64_t handle;
char16_t file16[PATH_MAX];
if (mkntpath2(file, flags, file16) == -1) return -1;
if (__mkntpath2(file, file16, flags) == -1) return -1;
if ((handle = CreateFile(
file16,
(flags & 0xf000000f) | (/* this is needed if we mmap(rwx+cow)
@ -119,7 +119,7 @@ textwindows ssize_t open$nt(const char *file, uint32_t flags, int32_t mode) {
size_t fd;
if ((fd = __getemptyfd()) == -1) return -1;
if ((flags & O_ACCMODE) == O_RDWR &&
tinystrcmp(file, kNtMagicPaths.devtty) == 0) {
strcmp(file, kNtMagicPaths.devtty) == 0) {
return open$nt$console(&kNtMagicPaths, flags, mode, fd);
} else {
return open$nt$file(file, flags, mode, fd);

View File

@ -27,8 +27,8 @@
textwindows int rename$nt(const char *oldpath, const char *newpath) {
char16_t oldpath16[PATH_MAX];
char16_t newpath16[PATH_MAX];
if (mkntpath(oldpath, oldpath16) == -1 ||
mkntpath(newpath, newpath16) == -1) {
if (__mkntpath(oldpath, oldpath16) == -1 ||
__mkntpath(newpath, newpath16) == -1) {
return -1;
}
if (MoveFileEx(oldpath16, newpath16, kNtMovefileReplaceExisting)) {

View File

@ -23,7 +23,7 @@
textwindows int rmdir$nt(const char *path) {
uint16_t path16[PATH_MAX];
if (mkntpath(path, path16) == -1) return -1;
if (__mkntpath(path, path16) == -1) return -1;
if (RemoveDirectory(path16)) {
return 0;
} else {