Make improvements
parent
3e4fd4b0ad
commit
e44a0cf6f8
2
Makefile
2
Makefile
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
136
examples/acid2.c
136
examples/acid2.c
|
@ -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("A");
|
||||
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;
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -96,5 +96,3 @@ error:
|
|||
free(cmdline_p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef APPENDCHAR
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 ─╬─│┼
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 {
|
||||
|
|