Make improvements
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user