mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-01 00:38:31 +00:00
Make improvements
- Expand redbean UNIX module - Expand redbean documentation - Ensure Lua copyright is embedded in binary - Increase the PATH_MAX limit especially on NT - Use column major sorting for linenoise completions - Fix some suboptimalities in redbean's new UNIX API - Figured out right flags for Multics newline in raw mode
This commit is contained in:
parent
cf3174dc74
commit
2046c0d2ae
305 changed files with 6602 additions and 4221 deletions
|
@ -75,7 +75,7 @@ bool isregularfile(const char *);
|
|||
bool issymlink(const char *);
|
||||
bool32 isatty(int) nosideeffect;
|
||||
bool32 ischardev(int) nosideeffect;
|
||||
char *commandv(const char *, char[hasatleast PATH_MAX]);
|
||||
char *commandv(const char *, char *, size_t);
|
||||
char *get_current_dir_name(void) dontdiscard;
|
||||
char *getcwd(char *, size_t);
|
||||
char *realpath(const char *, char *);
|
||||
|
@ -120,13 +120,16 @@ int ftruncate(int, int64_t);
|
|||
int getdents(unsigned, void *, unsigned, long *);
|
||||
int getdomainname(char *, size_t);
|
||||
int gethostname(char *, size_t);
|
||||
int getloadavg(double *, int);
|
||||
int getpgid(int);
|
||||
int getpgrp(void) nosideeffect;
|
||||
int getpid(void);
|
||||
int gettid(void);
|
||||
int getppid(void);
|
||||
int getpriority(int, unsigned);
|
||||
int getrlimit(int, struct rlimit *);
|
||||
int getrusage(int, struct rusage *);
|
||||
int getsid(int) nosideeffect;
|
||||
int gettid(void);
|
||||
int kill(int, int);
|
||||
int killpg(int, int);
|
||||
int link(const char *, const char *) dontthrow;
|
||||
|
@ -165,11 +168,12 @@ int rmdir(const char *);
|
|||
int sched_getaffinity(int, uint64_t, void *);
|
||||
int sched_setaffinity(int, uint64_t, const void *);
|
||||
int sched_yield(void);
|
||||
int seccomp(unsigned, unsigned, void *);
|
||||
int setegid(uint32_t);
|
||||
int seteuid(uint32_t);
|
||||
int setgid(int);
|
||||
int setpgrp(void);
|
||||
int setpgid(int, int);
|
||||
int setpgrp(void);
|
||||
int setpriority(int, unsigned, int);
|
||||
int setregid(uint32_t, uint32_t);
|
||||
int setresgid(uint32_t, uint32_t, uint32_t);
|
||||
|
@ -206,9 +210,9 @@ long ptrace(int, ...);
|
|||
long telldir(DIR *);
|
||||
long times(struct tms *);
|
||||
size_t GetFileSize(const char *);
|
||||
ssize_t getfiledescriptorsize(int);
|
||||
ssize_t copy_file_range(int, long *, int, long *, size_t, uint32_t);
|
||||
ssize_t copyfd(int, int64_t *, int, int64_t *, size_t, uint32_t);
|
||||
ssize_t getfiledescriptorsize(int);
|
||||
ssize_t lseek(int, int64_t, unsigned);
|
||||
ssize_t pread(int, void *, size_t, int64_t);
|
||||
ssize_t preadv(int, struct iovec *, int, int64_t);
|
||||
|
@ -225,14 +229,11 @@ struct dirent *readdir(DIR *);
|
|||
uint32_t getegid(void) nosideeffect;
|
||||
uint32_t geteuid(void) nosideeffect;
|
||||
uint32_t getgid(void) nosideeffect;
|
||||
uint32_t getpgrp(void) nosideeffect;
|
||||
uint32_t getsid(int) nosideeffect;
|
||||
uint32_t getuid(void) nosideeffect;
|
||||
uint32_t umask(uint32_t);
|
||||
void rewinddir(DIR *);
|
||||
void sync(void);
|
||||
int getloadavg(double *, int);
|
||||
int seccomp(unsigned, unsigned, void *);
|
||||
|
||||
int clone(int (*)(void *), void *, size_t, int, void *, int *, void *, size_t,
|
||||
int *);
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
textwindows int sys_chdir_nt(const char *path) {
|
||||
uint32_t n;
|
||||
int e, ms, err, len;
|
||||
char16_t path16[PATH_MAX], var[4];
|
||||
char16_t path16[PATH_MAX + 1], var[4];
|
||||
if ((len = __mkntpath(path, path16)) == -1) return -1;
|
||||
if (!len) return enoent();
|
||||
if (len && path16[len - 1] != u'\\') {
|
||||
|
|
|
@ -73,7 +73,9 @@ int close(int fd) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!__vforked) __releasefd(fd);
|
||||
if (!__vforked) {
|
||||
__releasefd(fd);
|
||||
}
|
||||
}
|
||||
STRACE("%s(%d) → %d% m", "close", fd, rc);
|
||||
return rc;
|
||||
|
|
|
@ -43,15 +43,16 @@ static bool IsComDbgPath(const char *s, size_t n) {
|
|||
READ64LE(s + n - 8) == READ64LE(".COM.DBG"));
|
||||
}
|
||||
|
||||
static bool AccessCommand(const char *name, char path[hasatleast PATH_MAX],
|
||||
static bool AccessCommand(const char *name, char *path, size_t pathsz,
|
||||
size_t namelen, int *err, const char *suffix,
|
||||
size_t pathlen) {
|
||||
size_t suffixlen;
|
||||
suffixlen = strlen(suffix);
|
||||
if (pathlen + 1 + namelen + suffixlen + 1 > PATH_MAX) return false;
|
||||
if (pathlen + 1 + namelen + suffixlen + 1 > pathsz) return false;
|
||||
if (pathlen && (path[pathlen - 1] != '/' && path[pathlen - 1] != '\\')) {
|
||||
path[pathlen] =
|
||||
!IsWindows() ? '/' : memchr(path, '\\', pathlen) ? '\\' : '/';
|
||||
path[pathlen] = !IsWindows() ? '/'
|
||||
: memchr(path, '\\', pathlen) ? '\\'
|
||||
: '/';
|
||||
pathlen++;
|
||||
}
|
||||
memcpy(path + pathlen, name, namelen);
|
||||
|
@ -61,7 +62,7 @@ static bool AccessCommand(const char *name, char path[hasatleast PATH_MAX],
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool SearchPath(const char *name, char path[hasatleast PATH_MAX],
|
||||
static bool SearchPath(const char *name, char *path, size_t pathsz,
|
||||
size_t namelen, int *err, const char *suffix) {
|
||||
char sep;
|
||||
size_t i;
|
||||
|
@ -70,11 +71,11 @@ static bool SearchPath(const char *name, char path[hasatleast PATH_MAX],
|
|||
sep = IsWindows() && strchr(p, ';') ? ';' : ':';
|
||||
for (;;) {
|
||||
for (i = 0; p[i] && p[i] != sep; ++i) {
|
||||
if (i < PATH_MAX) {
|
||||
if (i < pathsz) {
|
||||
path[i] = p[i];
|
||||
}
|
||||
}
|
||||
if (AccessCommand(name, path, namelen, err, suffix, i)) {
|
||||
if (AccessCommand(name, path, pathsz, namelen, err, suffix, i)) {
|
||||
return true;
|
||||
}
|
||||
if (p[i] == sep) {
|
||||
|
@ -86,36 +87,36 @@ static bool SearchPath(const char *name, char path[hasatleast PATH_MAX],
|
|||
return false;
|
||||
}
|
||||
|
||||
static bool FindCommand(const char *name, char pathbuf[hasatleast PATH_MAX],
|
||||
size_t namelen, bool priorityonly, const char *suffix,
|
||||
int *err) {
|
||||
if (priorityonly &&
|
||||
(memchr(name, '/', namelen) || memchr(name, '\\', namelen))) {
|
||||
pathbuf[0] = 0;
|
||||
return AccessCommand(name, pathbuf, namelen, err, suffix, 0);
|
||||
static bool FindCommand(const char *name, char *pb, size_t pbsz, size_t namelen,
|
||||
bool pri, const char *suffix, int *err) {
|
||||
if (pri && (memchr(name, '/', namelen) || memchr(name, '\\', namelen))) {
|
||||
pb[0] = 0;
|
||||
return AccessCommand(name, pb, pbsz, namelen, err, suffix, 0);
|
||||
}
|
||||
if (IsWindows() && priorityonly) {
|
||||
return AccessCommand(name, pathbuf, namelen, err, suffix,
|
||||
stpcpy(pathbuf, kNtSystemDirectory) - pathbuf) ||
|
||||
AccessCommand(name, pathbuf, namelen, err, suffix,
|
||||
stpcpy(pathbuf, kNtWindowsDirectory) - pathbuf);
|
||||
if (IsWindows() && pri &&
|
||||
pbsz > max(strlen(kNtSystemDirectory), strlen(kNtWindowsDirectory))) {
|
||||
return AccessCommand(name, pb, pbsz, namelen, err, suffix,
|
||||
stpcpy(pb, kNtSystemDirectory) - pb) ||
|
||||
AccessCommand(name, pb, pbsz, namelen, err, suffix,
|
||||
stpcpy(pb, kNtWindowsDirectory) - pb);
|
||||
}
|
||||
return (IsWindows() && AccessCommand(name, pathbuf, namelen, err, suffix,
|
||||
stpcpy(pathbuf, ".") - pathbuf)) ||
|
||||
SearchPath(name, pathbuf, namelen, err, suffix);
|
||||
return (IsWindows() &&
|
||||
(pbsz > 1 && AccessCommand(name, pb, pbsz, namelen, err, suffix,
|
||||
stpcpy(pb, ".") - pb))) ||
|
||||
SearchPath(name, pb, pbsz, namelen, err, suffix);
|
||||
}
|
||||
|
||||
static bool FindVerbatim(const char *name, char pathbuf[hasatleast PATH_MAX],
|
||||
size_t namelen, bool priorityonly, int *err) {
|
||||
return FindCommand(name, pathbuf, namelen, priorityonly, "", err);
|
||||
static bool FindVerbatim(const char *name, char *pb, size_t pbsz,
|
||||
size_t namelen, bool pri, int *err) {
|
||||
return FindCommand(name, pb, pbsz, namelen, pri, "", err);
|
||||
}
|
||||
|
||||
static bool FindSuffixed(const char *name, char pathbuf[hasatleast PATH_MAX],
|
||||
size_t namelen, bool priorityonly, int *err) {
|
||||
static bool FindSuffixed(const char *name, char *pb, size_t pbsz,
|
||||
size_t namelen, bool pri, int *err) {
|
||||
return !IsExePath(name, namelen) && !IsComPath(name, namelen) &&
|
||||
!IsComDbgPath(name, namelen) &&
|
||||
(FindCommand(name, pathbuf, namelen, priorityonly, ".com", err) ||
|
||||
FindCommand(name, pathbuf, namelen, priorityonly, ".exe", err));
|
||||
(FindCommand(name, pb, pbsz, namelen, pri, ".com", err) ||
|
||||
FindCommand(name, pb, pbsz, namelen, pri, ".exe", err));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -127,7 +128,7 @@ static bool FindSuffixed(const char *name, char pathbuf[hasatleast PATH_MAX],
|
|||
* @asyncsignalsafe
|
||||
* @vforksafe
|
||||
*/
|
||||
char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
||||
char *commandv(const char *name, char *pathbuf, size_t pathbufsz) {
|
||||
int e, f;
|
||||
char *res;
|
||||
size_t namelen;
|
||||
|
@ -136,25 +137,27 @@ char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
|||
efault();
|
||||
} else if (!(namelen = strlen(name))) {
|
||||
enoent();
|
||||
} else if (namelen + 1 > PATH_MAX) {
|
||||
} else if (namelen + 1 > pathbufsz) {
|
||||
enametoolong();
|
||||
} else {
|
||||
e = errno;
|
||||
f = ENOENT;
|
||||
if ((IsWindows() && (FindSuffixed(name, pathbuf, namelen, true, &f) ||
|
||||
FindVerbatim(name, pathbuf, namelen, true, &f) ||
|
||||
FindSuffixed(name, pathbuf, namelen, false, &f) ||
|
||||
FindVerbatim(name, pathbuf, namelen, false, &f))) ||
|
||||
(!IsWindows() && (FindVerbatim(name, pathbuf, namelen, true, &f) ||
|
||||
FindSuffixed(name, pathbuf, namelen, true, &f) ||
|
||||
FindVerbatim(name, pathbuf, namelen, false, &f) ||
|
||||
FindSuffixed(name, pathbuf, namelen, false, &f)))) {
|
||||
if ((IsWindows() &&
|
||||
(FindSuffixed(name, pathbuf, pathbufsz, namelen, true, &f) ||
|
||||
FindVerbatim(name, pathbuf, pathbufsz, namelen, true, &f) ||
|
||||
FindSuffixed(name, pathbuf, pathbufsz, namelen, false, &f) ||
|
||||
FindVerbatim(name, pathbuf, pathbufsz, namelen, false, &f))) ||
|
||||
(!IsWindows() &&
|
||||
(FindVerbatim(name, pathbuf, pathbufsz, namelen, true, &f) ||
|
||||
FindSuffixed(name, pathbuf, pathbufsz, namelen, true, &f) ||
|
||||
FindVerbatim(name, pathbuf, pathbufsz, namelen, false, &f) ||
|
||||
FindSuffixed(name, pathbuf, pathbufsz, namelen, false, &f)))) {
|
||||
errno = e;
|
||||
res = pathbuf;
|
||||
} else {
|
||||
errno = f;
|
||||
}
|
||||
}
|
||||
STRACE("commandv(%#s, %p) → %#s% m", name, pathbuf, res);
|
||||
STRACE("commandv(%#s, %p, %'zu) → %#s% m", name, pathbuf, pathbufsz, res);
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ static textwindows int sys_copyfile_nt(const char *src, const char *dst,
|
|||
int flags) {
|
||||
int64_t fhsrc, fhdst;
|
||||
struct NtFileTime accessed, modified;
|
||||
char16_t src16[PATH_MAX], dst16[PATH_MAX];
|
||||
char16_t src16[PATH_MAX + 1], dst16[PATH_MAX + 1];
|
||||
if (__mkntpath(src, src16) == -1) return -1;
|
||||
if (__mkntpath(dst, dst16) == -1) return -1;
|
||||
if (CopyFile(src16, dst16, !!(flags & COPYFILE_NOCLOBBER))) {
|
||||
|
|
|
@ -39,8 +39,8 @@ int execlp(const char *prog, const char *arg, ... /*, NULL*/) {
|
|||
char *exe;
|
||||
char **argv;
|
||||
va_list va, vb;
|
||||
char pathbuf[PATH_MAX];
|
||||
if (!(exe = commandv(prog, pathbuf))) return -1;
|
||||
char pathbuf[PATH_MAX + 1];
|
||||
if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) return -1;
|
||||
va_copy(vb, va);
|
||||
va_start(va, arg);
|
||||
for (i = 0; va_arg(va, const char *); ++i) donothing;
|
||||
|
|
|
@ -33,7 +33,8 @@ int sys_execve(const char *prog, char *const argv[], char *const envp[]) {
|
|||
shargs = alloca((i + 2) * sizeof(char *));
|
||||
memcpy(shargs + 2, argv + 1, i * sizeof(char *));
|
||||
if (IsFreebsd() || IsNetbsd()) {
|
||||
shargs[0] = firstnonnull(commandv("bash", alloca(PATH_MAX)), _PATH_BSHELL);
|
||||
shargs[0] = firstnonnull(
|
||||
commandv("bash", alloca(PATH_MAX + 1), PATH_MAX + 1), _PATH_BSHELL);
|
||||
} else {
|
||||
shargs[0] = _PATH_BSHELL;
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ int execve(const char *prog, char *const argv[], char *const envp[]) {
|
|||
if (i) kprintf(", ");
|
||||
kprintf("%#s", envp[i]);
|
||||
}
|
||||
kprintf("})%n");
|
||||
kprintf("})\n");
|
||||
}
|
||||
#endif
|
||||
for (i = 3; i < g_fds.n; ++i) {
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
*/
|
||||
int execvpe(const char *prog, char *const argv[], char *const *envp) {
|
||||
char *exe;
|
||||
char pathbuf[PATH_MAX];
|
||||
char pathbuf[PATH_MAX + 1];
|
||||
if (IsAsan() && !__asan_is_valid(prog, 1)) return efault();
|
||||
if (!(exe = commandv(prog, pathbuf))) return -1;
|
||||
if (!(exe = commandv(prog, pathbuf, sizeof(pathbuf)))) return -1;
|
||||
return execve(exe, argv, envp);
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int sys_faccessat_nt(int dirfd, const char *path, int mode, uint32_t flags) {
|
||||
char16_t path16[PATH_MAX];
|
||||
char16_t path16[PATH_MAX + 1];
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
return __fix_enotdir(ntaccesscheck(path16, mode), path16);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
textwindows int sys_fchdir_nt(int dirfd) {
|
||||
uint32_t len;
|
||||
char16_t dir[PATH_MAX];
|
||||
char16_t dir[PATH_MAX + 1];
|
||||
if (!__isfdkind(dirfd, kFdFile)) return ebadf();
|
||||
len = GetFinalPathNameByHandle(g_fds.p[dirfd].handle, dir, ARRAYLEN(dir),
|
||||
kNtFileNameNormalized | kNtVolumeNameDos);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
textwindows int sys_fchmodat_nt(int dirfd, const char *path, uint32_t mode,
|
||||
int flags) {
|
||||
uint32_t attr;
|
||||
uint16_t path16[PATH_MAX];
|
||||
uint16_t path16[PATH_MAX + 1];
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
if ((attr = GetFileAttributes(path16)) != -1u) {
|
||||
if (mode & 0200) {
|
||||
|
|
|
@ -48,7 +48,7 @@ bool fileexists(const char *path) {
|
|||
bool res;
|
||||
union metastat st;
|
||||
struct ZiposUri zipname;
|
||||
uint16_t path16[PATH_MAX];
|
||||
uint16_t path16[PATH_MAX + 1];
|
||||
e = errno;
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) {
|
||||
efault();
|
||||
|
|
|
@ -29,7 +29,7 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
|||
int flags) {
|
||||
int rc;
|
||||
int64_t fh;
|
||||
uint16_t path16[PATH_MAX];
|
||||
uint16_t path16[PATH_MAX + 1];
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
if ((fh = CreateFile(
|
||||
path16, kNtFileReadAttributes, 0, 0, kNtOpenExisting,
|
||||
|
|
|
@ -28,15 +28,22 @@ textwindows char *sys_getcwd_nt(char *buf, size_t size) {
|
|||
uint64_t w;
|
||||
wint_t x, y;
|
||||
uint32_t n, i, j;
|
||||
char16_t name16[PATH_MAX + 1];
|
||||
if ((n = GetCurrentDirectory(ARRAYLEN(name16), name16))) {
|
||||
if (n <= PATH_MAX) {
|
||||
tprecode16to8(buf, size, name16);
|
||||
for (j = i = 0; i < n;) {
|
||||
x = name16[i++] & 0xffff;
|
||||
char16_t p[PATH_MAX + 1];
|
||||
if ((n = GetCurrentDirectory(ARRAYLEN(p), p))) {
|
||||
if (4 + n + 1 <= size && 4 + n + 1 <= ARRAYLEN(p)) {
|
||||
tprecode16to8(buf, size, p);
|
||||
j = 0;
|
||||
if (n >= 3 && isalpha(p[0]) && p[1] == ':' && p[2] == '\\') {
|
||||
buf[j++] = '/';
|
||||
buf[j++] = '/';
|
||||
buf[j++] = '?';
|
||||
buf[j++] = '/';
|
||||
}
|
||||
for (i = 0; i < n;) {
|
||||
x = p[i++] & 0xffff;
|
||||
if (!IsUcs2(x)) {
|
||||
if (i < n) {
|
||||
y = name16[i++] & 0xffff;
|
||||
y = p[i++] & 0xffff;
|
||||
x = MergeUtf16(x, y);
|
||||
} else {
|
||||
x = 0xfffd;
|
||||
|
|
|
@ -19,13 +19,19 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
/**
|
||||
* Returns effective group ID of calling process.
|
||||
* @return group id
|
||||
*/
|
||||
uint32_t getegid(void) {
|
||||
int rc;
|
||||
rc = sys_getegid();
|
||||
if (!IsWindows()) {
|
||||
rc = sys_getegid();
|
||||
} else {
|
||||
rc = getgid();
|
||||
}
|
||||
STRACE("%s() → %d% m", "getegid", rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -22,10 +22,15 @@
|
|||
|
||||
/**
|
||||
* Returns effective user ID of calling process.
|
||||
* @return user id
|
||||
*/
|
||||
uint32_t geteuid(void) {
|
||||
int rc;
|
||||
rc = sys_geteuid();
|
||||
if (!IsWindows()) {
|
||||
rc = sys_geteuid();
|
||||
} else {
|
||||
rc = getuid();
|
||||
}
|
||||
STRACE("%s() → %d% m", "geteuid", rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
/**
|
||||
* Returns process group id of calling process.
|
||||
*/
|
||||
uint32_t getpgrp(void) {
|
||||
int getpgrp(void) {
|
||||
int rc;
|
||||
if (!IsWindows()) {
|
||||
rc = sys_getpgrp();
|
||||
|
|
|
@ -18,11 +18,14 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
#include "libc/nt/accounting.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/iocounters.h"
|
||||
#include "libc/nt/struct/processmemorycounters.h"
|
||||
#include "libc/nt/thread.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -30,22 +33,32 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_getrusage_nt(int who, struct rusage *usage) {
|
||||
int64_t me, nsignals;
|
||||
struct NtIoCounters iocount;
|
||||
struct NtProcessMemoryCountersEx memcount;
|
||||
struct NtFileTime ftExit, ftUser, ftKernel, ftCreation;
|
||||
if (!usage) return efault();
|
||||
if (who == 99) return enosys(); // @see libc/sysv/consts.sh
|
||||
if (!usage) return 0;
|
||||
me = GetCurrentProcess();
|
||||
if (!(who == RUSAGE_SELF ? GetProcessTimes : GetThreadTimes)(
|
||||
(who == RUSAGE_SELF ? GetCurrentProcess : GetCurrentThread)(),
|
||||
&ftCreation, &ftExit, &ftKernel, &ftUser) ||
|
||||
!GetProcessMemoryInfo(GetCurrentProcess(), &memcount, sizeof(memcount))) {
|
||||
!GetProcessMemoryInfo(me, &memcount, sizeof(memcount)) ||
|
||||
!GetProcessIoCounters(me, &iocount)) {
|
||||
return __winerr();
|
||||
}
|
||||
_spinlock(&__sig_lock);
|
||||
nsignals = __sig_count;
|
||||
_spunlock(&__sig_lock);
|
||||
*usage = (struct rusage){
|
||||
.ru_utime = WindowsDurationToTimeVal(ReadFileTime(ftUser)),
|
||||
.ru_stime = WindowsDurationToTimeVal(ReadFileTime(ftKernel)),
|
||||
.ru_maxrss = memcount.PeakWorkingSetSize / 1024,
|
||||
.ru_majflt = memcount.PageFaultCount,
|
||||
.ru_inblock = iocount.ReadOperationCount,
|
||||
.ru_oublock = iocount.WriteOperationCount,
|
||||
.ru_nsignals = __sig_count,
|
||||
};
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
/**
|
||||
* Creates session and sets the process group id.
|
||||
*/
|
||||
uint32_t getsid(int pid) {
|
||||
int getsid(int pid) {
|
||||
int rc;
|
||||
rc = sys_getsid(pid);
|
||||
STRACE("%s(%d) → %d% m", "getsid", pid, rc);
|
||||
|
|
|
@ -88,7 +88,7 @@ int __reservefd(int) hidden;
|
|||
void __releasefd(int) hidden;
|
||||
int __ensurefds(int) hidden;
|
||||
int64_t __getfdhandleactual(int) hidden;
|
||||
void __printfds(void);
|
||||
void __printfds(void) hidden;
|
||||
|
||||
forceinline bool __isfdopen(int fd) {
|
||||
return 0 <= fd && fd < g_fds.n && g_fds.p[fd].kind != kFdEmpty;
|
||||
|
@ -165,6 +165,7 @@ i32 sys_getppid(void) hidden;
|
|||
i32 sys_getpriority(i32, u32) hidden;
|
||||
i32 sys_getrlimit(i32, struct rlimit *) hidden;
|
||||
i32 sys_getrusage(i32, struct rusage *) hidden;
|
||||
i32 sys_getsid(int) hidden;
|
||||
i32 sys_ioctl(i32, u64, ...) hidden;
|
||||
i32 sys_kill(i32, i32, i32) hidden;
|
||||
i32 sys_linkat(i32, const char *, i32, const char *, i32) hidden;
|
||||
|
@ -191,8 +192,10 @@ i32 sys_setgid(i32) hidden;
|
|||
i32 sys_setitimer(i32, const struct itimerval *, struct itimerval *) hidden;
|
||||
i32 sys_setpgid(i32, i32) hidden;
|
||||
i32 sys_setpriority(i32, u32, i32) hidden;
|
||||
i32 sys_setregid(u32, u32) hidden;
|
||||
i32 sys_setresgid(uint32_t, uint32_t, uint32_t) hidden;
|
||||
i32 sys_setresuid(uint32_t, uint32_t, uint32_t) hidden;
|
||||
i32 sys_setreuid(u32, u32) hidden;
|
||||
i32 sys_setrlimit(i32, const struct rlimit *) hidden;
|
||||
i32 sys_setsid(void) hidden;
|
||||
i32 sys_setuid(i32) hidden;
|
||||
|
@ -230,7 +233,6 @@ i64 sys_write(i32, const void *, u64) hidden;
|
|||
u32 sys_getegid(void) hidden;
|
||||
u32 sys_geteuid(void) hidden;
|
||||
u32 sys_getgid(void) hidden;
|
||||
u32 sys_getsid(int) hidden;
|
||||
u32 sys_gettid(void) hidden;
|
||||
u32 sys_getuid(void) hidden;
|
||||
u32 sys_umask(u32) hidden;
|
||||
|
@ -337,9 +339,10 @@ bool isregularfile_nt(const char *) hidden;
|
|||
bool issymlink_nt(const char *) hidden;
|
||||
bool32 ntsetprivilege(i64, const char16_t *, u32) hidden;
|
||||
char16_t *CreatePipeName(char16_t *) hidden;
|
||||
int __mkntpath(const char *, char16_t[hasatleast PATH_MAX - 16]) hidden;
|
||||
int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX - 16], int) hidden;
|
||||
int __mkntpathat(int, const char *, int, char16_t[PATH_MAX]) hidden;
|
||||
int __mkntpath(const char *, char16_t[hasatleast PATH_MAX + 1]) hidden;
|
||||
int __mkntpath2(const char *, char16_t[hasatleast PATH_MAX + 1], int) hidden;
|
||||
int __mkntpathat(int, const char *, int,
|
||||
char16_t[hasatleast PATH_MAX + 1]) hidden;
|
||||
int sys_clock_gettime_nt(int, struct timespec *) hidden;
|
||||
int ntaccesscheck(const char16_t *, u32) paramsnonnull() hidden;
|
||||
int sys_getsetpriority_nt(int, int, int, int (*)(int));
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/termios.h"
|
||||
#include "libc/calls/ttydefaults.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/enum/consolemodeflags.h"
|
||||
#include "libc/nt/struct/consolescreenbufferinfoex.h"
|
||||
|
@ -35,6 +36,23 @@ textwindows int ioctl_tcgets_nt(int ignored, struct termios *tio) {
|
|||
outok = GetConsoleMode((out = __getfdhandleactual(1)), &outmode);
|
||||
if (inok | outok) {
|
||||
bzero(tio, sizeof(*tio));
|
||||
|
||||
tio->c_cflag |= CS8;
|
||||
|
||||
tio->c_cc[VINTR] = CTRL('C');
|
||||
tio->c_cc[VQUIT] = CTRL('\\');
|
||||
tio->c_cc[VERASE] = CTRL('?');
|
||||
tio->c_cc[VKILL] = CTRL('U');
|
||||
tio->c_cc[VEOF] = CTRL('D');
|
||||
tio->c_cc[VMIN] = CTRL('A');
|
||||
tio->c_cc[VSTART] = CTRL('Q');
|
||||
tio->c_cc[VSTOP] = CTRL('S');
|
||||
tio->c_cc[VSUSP] = CTRL('Z');
|
||||
tio->c_cc[VREPRINT] = CTRL('R');
|
||||
tio->c_cc[VDISCARD] = CTRL('O');
|
||||
tio->c_cc[VWERASE] = CTRL('W');
|
||||
tio->c_cc[VLNEXT] = CTRL('V');
|
||||
|
||||
if (inok) {
|
||||
if (inmode & kNtEnableLineInput) {
|
||||
tio->c_lflag |= ICANON;
|
||||
|
@ -44,16 +62,21 @@ textwindows int ioctl_tcgets_nt(int ignored, struct termios *tio) {
|
|||
}
|
||||
if (inmode & kNtEnableProcessedInput) {
|
||||
tio->c_lflag |= IEXTEN | ISIG;
|
||||
if (tio->c_lflag | ECHO) {
|
||||
tio->c_lflag |= ECHOE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (outok) {
|
||||
if (outmode & kNtEnableProcessedOutput) {
|
||||
tio->c_oflag |= OPOST;
|
||||
}
|
||||
if (!(outmode & kNtDisableNewlineAutoReturn)) {
|
||||
tio->c_oflag |= ONLCR;
|
||||
tio->c_oflag |= OPOST | ONLCR;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return enotty();
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/metatermios.internal.h"
|
||||
#include "libc/calls/termios.internal.h"
|
||||
#include "libc/intrin/describeflags.internal.h"
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/enum/consolemodeflags.h"
|
||||
#include "libc/nt/enum/version.h"
|
||||
|
@ -29,35 +31,54 @@
|
|||
textwindows int ioctl_tcsets_nt(int ignored, uint64_t request,
|
||||
const struct termios *tio) {
|
||||
int64_t in, out;
|
||||
bool32 inok, outok;
|
||||
bool32 ok, inok, outok;
|
||||
uint32_t inmode, outmode;
|
||||
inok = GetConsoleMode((in = __getfdhandleactual(0)), &inmode);
|
||||
outok = GetConsoleMode((out = __getfdhandleactual(1)), &outmode);
|
||||
if (inok | outok) {
|
||||
|
||||
if (inok) {
|
||||
if (request == TCSETSF) {
|
||||
FlushConsoleInputBuffer(in);
|
||||
}
|
||||
inmode &=
|
||||
~(kNtEnableLineInput | kNtEnableEchoInput | kNtEnableProcessedInput);
|
||||
if (tio->c_lflag & ICANON) inmode |= kNtEnableLineInput;
|
||||
if (tio->c_lflag & ECHO) inmode |= kNtEnableEchoInput;
|
||||
if (tio->c_lflag & (IEXTEN | ISIG)) inmode |= kNtEnableProcessedInput;
|
||||
inmode |= kNtEnableWindowInput;
|
||||
if (tio->c_lflag & ICANON) {
|
||||
inmode |= kNtEnableLineInput;
|
||||
}
|
||||
if (tio->c_lflag & ECHO) {
|
||||
/*
|
||||
* kNtEnableEchoInput can be used only if the ENABLE_LINE_INPUT mode
|
||||
* is also enabled. --Quoth MSDN
|
||||
*/
|
||||
inmode |= kNtEnableEchoInput | kNtEnableLineInput;
|
||||
}
|
||||
if (tio->c_lflag & (IEXTEN | ISIG)) {
|
||||
inmode |= kNtEnableProcessedInput;
|
||||
}
|
||||
if (NtGetVersion() >= kNtVersionWindows10) {
|
||||
inmode |= kNtEnableVirtualTerminalInput;
|
||||
}
|
||||
SetConsoleMode(in, inmode);
|
||||
ok = SetConsoleMode(in, inmode);
|
||||
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", in,
|
||||
DescribeNtConsoleModeInputFlags(inmode), ok);
|
||||
}
|
||||
|
||||
if (outok) {
|
||||
outmode |= kNtEnableWrapAtEolOutput;
|
||||
if (tio->c_oflag & OPOST) outmode |= kNtEnableProcessedOutput;
|
||||
if (!(tio->c_oflag & ONLCR)) outmode |= kNtDisableNewlineAutoReturn;
|
||||
outmode &= ~(kNtDisableNewlineAutoReturn);
|
||||
outmode |= kNtEnableProcessedOutput;
|
||||
if (!(tio->c_oflag & ONLCR)) {
|
||||
outmode |= kNtDisableNewlineAutoReturn;
|
||||
}
|
||||
if (NtGetVersion() >= kNtVersionWindows10) {
|
||||
outmode |= kNtEnableVirtualTerminalProcessing;
|
||||
}
|
||||
SetConsoleMode(out, outmode);
|
||||
ok = SetConsoleMode(out, outmode);
|
||||
NTTRACE("SetConsoleMode(%p, %s) → %hhhd", out,
|
||||
DescribeNtConsoleModeOutputFlags(outmode), ok);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
return enotty();
|
||||
|
|
|
@ -83,11 +83,6 @@ int ioctl_tcsets(int fd, uint64_t request, ...) {
|
|||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
if (rc != -1) {
|
||||
if (__nomultics == 0 || __nomultics == 1) {
|
||||
__nomultics = !(tio->c_oflag & OPOST);
|
||||
}
|
||||
}
|
||||
STRACE("ioctl_tcsets(%d, %p, %p) → %d% m", fd, request, tio, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
bool isdirectory_nt(const char *path) {
|
||||
int e;
|
||||
uint32_t x;
|
||||
char16_t path16[PATH_MAX];
|
||||
char16_t path16[PATH_MAX + 1];
|
||||
e = errno;
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
if ((x = GetFileAttributes(path16)) != -1u) {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
bool isregularfile_nt(const char *path) {
|
||||
int e;
|
||||
uint32_t x;
|
||||
char16_t path16[PATH_MAX];
|
||||
char16_t path16[PATH_MAX + 1];
|
||||
e = errno;
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
if ((x = GetFileAttributes(path16)) != -1u) {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
bool issymlink_nt(const char *path) {
|
||||
int e;
|
||||
uint32_t x;
|
||||
char16_t path16[PATH_MAX];
|
||||
char16_t path16[PATH_MAX + 1];
|
||||
e = errno;
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
if ((x = GetFileAttributes(path16)) != -1u) {
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
textwindows int sys_linkat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
||||
const char *newpath) {
|
||||
char16_t newpath16[PATH_MAX];
|
||||
char16_t oldpath16[PATH_MAX];
|
||||
char16_t newpath16[PATH_MAX + 1];
|
||||
char16_t oldpath16[PATH_MAX + 1];
|
||||
if (__mkntpathat(olddirfd, oldpath, 0, oldpath16) != -1 &&
|
||||
__mkntpathat(newdirfd, newpath, 0, newpath16) != -1) {
|
||||
if (CreateHardLink(newpath16, oldpath16, NULL)) {
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
* @param path is a UTF-8 string, preferably relative w/ forward slashes
|
||||
* @param mode can be, for example, 0755
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @error EEXIST, ENOTDIR, ENAMETOOLONG, EACCES
|
||||
* @error ENAMETOOLONG if >246 characters on NT
|
||||
* @asyncsignalsafe
|
||||
* @see makedirs()
|
||||
*/
|
||||
|
|
|
@ -18,10 +18,13 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_mkdirat_nt(int dirfd, const char *path, uint32_t mode) {
|
||||
int e;
|
||||
char16_t *p, path16[PATH_MAX];
|
||||
char16_t *p, path16[PATH_MAX + 1];
|
||||
/* if (strlen(path) > 248) return enametoolong(); */
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
if (CreateDirectory(path16, 0)) return 0;
|
||||
return __fix_enotdir(-1, path16);
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ntmagicpaths.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/systeminfo.h"
|
||||
#include "libc/str/oldutf16.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -49,7 +50,7 @@ textwindows static const char *FixNtMagicPath(const char *path,
|
|||
}
|
||||
|
||||
textwindows int __mkntpath(const char *path,
|
||||
char16_t path16[hasatleast PATH_MAX - 16]) {
|
||||
char16_t path16[hasatleast PATH_MAX + 1]) {
|
||||
return __mkntpath2(path, path16, -1);
|
||||
}
|
||||
|
||||
|
@ -67,14 +68,14 @@ textwindows int __mkntpath(const char *path,
|
|||
* @error ENAMETOOLONG
|
||||
*/
|
||||
textwindows int __mkntpath2(const char *path,
|
||||
char16_t path16[hasatleast PATH_MAX - 16],
|
||||
char16_t path16[hasatleast PATH_MAX + 1],
|
||||
int flags) {
|
||||
/*
|
||||
* 1. Reserve +1 for NUL-terminator
|
||||
* 2. Reserve +1 for UTF-16 overflow
|
||||
* 3. Reserve ≥2 for SetCurrentDirectory trailing slash requirement
|
||||
* 4. Reserve ≥10 for CreateNamedPipe "\\.\pipe\" prefix requirement
|
||||
* 5. Reserve ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
||||
* 1. Need +1 for NUL-terminator
|
||||
* 2. Need +1 for UTF-16 overflow
|
||||
* 3. Need ≥2 for SetCurrentDirectory trailing slash requirement
|
||||
* 5. Need ≥13 for mkdir() i.e. 1+8+3+1, e.g. "\\ffffffff.xxx\0"
|
||||
* which is an "8.3 filename" from the DOS days
|
||||
*/
|
||||
char16_t *p;
|
||||
const char *q;
|
||||
|
@ -83,7 +84,12 @@ textwindows int __mkntpath2(const char *path,
|
|||
path = FixNtMagicPath(path, flags);
|
||||
p = path16;
|
||||
q = path;
|
||||
z = PATH_MAX - 16;
|
||||
if (IsSlash(path[0]) && IsSlash(path[1]) && path[2] == '?' &&
|
||||
IsSlash(path[3])) {
|
||||
z = MIN(32767, PATH_MAX);
|
||||
} else {
|
||||
z = MIN(260, PATH_MAX);
|
||||
}
|
||||
if (IsSlash(q[0]) && q[1] == 't' && q[2] == 'm' && q[3] == 'p' &&
|
||||
(IsSlash(q[4]) || !q[4])) {
|
||||
m = GetTempPath(z, p);
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int __mkntpathat(int dirfd, const char *path, int flags,
|
||||
char16_t file[PATH_MAX]) {
|
||||
char16_t dir[PATH_MAX];
|
||||
char16_t file[hasatleast PATH_MAX + 1]) {
|
||||
uint32_t dirlen, filelen;
|
||||
char16_t dir[PATH_MAX + 1];
|
||||
if ((filelen = __mkntpath2(path, file, flags)) == -1) return -1;
|
||||
if (!filelen) return enoent();
|
||||
if (file[0] != u'\\' && dirfd != AT_FDCWD) { /* ProTip: \\?\C:\foo */
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/sig.internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/nt/nt/time.h"
|
||||
|
@ -34,7 +35,7 @@ textwindows noinstrument int sys_nanosleep_nt(const struct timespec *req,
|
|||
int64_t ms, sec, nsec;
|
||||
if (__builtin_mul_overflow(req->tv_sec, 1000, &ms) ||
|
||||
__builtin_add_overflow(ms, req->tv_nsec / 1000000, &ms)) {
|
||||
ms = -1;
|
||||
ms = INT64_MAX;
|
||||
}
|
||||
if (!ms && (req->tv_sec || req->tv_nsec)) {
|
||||
ms = 1;
|
||||
|
|
|
@ -70,7 +70,7 @@ textwindows int ntspawn(
|
|||
int64_t handle;
|
||||
size_t blocksize;
|
||||
struct SpawnBlock *block;
|
||||
char16_t prog16[PATH_MAX];
|
||||
char16_t prog16[PATH_MAX + 1];
|
||||
rc = -1;
|
||||
block = NULL;
|
||||
if (__mkntpath(prog, prog16) == -1) return -1;
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path,
|
||||
uint32_t flags, int32_t mode) {
|
||||
char16_t path16[PATH_MAX];
|
||||
char16_t path16[PATH_MAX + 1];
|
||||
uint32_t perm, share, disp, attr;
|
||||
if (__mkntpathat(dirfd, path, flags, path16) == -1) return -1;
|
||||
if (GetNtOpenFlags(flags, mode, &perm, &share, &disp, &attr) == -1) return -1;
|
||||
|
|
|
@ -95,7 +95,7 @@ int poll(struct pollfd *fds, size_t nfds, int timeout_ms) {
|
|||
DescribePollFlags(flagbuf[0], sizeof(flagbuf[0]), fds[i].events),
|
||||
DescribePollFlags(flagbuf[1], sizeof(flagbuf[1]), fds[i].revents));
|
||||
}
|
||||
kprintf("%s}, %'zu, %'d) → %d% lm%n", i == 5 ? "..." : "", nfds,
|
||||
kprintf("%s}, %'zu, %'d) → %d% lm\n", i == 5 ? "..." : "", nfds,
|
||||
timeout_ms, rc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ ssize_t preadv(int fd, struct iovec *iov, int iovlen, int64_t off) {
|
|||
} else {
|
||||
kprintf(STRACE_PROLOGUE "preadv(%d, [", fd);
|
||||
__strace_iov(iov, iovlen, rc != -1 ? rc : 0);
|
||||
kprintf("], %d, %'ld) → %'ld% m%n", iovlen, off, rc);
|
||||
kprintf("], %d, %'ld) → %'ld% m\n", iovlen, off, rc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/spinlock.h"
|
||||
|
||||
static const char *__fdkind2str(int x) {
|
||||
switch (x) {
|
||||
|
@ -44,6 +45,7 @@ static const char *__fdkind2str(int x) {
|
|||
|
||||
void __printfds(void) {
|
||||
int i;
|
||||
_spinlock(&__fds_lock);
|
||||
for (i = 0; i < g_fds.n; ++i) {
|
||||
if (!g_fds.p[i].kind) continue;
|
||||
kprintf("%3d %s", i, __fdkind2str(g_fds.p[i].kind));
|
||||
|
@ -53,6 +55,7 @@ void __printfds(void) {
|
|||
if (g_fds.p[i].handle) kprintf(" handle=%ld", g_fds.p[i].handle);
|
||||
if (g_fds.p[i].extra) kprintf(" extra=%ld", g_fds.p[i].extra);
|
||||
if (g_fds.p[i].worker) kprintf(" worker=%p", g_fds.p[i].worker);
|
||||
kprintf("%n", g_fds.p[i].zombie);
|
||||
kprintf("\n");
|
||||
}
|
||||
_spunlock(&__fds_lock);
|
||||
}
|
||||
|
|
|
@ -52,14 +52,21 @@ static textwindows bool GetNtExePath(char exe[SIZE]) {
|
|||
uint64_t w;
|
||||
wint_t x, y;
|
||||
uint32_t i, j;
|
||||
char16_t path16[PATH_MAX + 1];
|
||||
path16[0] = 0;
|
||||
rc = GetModuleFileName(0, path16, ARRAYLEN(path16));
|
||||
NTTRACE("GetModuleFileName(0, [%#hs]) → %hhhd", path16, rc);
|
||||
char16_t p[PATH_MAX + 1];
|
||||
p[0] = 0;
|
||||
rc = GetModuleFileName(0, p, ARRAYLEN(p));
|
||||
NTTRACE("GetModuleFileName(0, [%#hs]) → %hhhd", p, rc);
|
||||
if (!rc) return false;
|
||||
for (i = j = 0; (x = path16[i++] & 0xffff);) {
|
||||
j = 0;
|
||||
if (p[0] != '\\' || p[1] != '\\' || p[2] != '?' || p[3] != '\\') {
|
||||
exe[j++] = '/';
|
||||
exe[j++] = '/';
|
||||
exe[j++] = '?';
|
||||
exe[j++] = '/';
|
||||
}
|
||||
for (i = 0; (x = p[i++] & 0xffff);) {
|
||||
if (!IsUcs2(x)) {
|
||||
y = path16[i++] & 0xffff;
|
||||
y = p[i++] & 0xffff;
|
||||
x = MergeUtf16(x, y);
|
||||
}
|
||||
if (x == '\\') x = '/';
|
||||
|
|
|
@ -123,7 +123,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
|
|||
} else {
|
||||
kprintf(STRACE_PROLOGUE "pwritev(%d, ", fd);
|
||||
__strace_iov(iov, iovlen, rc != -1 ? rc : 0);
|
||||
kprintf(", %d, %'ld) → %'ld% m%n", iovlen, off, rc);
|
||||
kprintf(", %d, %'ld) → %'ld% m\n", iovlen, off, rc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/reparsedatabuffer.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tpenc.h"
|
||||
#include "libc/str/utf16.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -39,7 +40,7 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
|||
wint_t x, y;
|
||||
volatile char *memory;
|
||||
uint32_t i, j, n, mem;
|
||||
char16_t path16[PATH_MAX], *p;
|
||||
char16_t path16[PATH_MAX + 1], *p;
|
||||
struct NtReparseDataBuffer *rdb;
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
mem = 16384;
|
||||
|
@ -56,6 +57,12 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
|||
n = rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(char16_t);
|
||||
p = (char16_t *)((char *)rdb->SymbolicLinkReparseBuffer.PathBuffer +
|
||||
rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
|
||||
if (n >= 3 && isalpha(p[0]) && p[1] == ':' && p[2] == '\\') {
|
||||
buf[j++] = '/';
|
||||
buf[j++] = '/';
|
||||
buf[j++] = '?';
|
||||
buf[j++] = '/';
|
||||
}
|
||||
while (i < n) {
|
||||
x = p[i++] & 0xffff;
|
||||
if (!IsUcs2(x)) {
|
||||
|
|
|
@ -72,7 +72,7 @@ ssize_t readv(int fd, const struct iovec *iov, int iovlen) {
|
|||
} else {
|
||||
kprintf(STRACE_PROLOGUE "readv(%d, [", fd);
|
||||
__strace_iov(iov, iovlen, rc != -1 ? rc : 0);
|
||||
kprintf("], %d) → %'ld% m%n", iovlen, rc);
|
||||
kprintf("], %d) → %'ld% m\n", iovlen, rc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
textwindows int sys_renameat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
||||
const char *newpath) {
|
||||
char16_t oldpath16[PATH_MAX];
|
||||
char16_t newpath16[PATH_MAX];
|
||||
char16_t oldpath16[PATH_MAX + 1];
|
||||
char16_t newpath16[PATH_MAX + 1];
|
||||
if (__mkntpathat(olddirfd, oldpath, 0, oldpath16) == -1 ||
|
||||
__mkntpathat(newdirfd, newpath, 0, newpath16) == -1) {
|
||||
return -1;
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
/**
|
||||
* Sets effective group ID.
|
||||
*/
|
||||
int setegid(unsigned egid) {
|
||||
int rc;
|
||||
rc = setregid(-1, egid);
|
||||
STRACE("%s(%u) → %d% m", "setegid", egid, rc);
|
||||
return rc;
|
||||
int setegid(uint32_t egid) {
|
||||
return setregid(-1, egid);
|
||||
}
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
/**
|
||||
* Sets effective user ID.
|
||||
*/
|
||||
int seteuid(unsigned euid) {
|
||||
int rc;
|
||||
rc = setreuid(-1, euid);
|
||||
STRACE("%s(%u) → %d% m", "seteuid", euid, rc);
|
||||
return rc;
|
||||
int seteuid(uint32_t euid) {
|
||||
return setregid(euid, -1);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,16 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
|
||||
/**
|
||||
* Sets effective group id of current process.
|
||||
* Sets group id of current process.
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int setgid(int gid) {
|
||||
int rc;
|
||||
rc = sys_setgid(gid);
|
||||
STRACE("%s(%d) → %d% m", "setgid", gid);
|
||||
if (IsWindows() && gid == getgid()) {
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = sys_setgid(gid);
|
||||
}
|
||||
STRACE("setgid(%d) → %d% m", gid, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
35
libc/calls/setregid.c
Normal file
35
libc/calls/setregid.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- 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 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
|
||||
/**
|
||||
* Sets real and/or effective group ids.
|
||||
*
|
||||
* @param rgid is real group id or -1 to leave it unchanged
|
||||
* @param egid is effective group id or -1 to leave it unchanged
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int setregid(uint32_t rgid, uint32_t egid) {
|
||||
int rc;
|
||||
rc = sys_setregid(rgid, egid);
|
||||
STRACE("setregid(%d, %d) → %d% m", rgid, egid, rc);
|
||||
return rc;
|
||||
}
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
|
||||
/**
|
||||
* Sets real, effective, and "saved" group ids.
|
||||
|
@ -25,9 +26,17 @@
|
|||
* @param real sets real group id or -1 to do nothing
|
||||
* @param effective sets effective group id or -1 to do nothing
|
||||
* @param saved sets saved group id or -1 to do nothing
|
||||
* @see setregid(), getauxval(AT_SECURE)
|
||||
* @see setresuid(), getauxval(AT_SECURE)
|
||||
* @raise ENOSYS on Windows NT
|
||||
*/
|
||||
int setresgid(uint32_t real, uint32_t effective, uint32_t saved) {
|
||||
if (saved == -1) return setregid(real, effective);
|
||||
return sys_setresgid(real, effective, saved);
|
||||
int rc;
|
||||
if (saved != -1) {
|
||||
rc = sys_setresgid(real, effective, saved);
|
||||
} else {
|
||||
// polyfill xnu and netbsd
|
||||
rc = sys_setregid(real, effective);
|
||||
}
|
||||
STRACE("setresgid(%d, %d, %d) → %d% m", real, effective, saved, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
|
||||
/**
|
||||
* Sets real, effective, and "saved" user ids.
|
||||
|
@ -25,9 +26,17 @@
|
|||
* @param real sets real user id or -1 to do nothing
|
||||
* @param effective sets effective user id or -1 to do nothing
|
||||
* @param saved sets saved user id or -1 to do nothing
|
||||
* @see setreuid(), getauxval(AT_SECURE)
|
||||
* @see setresgid(), getauxval(AT_SECURE)
|
||||
* @raise ENOSYS on Windows NT
|
||||
*/
|
||||
int setresuid(uint32_t real, uint32_t effective, uint32_t saved) {
|
||||
if (saved == -1) return setreuid(real, effective);
|
||||
return sys_setresuid(real, effective, saved);
|
||||
int rc;
|
||||
if (saved != -1) {
|
||||
rc = sys_setresuid(real, effective, saved);
|
||||
} else {
|
||||
// polyfill xnu and netbsd
|
||||
rc = sys_setreuid(real, effective);
|
||||
}
|
||||
STRACE("setresuid(%d, %d, %d) → %d% m", real, effective, saved, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
35
libc/calls/setreuid.c
Normal file
35
libc/calls/setreuid.c
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- 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 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
|
||||
/**
|
||||
* Sets real and/or effective user ids.
|
||||
*
|
||||
* @param ruid is real user id or -1 to leave it unchanged
|
||||
* @param euid is effective user id or -1 to leave it unchanged
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int setreuid(uint32_t ruid, uint32_t euid) {
|
||||
int rc;
|
||||
rc = sys_setreuid(ruid, euid);
|
||||
STRACE("setreuid(%d, %d) → %d% m", ruid, euid, rc);
|
||||
return rc;
|
||||
}
|
|
@ -21,12 +21,16 @@
|
|||
#include "libc/calls/strace.internal.h"
|
||||
|
||||
/**
|
||||
* Sets effective group id of current process.
|
||||
* Sets user id of current process.
|
||||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int setuid(int uid) {
|
||||
int rc;
|
||||
rc = sys_setuid(uid);
|
||||
STRACE("%s(%d) → %d% m", "setuid", uid);
|
||||
if (IsWindows() && uid == getuid()) {
|
||||
rc = 0;
|
||||
} else {
|
||||
rc = sys_setuid(uid);
|
||||
}
|
||||
STRACE("setuid(%d) → %d% m", uid, rc);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ struct Signals {
|
|||
};
|
||||
|
||||
extern struct Signals __sig; // TODO(jart): Need TLS
|
||||
extern long __sig_count;
|
||||
|
||||
bool __sig_check(bool) hidden;
|
||||
bool __sig_handle(bool, int, int, ucontext_t *) hidden;
|
||||
|
|
|
@ -222,6 +222,7 @@ textwindows int __sig_add(int sig, int si_code) {
|
|||
if (1 <= sig && sig <= NSIG) {
|
||||
STRACE("enqueuing %G", sig);
|
||||
_spinlock(&__sig_lock);
|
||||
++__sig_count;
|
||||
if ((mem = __sig_alloc())) {
|
||||
mem->sig = sig;
|
||||
mem->si_code = si_code;
|
||||
|
|
21
libc/calls/sigcount.c
Normal file
21
libc/calls/sigcount.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*-*- 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 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/sig.internal.h"
|
||||
|
||||
long __sig_count;
|
|
@ -5,8 +5,8 @@
|
|||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
|
||||
#define _KERNTRACE 1 /* not configurable w/ flag yet */
|
||||
#define _POLLTRACE 1 /* not configurable w/ flag yet */
|
||||
#define _KERNTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _POLLTRACE 0 /* not configurable w/ flag yet */
|
||||
#define _DATATRACE 1 /* not configurable w/ flag yet */
|
||||
#define _NTTRACE 1 /* not configurable w/ flag yet */
|
||||
|
||||
|
@ -19,7 +19,7 @@ COSMOPOLITAN_C_START_
|
|||
#define STRACE(FMT, ...) \
|
||||
do { \
|
||||
if (__strace > 0) { \
|
||||
__stracef(STRACE_PROLOGUE FMT "%n", ##__VA_ARGS__); \
|
||||
__stracef(STRACE_PROLOGUE FMT "\n", ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
|
|
|
@ -53,8 +53,8 @@ textwindows int sys_symlinkat_nt(const char *target, int newdirfd,
|
|||
const char *linkpath) {
|
||||
int targetlen;
|
||||
uint32_t attrs, flags;
|
||||
char16_t target16[PATH_MAX];
|
||||
char16_t linkpath16[PATH_MAX];
|
||||
char16_t target16[PATH_MAX + 1];
|
||||
char16_t linkpath16[PATH_MAX + 1];
|
||||
|
||||
// convert the paths
|
||||
if (__mkntpathat(newdirfd, linkpath, 0, linkpath16) == -1) return -1;
|
||||
|
|
|
@ -28,7 +28,7 @@ textwindows int sys_truncate_nt(const char *path, uint64_t length) {
|
|||
int rc;
|
||||
bool32 ok;
|
||||
int64_t fh;
|
||||
uint16_t path16[PATH_MAX];
|
||||
uint16_t path16[PATH_MAX + 1];
|
||||
if (__mkntpath(path, path16) == -1) return -1;
|
||||
if ((fh = CreateFile(path16, kNtGenericWrite, kNtFileShareRead, NULL,
|
||||
kNtOpenExisting, kNtFileAttributeNormal, 0)) != -1) {
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/log.h"
|
||||
|
||||
static char ttyname_buf[PATH_MAX];
|
||||
static char ttyname_buf[PATH_MAX + 1];
|
||||
|
||||
/**
|
||||
* Returns name of terminal.
|
||||
|
|
|
@ -63,7 +63,7 @@ static int ttyname_freebsd(int fd, char *buf, size_t size) {
|
|||
static int ttyname_linux(int fd, char *buf, size_t size) {
|
||||
struct stat st1, st2;
|
||||
if (!isatty(fd)) return errno;
|
||||
char name[PATH_MAX];
|
||||
char name[PATH_MAX + 1];
|
||||
FormatInt32(stpcpy(name, "/proc/self/fd/"), fd);
|
||||
ssize_t got;
|
||||
got = readlink(name, buf, size);
|
||||
|
|
|
@ -39,7 +39,8 @@
|
|||
* from failing for no reason at all. For example a unit test that
|
||||
* repeatedly opens and unlinks the same filename.
|
||||
*/
|
||||
static textwindows int SyncDirectory(int df, char16_t path[PATH_MAX], int n) {
|
||||
static textwindows int SyncDirectory(int df, char16_t path[PATH_MAX + 1],
|
||||
int n) {
|
||||
int rc;
|
||||
int64_t fh;
|
||||
char16_t *p;
|
||||
|
@ -128,7 +129,7 @@ static textwindows int sys_unlink_nt(const char16_t *path) {
|
|||
|
||||
textwindows int sys_unlinkat_nt(int dirfd, const char *path, int flags) {
|
||||
int n, rc;
|
||||
char16_t path16[PATH_MAX];
|
||||
char16_t path16[PATH_MAX + 1];
|
||||
if ((n = __mkntpathat(dirfd, path, 0, path16)) == -1) {
|
||||
rc = -1;
|
||||
} else if (flags & AT_REMOVEDIR) {
|
||||
|
|
|
@ -35,7 +35,7 @@ textwindows int sys_utimensat_nt(int dirfd, const char *path,
|
|||
const struct timespec ts[2], int flags) {
|
||||
int i, rc;
|
||||
int64_t fh;
|
||||
uint16_t path16[PATH_MAX];
|
||||
uint16_t path16[PATH_MAX + 1];
|
||||
struct NtFileTime ft[2], *ftp[2];
|
||||
if (__mkntpathat(dirfd, path, 0, path16) == -1) return -1;
|
||||
if ((fh = CreateFile(path16, kNtFileWriteAttributes, kNtFileShareRead, NULL,
|
||||
|
|
|
@ -95,7 +95,11 @@ static textwindows int sys_wait4_nt_impl(int pid, int *opt_out_wstatus,
|
|||
return 0;
|
||||
}
|
||||
} else {
|
||||
i = WaitForMultipleObjects(count, handles, false, -1);
|
||||
i = WaitForMultipleObjects(count, handles, false,
|
||||
__SIG_POLLING_INTERVAL_MS);
|
||||
if (i == kNtWaitTimeout) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (i == kNtWaitFailed) {
|
||||
STRACE("%s failed %u", "WaitForMultipleObjects", GetLastError());
|
||||
|
|
|
@ -79,7 +79,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
|
|||
} else {
|
||||
kprintf(STRACE_PROLOGUE "writev(%d, ", fd);
|
||||
__strace_iov(iov, iovlen, rc != -1 ? rc : 0);
|
||||
kprintf(", %d) → %'ld% m%n", iovlen, rc);
|
||||
kprintf(", %d) → %'ld% m\n", iovlen, rc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue