mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-02 23:18:44 +00:00
Improve ZIP filesystem and change its prefix
The ZIP filesystem has a breaking change. You now need to use /zip/ to open() / opendir() / etc. assets within the ZIP structure of your APE binary, instead of the previous convention of using zip: or zip! URIs. This is needed because Python likes to use absolute paths, and having ZIP paths encoded like URIs simply broke too many things. Many more system calls have been updated to be able to operate on ZIP files and file descriptors. In particular fcntl() and ioctl() since Python would do things like ask if a ZIP file is a terminal and get confused when the old implementation mistakenly said yes, because the fastest way to guarantee native file descriptors is to dup(2). This change also improves the async signal safety of zipos and ensures it doesn't maintain any open file descriptors beyond that which the user has opened. This change makes a lot of progress towards adding magic numbers that are specific to platforms other than Linux. The philosophy here is that, if you use an operating system like FreeBSD, then you should be able to take advantage of FreeBSD exclusive features, even if we don't polyfill them on other platforms. For example, you can now open() a file with the O_VERIFY flag. If your program runs on other platforms, then Cosmo will automatically set O_VERIFY to zero. This lets you safely use it without the need for #ifdef or ifstatements which detract from readability. One of the blindspots of the ASAN memory hardening we use to offer Rust like assurances has always been that memory passed to the kernel via system calls (e.g. writev) can't be checked automatically since the kernel wasn't built with MODE=asan. This change makes more progress ensuring that each system call will verify the soundness of memory before it's passed to the kernel. The code for doing these checks is fast, particularly for buffers, where it can verify 64 bytes a cycle. - Correct O_LOOP definition on NT - Introduce program_executable_name - Add ASAN guards to more system calls - Improve termios compatibility with BSDs - Fix bug in Windows auxiliary value encoding - Add BSD and XNU specific errnos and open flags - Add check to ensure build doesn't talk to internet
This commit is contained in:
parent
2730c66f4a
commit
00611e9b06
319 changed files with 4418 additions and 2599 deletions
|
@ -35,7 +35,7 @@ STATIC_YOINK("ssl_root_support");
|
|||
#define DFL_FILENAME "cert.crt"
|
||||
#define DFL_CA_FILE ""
|
||||
#define DFL_CRL_FILE ""
|
||||
#define DFL_CA_PATH "zip:usr/share/ssl/root"
|
||||
#define DFL_CA_PATH "/zip/usr/share/ssl/root"
|
||||
#define DFL_SERVER_NAME "localhost"
|
||||
#define DFL_SERVER_PORT "4433"
|
||||
#define DFL_DEBUG_LEVEL 0
|
||||
|
|
|
@ -69,12 +69,13 @@ EXAMPLES_DIRECTDEPS = \
|
|||
NET_HTTPS \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_QUICKJS \
|
||||
THIRD_PARTY_GDTOA \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_LINENOISE \
|
||||
THIRD_PARTY_LUA \
|
||||
THIRD_PARTY_MBEDTLS \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_QUICKJS \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_XED \
|
||||
THIRD_PARTY_ZLIB \
|
||||
|
|
|
@ -24,7 +24,7 @@ int main(int argc, char *argv[]) {
|
|||
luaL_openlibs(L);
|
||||
lua_pushcfunction(L, NativeAdd);
|
||||
lua_setglobal(L, "NativeAdd");
|
||||
luaL_dofile(L, "zip:examples/hellolua.lua");
|
||||
luaL_dofile(L, "/zip/examples/hellolua.lua");
|
||||
lua_close(L);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -145,7 +145,7 @@ void SpellChecker(void) {
|
|||
}
|
||||
|
||||
void LoadWords(void) {
|
||||
CHECK_NOTNULL((f = fopen("zip:usr/share/dict/words", "r")));
|
||||
CHECK_NOTNULL((f = fopen("/zip/usr/share/dict/words", "r")));
|
||||
while (getline(&line, &linesize, f) > 0) {
|
||||
critbit0_insert(&words, strtolower(chomp(line)));
|
||||
}
|
||||
|
|
|
@ -1818,7 +1818,7 @@ size_t FindZipGames(void) {
|
|||
!memcmp((ZIP_CFILE_NAME(zipos->map + cf) +
|
||||
ZIP_CFILE_NAMESIZE(zipos->map + cf) - 4),
|
||||
".nes", 4) &&
|
||||
(name = xasprintf("zip:%.*s", ZIP_CFILE_NAMESIZE(zipos->map + cf),
|
||||
(name = xasprintf("/zip/%.*s", ZIP_CFILE_NAMESIZE(zipos->map + cf),
|
||||
ZIP_CFILE_NAME(zipos->map + cf)))) {
|
||||
APPEND(&zipgames_.p, &zipgames_.i, &zipgames_.n, &name);
|
||||
}
|
||||
|
|
98
examples/time.c
Normal file
98
examples/time.c
Normal file
|
@ -0,0 +1,98 @@
|
|||
#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/struct/timespec.h"
|
||||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ex.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* @fileoverview command for showing how long a command takes
|
||||
*
|
||||
* This offers the following improvements over the existing `time`
|
||||
* command that's incorporated into most shells:
|
||||
*
|
||||
* - This will show microseconds if seconds < 1
|
||||
* - This will launch APE binaries on systems with broken libc execv()
|
||||
*/
|
||||
|
||||
#define WRITE(FD, STR) write(FD, STR, strlen(STR))
|
||||
|
||||
void OnChild(void *arg) {
|
||||
char **argv = arg;
|
||||
execv(argv[0], argv);
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
long double GetTimeval(struct timeval t) {
|
||||
return t.tv_sec + t.tv_usec * 1e-6l;
|
||||
}
|
||||
|
||||
void PrintMetric(const char *name, long double d) {
|
||||
char buf[256], *p = buf;
|
||||
long mins, secs, mils, mics;
|
||||
mins = d / 60;
|
||||
secs = fmodl(d, 60);
|
||||
mils = fmodl(d * 1000, 1000);
|
||||
mics = fmodl(d * 1000000, 1000);
|
||||
p = stpcpy(p, name), *p++ = '\t';
|
||||
p += int64toarray_radix10(mins, p), *p++ = 'm';
|
||||
p += int64toarray_radix10(secs, p), *p++ = '.';
|
||||
*p++ = '0' + mils / 100;
|
||||
*p++ = '0' + mils / 10 % 10;
|
||||
*p++ = '0' + mils % 10;
|
||||
if (!secs) {
|
||||
*p++ = '0' + mics / 100;
|
||||
*p++ = '0' + mics / 10 % 10;
|
||||
*p++ = '0' + mics % 10;
|
||||
}
|
||||
*p++ = 's';
|
||||
*p++ = '\n';
|
||||
write(2, buf, p - buf);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int ws;
|
||||
char *exepath;
|
||||
struct rusage r;
|
||||
long double real;
|
||||
char exebuf[PATH_MAX];
|
||||
if (argc >= 2) {
|
||||
if ((exepath = commandv(argv[1], exebuf))) {
|
||||
real = nowl();
|
||||
argv[1] = exepath;
|
||||
if ((ws = xvspawn(OnChild, argv + 1, &r)) != -1) {
|
||||
PrintMetric("real", nowl() - real);
|
||||
PrintMetric("user", GetTimeval(r.ru_utime));
|
||||
PrintMetric("sys", GetTimeval(r.ru_stime));
|
||||
if (WIFEXITED(ws)) {
|
||||
return WEXITSTATUS(ws);
|
||||
} else {
|
||||
return 128 + WTERMSIG(ws);
|
||||
}
|
||||
} else {
|
||||
perror("xvspawn");
|
||||
return 127;
|
||||
}
|
||||
} else {
|
||||
perror(argv[1]);
|
||||
return 127;
|
||||
}
|
||||
} else {
|
||||
WRITE(2, "Usage: ");
|
||||
WRITE(2, argv[0]);
|
||||
WRITE(2, " PROG [ARGS...]\n");
|
||||
return EX_USAGE;
|
||||
}
|
||||
}
|
|
@ -111,6 +111,8 @@
|
|||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sigbits.h"
|
||||
#include "libc/calls/struct/dirent.h"
|
||||
|
@ -125,6 +127,7 @@
|
|||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/paths.h"
|
||||
|
@ -132,6 +135,7 @@
|
|||
#include "libc/runtime/sysconf.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
#include "libc/sysv/consts/f.h"
|
||||
#include "libc/sysv/consts/fd.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
|
@ -141,6 +145,7 @@
|
|||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/w.h"
|
||||
#include "third_party/gdtoa/gdtoa.h"
|
||||
#include "third_party/linenoise/linenoise.h"
|
||||
#include "third_party/musl/passwd.h"
|
||||
|
||||
#define likely(expr) __builtin_expect(!!(expr), 1)
|
||||
|
@ -1030,6 +1035,7 @@ struct t_op {
|
|||
│ cosmopolitan § the unbourne shell » bss ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
static int inter;
|
||||
static char **argptr; /* argument list for builtin commands */
|
||||
static char **gargv;
|
||||
static char **t_wp;
|
||||
|
@ -1827,7 +1833,7 @@ printfesque(3) static int fmtstr(char *outbuf, unsigned length, const char *fmt,
|
|||
return ret > (int)length ? length : ret;
|
||||
}
|
||||
|
||||
printfesque(2) static int xasprintf(char **sp, const char *fmt, ...) {
|
||||
printfesque(2) static int Xasprintf(char **sp, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
int ret;
|
||||
va_start(ap, fmt);
|
||||
|
@ -5629,12 +5635,129 @@ static int pgetc2() {
|
|||
return c;
|
||||
}
|
||||
|
||||
static void AddUniqueCompletion(linenoiseCompletions *c, char *s) {
|
||||
size_t i;
|
||||
if (!s) return;
|
||||
for (i = 0; i < c->len; ++i) {
|
||||
if (!strcmp(s, c->cvec[i])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
c->cvec = realloc(c->cvec, ++c->len * sizeof(*c->cvec));
|
||||
c->cvec[c->len - 1] = s;
|
||||
}
|
||||
|
||||
static void CompleteCommand(const char *p, const char *q, const char *b, linenoiseCompletions *c) {
|
||||
DIR *d;
|
||||
size_t i;
|
||||
struct dirent *e;
|
||||
const char *x, *y, *path;
|
||||
struct tblentry **pp, *cmdp;
|
||||
for (pp = cmdtable; pp < &cmdtable[CMDTABLESIZE]; pp++) {
|
||||
for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
|
||||
if (cmdp->cmdtype >= 0 && !strncmp(cmdp->cmdname, p, q - p)) {
|
||||
AddUniqueCompletion(c, strdup(cmdp->cmdname));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAYLEN(kBuiltinCmds); ++i) {
|
||||
if (!strncmp(kBuiltinCmds[i].name, p, q - p)) {
|
||||
AddUniqueCompletion(c, strdup(kBuiltinCmds[i].name));
|
||||
}
|
||||
}
|
||||
for (y = x = lookupvar("PATH"); *y; x = y + 1) {
|
||||
if ((path = strndup(x, (y = strchrnul(x, ':')) - x))) {
|
||||
if ((d = opendir(path))) {
|
||||
while ((e = readdir(d))) {
|
||||
if (e->d_type == DT_REG && !strncmp(e->d_name, p, q - p)) {
|
||||
AddUniqueCompletion(c, strdup(e->d_name));
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
free(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void CompleteFilename(const char *p, const char *q, const char *b, linenoiseCompletions *c) {
|
||||
DIR *d;
|
||||
char *buf;
|
||||
const char *g;
|
||||
struct dirent *e;
|
||||
if ((buf = malloc(512))) {
|
||||
if ((g = memrchr(p, '/', q - p))) {
|
||||
*(char *)mempcpy(buf, p, MIN(g - p, 511)) = 0;
|
||||
p = ++g;
|
||||
} else {
|
||||
strcpy(buf, ".");
|
||||
}
|
||||
if ((d = opendir(buf))) {
|
||||
while ((e = readdir(d))) {
|
||||
if (!strcmp(e->d_name, ".")) continue;
|
||||
if (!strcmp(e->d_name, "..")) continue;
|
||||
if (!strncmp(e->d_name, p, q - p)) {
|
||||
snprintf(buf, 512, "%.*s%s%s", p - b, b, e->d_name, e->d_type == DT_DIR ? "/" : "");
|
||||
AddUniqueCompletion(c, strdup(buf));
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void ShellCompletion(const char *p, linenoiseCompletions *c) {
|
||||
bool slashed;
|
||||
const char *q, *b;
|
||||
struct tblentry **pp, *cmdp;
|
||||
for (slashed = false, b = p, q = (p += strlen(p)); p > b; --p) {
|
||||
if (p[-1] == '/' && p[-1] == '\\') slashed = true;
|
||||
if (!isalnum(p[-1]) && (p[-1] != '.' && p[-1] != '_' && p[-1] != '-' && p[-1] != '+' &&
|
||||
p[-1] != '[' && p[-1] != '/' && p[-1] != '\\')) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (b == p && !slashed) {
|
||||
CompleteCommand(p, q, b, c);
|
||||
} else {
|
||||
CompleteFilename(p, q, b, c);
|
||||
}
|
||||
}
|
||||
|
||||
static char *ShellHint(const char *p, int *color, int *bold) {
|
||||
char *h = 0;
|
||||
linenoiseCompletions c = {0};
|
||||
ShellCompletion(p, &c);
|
||||
if (c.len == 1) {
|
||||
h = strdup(c.cvec[0] + strlen(p));
|
||||
*bold = 2;
|
||||
}
|
||||
linenoiseFreeCompletions(&c);
|
||||
return h;
|
||||
}
|
||||
|
||||
static ssize_t preadfd(void) {
|
||||
ssize_t nr;
|
||||
char *buf = parsefile->buf;
|
||||
char *p, *buf = parsefile->buf;
|
||||
parsefile->nextc = buf;
|
||||
retry:
|
||||
nr = read(parsefile->fd, buf, IBUFSIZ - 1);
|
||||
if (!parsefile->fd && isatty(0)) {
|
||||
linenoiseSetFreeHintsCallback(free);
|
||||
linenoiseSetHintsCallback(ShellHint);
|
||||
linenoiseSetCompletionCallback(ShellCompletion);
|
||||
if ((p = ezlinenoise(getprompt(NULL), "unbourne"))) {
|
||||
nr = min(strlen(p), IBUFSIZ - 2);
|
||||
memcpy(buf, p, nr);
|
||||
buf[nr++] = '\n';
|
||||
free(p);
|
||||
} else {
|
||||
write(1, "\n", 1);
|
||||
nr = 0;
|
||||
}
|
||||
} else {
|
||||
nr = read(parsefile->fd, buf, IBUFSIZ - 1);
|
||||
}
|
||||
if (nr < 0) {
|
||||
if (errno == EINTR) goto retry;
|
||||
if (parsefile->fd == 0 && errno == EAGAIN) {
|
||||
|
@ -7036,12 +7159,12 @@ static int readcmd(int argc, char **argv) {
|
|||
if (prompt && isatty(0)) {
|
||||
outstr(prompt, out2);
|
||||
}
|
||||
if (*(ap = argptr) == NULL) sh_error("arg count");
|
||||
if (!*(ap = argptr)) sh_error("arg count");
|
||||
status = 0;
|
||||
STARTSTACKSTR(p);
|
||||
goto start;
|
||||
for (;;) {
|
||||
switch (read(STDIN_FILENO, &c, 1)) {
|
||||
switch (read(0, &c, 1)) {
|
||||
case 1:
|
||||
break;
|
||||
default:
|
||||
|
@ -7051,7 +7174,7 @@ static int readcmd(int argc, char **argv) {
|
|||
status = 1;
|
||||
goto out;
|
||||
}
|
||||
if (c == '\0') continue;
|
||||
if (!c) continue;
|
||||
if (newloc >= startloc) {
|
||||
if (c == '\n') goto resetbs;
|
||||
goto put;
|
||||
|
@ -8820,7 +8943,7 @@ static void setprompt(int which) {
|
|||
int show;
|
||||
needprompt = 0;
|
||||
whichprompt = which;
|
||||
show = 1;
|
||||
show = 0;
|
||||
if (show) {
|
||||
pushstackmark(&smark, stackblocksize());
|
||||
outstr(getprompt(NULL), out2);
|
||||
|
@ -9377,13 +9500,13 @@ static void sigblockall(sigset_t *oldmask) {
|
|||
int ret; \
|
||||
switch ((char *)param - (char *)array) { \
|
||||
default: \
|
||||
ret = xasprintf(sp, f, array[0], array[1], func); \
|
||||
ret = Xasprintf(sp, f, array[0], array[1], func); \
|
||||
break; \
|
||||
case sizeof(*param): \
|
||||
ret = xasprintf(sp, f, array[0], func); \
|
||||
ret = Xasprintf(sp, f, array[0], func); \
|
||||
break; \
|
||||
case 0: \
|
||||
ret = xasprintf(sp, f, func); \
|
||||
ret = Xasprintf(sp, f, func); \
|
||||
break; \
|
||||
} \
|
||||
ret; \
|
||||
|
@ -10788,8 +10911,6 @@ static int exitcmd(int argc, char **argv) {
|
|||
* is used to figure out how far we had gotten.
|
||||
*/
|
||||
int main(int argc, char **argv) {
|
||||
showcrashreports();
|
||||
unsetenv("PS1");
|
||||
char *shinit;
|
||||
volatile int state;
|
||||
struct jmploc jmploc;
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#define WIFSTOPPED(s) ((short)((((s)&0xffff) * 0x10001) >> 8) > 0x7f00)
|
||||
#define WSTOPSIG(s) WEXITSTATUS(s)
|
||||
#define WTERMSIG(s) ((s)&0x7f)
|
||||
#define W_STOPCODE(s) ((s) << 8 | 0177)
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
@ -88,34 +89,35 @@ int chown(const char *, uint32_t, uint32_t);
|
|||
int chroot(const char *);
|
||||
int close(int);
|
||||
int closedir(DIR *);
|
||||
int creat(const char *, uint32_t) nodiscard;
|
||||
int creat(const char *, uint32_t);
|
||||
int dirfd(DIR *);
|
||||
int dup(int) nodiscard;
|
||||
int dup(int);
|
||||
int dup2(int, int);
|
||||
int dup3(int, int, int);
|
||||
int execl(const char *, const char *, ...) nullterminated();
|
||||
int execle(const char *, const char *, ...) nullterminated((1));
|
||||
int execlp(const char *, const char *, ...) nullterminated();
|
||||
int execv(const char *, char *const[]) paramsnonnull();
|
||||
int execve(const char *, char *const[], char *const[]) paramsnonnull();
|
||||
int execvp(const char *, char *const[]) paramsnonnull();
|
||||
int execvpe(const char *, char *const[], char *const[]) paramsnonnull();
|
||||
int execv(const char *, char *const[]);
|
||||
int execve(const char *, char *const[], char *const[]);
|
||||
int execvp(const char *, char *const[]);
|
||||
int execvpe(const char *, char *const[], char *const[]);
|
||||
int faccessat(int, const char *, int, uint32_t);
|
||||
int fadvise(int, uint64_t, uint64_t, int);
|
||||
int fchdir(int);
|
||||
int fchmod(int, uint32_t) nothrow;
|
||||
int fchmodat(int, const char *, uint32_t, uint32_t);
|
||||
int fchmodat(int, const char *, uint32_t, int);
|
||||
int fchown(int, uint32_t, uint32_t);
|
||||
int fchownat(int, const char *, uint32_t, uint32_t, uint32_t);
|
||||
int fchownat(int, const char *, uint32_t, uint32_t, int);
|
||||
int fcntl(int, int, ...);
|
||||
int fdatasync(int);
|
||||
int filecmp(const char *, const char *);
|
||||
int flock(int, int);
|
||||
int fork(void);
|
||||
int fstat(int, struct stat *);
|
||||
int fstatat(int, const char *, struct stat *, uint32_t);
|
||||
int fstatat(int, const char *, struct stat *, int);
|
||||
int fsync(int);
|
||||
int ftruncate(int, int64_t);
|
||||
int getdents(unsigned, void *, unsigned, long *);
|
||||
int getdomainname(char *, size_t);
|
||||
int gethostname(char *, size_t);
|
||||
int getpgid(int);
|
||||
|
@ -127,7 +129,7 @@ int getrusage(int, struct rusage *);
|
|||
int kill(int, int);
|
||||
int killpg(int, int);
|
||||
int link(const char *, const char *) nothrow;
|
||||
int linkat(int, const char *, int, const char *, uint32_t);
|
||||
int linkat(int, const char *, int, const char *, int);
|
||||
int lstat(const char *, struct stat *);
|
||||
int lutimes(const char *, const struct timeval[2]);
|
||||
int madvise(void *, uint64_t, int);
|
||||
|
@ -244,10 +246,6 @@ int vdprintf(int, const char *, va_list) paramsnonnull();
|
|||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
|
||||
#define getcwd(BUF, SIZE) \
|
||||
(__builtin_constant_p(BUF) && !(BUF) ? get_current_dir_name() \
|
||||
: getcwd(BUF, SIZE))
|
||||
|
||||
void _init_onntconsoleevent(void);
|
||||
void _init_wincrash(void);
|
||||
|
||||
|
|
|
@ -75,6 +75,25 @@ o/$(MODE)/libc/calls/ntcontext2linux.o: \
|
|||
OVERRIDE_COPTS += \
|
||||
-O3
|
||||
|
||||
# TODO(jart): make va_arg optimize well in default mode
|
||||
o//libc/calls/ioctl.o \
|
||||
o//libc/calls/ioctl_default.o \
|
||||
o//libc/calls/ioctl_fioclex-nt.o \
|
||||
o//libc/calls/ioctl_fioclex.o \
|
||||
o//libc/calls/ioctl_siocgifconf-nt.o \
|
||||
o//libc/calls/ioctl_siocgifconf.o \
|
||||
o//libc/calls/ioctl_tcgets-nt.o \
|
||||
o//libc/calls/ioctl_tcgets.o \
|
||||
o//libc/calls/ioctl_tcsets-nt.o \
|
||||
o//libc/calls/ioctl_tcsets.o \
|
||||
o//libc/calls/ioctl_tiocgwinsz-nt.o \
|
||||
o//libc/calls/ioctl_tiocgwinsz.o \
|
||||
o//libc/calls/ioctl_tiocswinsz-nt.o \
|
||||
o//libc/calls/ioctl_tiocswinsz.o \
|
||||
o//libc/calls/fcntl.o: \
|
||||
OVERRIDE_CFLAGS += \
|
||||
-Os
|
||||
|
||||
o/$(MODE)/libc/calls/execl.o \
|
||||
o/$(MODE)/libc/calls/execle.o \
|
||||
o/$(MODE)/libc/calls/execlp.o \
|
||||
|
|
|
@ -18,14 +18,19 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Sets current directory.
|
||||
*
|
||||
* This does *not* update the `PWD` environment variable.
|
||||
*
|
||||
* @asyncsignalsafe
|
||||
* @see fchdir()
|
||||
*/
|
||||
int chdir(const char *path) {
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (!IsWindows()) {
|
||||
return sys_chdir(path);
|
||||
} else {
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
|
@ -42,5 +41,5 @@
|
|||
* @see fchmod()
|
||||
*/
|
||||
int chmod(const char *pathname, uint32_t mode) {
|
||||
return sys_fchmodat(AT_FDCWD, pathname, mode, 0);
|
||||
return fchmodat(AT_FDCWD, pathname, mode, 0);
|
||||
}
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
/**
|
||||
|
@ -33,5 +32,5 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int chown(const char *pathname, uint32_t uid, uint32_t gid) {
|
||||
return sys_fchownat(AT_FDCWD, pathname, uid, gid, 0);
|
||||
return fchownat(AT_FDCWD, pathname, uid, gid, 0);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -42,6 +44,7 @@ int clock_gettime(int clockid, struct timespec *ts) {
|
|||
axdx_t ad;
|
||||
struct NtFileTime ft;
|
||||
if (!ts) return efault();
|
||||
if (IsAsan() && !__asan_is_valid(ts, sizeof(*ts))) return efault();
|
||||
if (clockid == -1) return einval();
|
||||
if (!IsWindows()) {
|
||||
if ((rc = sys_clock_gettime(clockid, ts)) == -1 && errno == ENOSYS) {
|
||||
|
|
|
@ -33,7 +33,7 @@ textwindows int sys_close_nt(struct Fd *fd) {
|
|||
FlushFileBuffers(fd->handle);
|
||||
}
|
||||
ok = CloseHandle(fd->handle);
|
||||
if (fd->kind == kFdConsole) {
|
||||
if (fd->kind == kFdConsole && fd->extra && fd->extra != -1) {
|
||||
ok &= CloseHandle(fd->extra);
|
||||
}
|
||||
return ok ? 0 : __winerr();
|
||||
|
|
|
@ -74,6 +74,10 @@ char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
|
|||
char *p;
|
||||
size_t namelen;
|
||||
int rc, olderr;
|
||||
if (!name) {
|
||||
efault();
|
||||
return NULL;
|
||||
}
|
||||
if (!(namelen = strlen(name))) {
|
||||
enoent();
|
||||
return NULL;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Executes program, with PATH search and current environment.
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "libc/sysv/consts/o.h"
|
||||
|
||||
textwindows int sys_execve_nt(const char *program, char *const argv[],
|
||||
char *const envp[]) {
|
||||
char *const envp[]) {
|
||||
int rc;
|
||||
size_t i;
|
||||
uint32_t dwExitCode;
|
||||
|
@ -42,13 +42,7 @@ textwindows int sys_execve_nt(const char *program, char *const argv[],
|
|||
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);
|
||||
}
|
||||
}
|
||||
rc = ntspawn(program, argv, envp, NULL, NULL, NULL, true, 0, NULL, &startinfo,
|
||||
&procinfo);
|
||||
rc = ntspawn(program, argv, envp, 0, 0, 0, 1, 0, 0, &startinfo, &procinfo);
|
||||
if (rc == -1) return -1;
|
||||
CloseHandle(procinfo.hThread);
|
||||
do {
|
||||
|
|
|
@ -19,6 +19,17 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
static noasan bool __asan_is_valid_strlist(char *const *p) {
|
||||
for (;; ++p) {
|
||||
if (!__asan_is_valid(p, sizeof(char *))) return false;
|
||||
if (!*p) return true;
|
||||
if (!__asan_is_valid(*p, 1)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces current process with program.
|
||||
|
@ -34,6 +45,18 @@
|
|||
* @vforksafe
|
||||
*/
|
||||
int execve(const char *program, char *const argv[], char *const envp[]) {
|
||||
size_t i;
|
||||
if (!program || !argv || !envp) return efault();
|
||||
if (IsAsan() &&
|
||||
(!__asan_is_valid(program, 1) || !__asan_is_valid_strlist(argv) ||
|
||||
!__asan_is_valid_strlist(envp))) {
|
||||
return efault();
|
||||
}
|
||||
for (i = 3; i < g_fds.n; ++i) {
|
||||
if (g_fds.p[i].kind != kFdEmpty && (g_fds.p[i].flags & O_CLOEXEC)) {
|
||||
close(i);
|
||||
}
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_execve(program, argv, envp);
|
||||
} else {
|
||||
|
|
|
@ -17,7 +17,10 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Executes program, with path environment search.
|
||||
|
@ -34,6 +37,7 @@
|
|||
int execvpe(const char *prog, char *const argv[], char *const *envp) {
|
||||
char *exe;
|
||||
char pathbuf[PATH_MAX];
|
||||
if (IsAsan() && !__asan_is_valid(prog, 1)) return efault();
|
||||
if (!(exe = commandv(prog, pathbuf))) return -1;
|
||||
return execve(exe, argv, envp);
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ 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/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
|
|
@ -16,11 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Checks if effective user can access path in particular ways.
|
||||
|
@ -34,6 +37,10 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int faccessat(int dirfd, const char *path, int mode, uint32_t flags) {
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_faccessat(dirfd, path, mode, flags);
|
||||
} else {
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
/**
|
||||
* Sets current directory based on file descriptor.
|
||||
*
|
||||
* This does *not* update the `PWD` environment variable.
|
||||
*
|
||||
* @see open(path, O_DIRECTORY)
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
|
|
|
@ -22,22 +22,9 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Changes file permissions via open()'d file descriptor, e.g.:
|
||||
*
|
||||
* CHECK_NE(-1, chmod("foo/bar.txt", 0644));
|
||||
* CHECK_NE(-1, chmod("o/default/program.com", 0755));
|
||||
* CHECK_NE(-1, chmod("privatefolder/", 0700));
|
||||
*
|
||||
* The esoteric bits generally available on System V are:
|
||||
*
|
||||
* CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit
|
||||
* CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit
|
||||
* CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit
|
||||
*
|
||||
* This works on Windows NT if you ignore the error ;-)
|
||||
* Changes file permissions via open()'d file descriptor.
|
||||
*
|
||||
* @param mode contains octal flags (base 8)
|
||||
* @errors ENOSYS
|
||||
* @asyncsignalsafe
|
||||
* @see chmod()
|
||||
*/
|
||||
|
|
49
libc/calls/fchmodat.c
Normal file
49
libc/calls/fchmodat.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- 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 2021 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/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Changes permissions on file, e.g.:
|
||||
*
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "foo/bar.txt", 0644));
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "o/default/program.com", 0755));
|
||||
* CHECK_NE(-1, fchmodat(AT_FDCWD, "privatefolder/", 0700));
|
||||
*
|
||||
* This works on Windows NT if you ignore the error ;-)
|
||||
*
|
||||
* @param path must exist
|
||||
* @param mode contains octal flags (base 8)
|
||||
* @param flags can have `AT_SYMLINK_NOFOLLOW`
|
||||
* @errors ENOENT, ENOTDIR, ENOSYS
|
||||
* @asyncsignalsafe
|
||||
* @see fchmod()
|
||||
*/
|
||||
int fchmodat(int dirfd, const char *path, uint32_t mode, int flags) {
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
return sys_fchmodat(dirfd, path, mode, flags);
|
||||
}
|
|
@ -16,11 +16,16 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Changes owner and/or group of pathname.
|
||||
* Changes owner and/or group of path.
|
||||
*
|
||||
* @param dirfd is open()'d relative-to directory, or AT_FDCWD, etc.
|
||||
* @param uid is user id, or -1 to not change
|
||||
|
@ -32,7 +37,11 @@
|
|||
* @see /etc/group for group ids
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fchownat(int dirfd, const char *pathname, uint32_t uid, uint32_t gid,
|
||||
uint32_t flags) {
|
||||
return sys_fchownat(dirfd, pathname, uid, gid, flags);
|
||||
int fchownat(int dirfd, const char *path, uint32_t uid, uint32_t gid,
|
||||
int flags) {
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
return sys_fchownat(dirfd, path, uid, gid, flags);
|
||||
}
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Does things with file descriptor, via re-imagined hourglass api, e.g.
|
||||
|
@ -45,9 +48,15 @@ int fcntl(int fd, int cmd, ...) {
|
|||
va_start(va, cmd);
|
||||
arg = va_arg(va, uintptr_t);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return sys_fcntl(fd, cmd, arg);
|
||||
if (fd >= 0) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return weaken(__zipos_fcntl)(fd, cmd, arg);
|
||||
} else if (!IsWindows()) {
|
||||
return sys_fcntl(fd, cmd, arg);
|
||||
} else {
|
||||
return sys_fcntl_nt(fd, cmd, arg);
|
||||
}
|
||||
} else {
|
||||
return sys_fcntl_nt(fd, cmd, arg);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
@ -37,6 +38,7 @@ bool fileexists(const char *path) {
|
|||
int rc, olderr;
|
||||
struct stat st;
|
||||
uint16_t path16[PATH_MAX];
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (!IsWindows()) {
|
||||
olderr = errno;
|
||||
rc = __sys_fstatat(AT_FDCWD, path, &st, 0);
|
||||
|
|
|
@ -17,24 +17,69 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/fileinfobyhandleclass.h"
|
||||
#include "libc/nt/enum/filetype.h"
|
||||
#include "libc/nt/enum/fsctl.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/byhandlefileinformation.h"
|
||||
#include "libc/nt/struct/filecompressioninfo.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/consts/s.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#if 0
|
||||
#define DEBUG(FMT, ...) (dprintf)(2, FMT "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG(FMT, ...) (void)0
|
||||
#endif
|
||||
|
||||
static textwindows uint32_t GetSizeOfReparsePoint(int64_t fh) {
|
||||
wint_t x, y;
|
||||
const char16_t *p;
|
||||
uint32_t mem, i, n, z = 0;
|
||||
struct NtReparseDataBuffer *rdb;
|
||||
long buf[(sizeof(*rdb) + PATH_MAX * sizeof(char16_t)) / sizeof(long)];
|
||||
mem = sizeof(buf);
|
||||
rdb = (struct NtReparseDataBuffer *)buf;
|
||||
if (DeviceIoControl(fh, kNtFsctlGetReparsePoint, 0, 0, rdb, mem, &n, 0)) {
|
||||
i = 0;
|
||||
n = rdb->SymbolicLinkReparseBuffer.PrintNameLength / sizeof(char16_t);
|
||||
p = (char16_t *)((char *)rdb->SymbolicLinkReparseBuffer.PathBuffer +
|
||||
rdb->SymbolicLinkReparseBuffer.PrintNameOffset);
|
||||
while (i < n) {
|
||||
x = p[i++] & 0xffff;
|
||||
if (!IsUcs2(x)) {
|
||||
if (i < n) {
|
||||
y = p[i++] & 0xffff;
|
||||
x = MergeUtf16(x, y);
|
||||
} else {
|
||||
x = 0xfffd;
|
||||
}
|
||||
}
|
||||
z += x < 0200 ? 1 : bsrl(tpenc(x)) >> 3;
|
||||
}
|
||||
} else {
|
||||
DEBUG("GetSizeOfReparsePoint failed %d", GetLastError());
|
||||
}
|
||||
return z;
|
||||
}
|
||||
|
||||
textwindows int sys_fstat_nt(int64_t handle, struct stat *st) {
|
||||
int filetype;
|
||||
uint64_t actualsize;
|
||||
struct NtFileCompressionInfo fci;
|
||||
struct NtByHandleFileInformation wst;
|
||||
if (!st) return efault();
|
||||
if ((filetype = GetFileType(handle))) {
|
||||
memset(st, 0, sizeof(*st));
|
||||
switch (filetype) {
|
||||
|
@ -52,7 +97,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) {
|
|||
}
|
||||
if (wst.dwFileAttributes & kNtFileAttributeDirectory) {
|
||||
st->st_mode |= S_IFDIR;
|
||||
} else if (wst.dwFileAttributes & kNtFileFlagOpenReparsePoint) {
|
||||
} else if (wst.dwFileAttributes & kNtFileAttributeReparsePoint) {
|
||||
st->st_mode |= S_IFLNK;
|
||||
} else {
|
||||
st->st_mode |= S_IFREG;
|
||||
|
@ -66,13 +111,19 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) {
|
|||
st->st_rdev = wst.dwVolumeSerialNumber;
|
||||
st->st_ino = (uint64_t)wst.nFileIndexHigh << 32 | wst.nFileIndexLow;
|
||||
st->st_nlink = wst.nNumberOfLinks;
|
||||
if (GetFileInformationByHandleEx(handle, kNtFileCompressionInfo, &fci,
|
||||
sizeof(fci))) {
|
||||
actualsize = fci.CompressedFileSize;
|
||||
if (S_ISLNK(st->st_mode)) {
|
||||
if (!st->st_size) {
|
||||
st->st_size = GetSizeOfReparsePoint(handle);
|
||||
}
|
||||
} else {
|
||||
actualsize = st->st_size;
|
||||
if (S_ISREG(st->st_mode) &&
|
||||
GetFileInformationByHandleEx(handle, kNtFileCompressionInfo,
|
||||
&fci, sizeof(fci))) {
|
||||
actualsize = fci.CompressedFileSize;
|
||||
}
|
||||
st->st_blocks = roundup(actualsize, PAGESIZE) / 512;
|
||||
}
|
||||
st->st_blocks = roundup(actualsize, PAGESIZE) / 512;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int fstat(int fd, struct stat *st) {
|
||||
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
|
||||
if (IsAsan() && !__asan_is_valid(st, sizeof(*st))) return efault();
|
||||
if (__isfdkind(fd, kFdZip)) {
|
||||
return weaken(__zipos_fstat)(
|
||||
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st);
|
||||
|
|
|
@ -22,12 +22,11 @@
|
|||
#include "libc/nt/enum/creationdisposition.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/filesharemode.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
|
||||
textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
||||
uint32_t flags) {
|
||||
int flags) {
|
||||
int rc;
|
||||
int64_t fh;
|
||||
uint16_t path16[PATH_MAX];
|
||||
|
@ -35,9 +34,12 @@ textwindows int sys_fstatat_nt(int dirfd, const char *path, struct stat *st,
|
|||
if ((fh = CreateFile(
|
||||
path16, kNtFileReadAttributes,
|
||||
kNtFileShareRead | kNtFileShareWrite | kNtFileShareDelete, NULL,
|
||||
kNtOpenExisting, kNtFileAttributeNormal | kNtFileFlagBackupSemantics,
|
||||
kNtOpenExisting,
|
||||
kNtFileAttributeNormal | kNtFileFlagBackupSemantics |
|
||||
((flags & AT_SYMLINK_NOFOLLOW) ? kNtFileFlagOpenReparsePoint
|
||||
: 0),
|
||||
0)) != -1) {
|
||||
rc = sys_fstat_nt(fh, st);
|
||||
rc = st ? sys_fstat_nt(fh, st) : 0;
|
||||
CloseHandle(fh);
|
||||
return rc;
|
||||
} else {
|
||||
|
|
|
@ -19,8 +19,11 @@
|
|||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
@ -36,9 +39,13 @@
|
|||
* @see S_ISDIR(st.st_mode), S_ISREG()
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int fstatat(int dirfd, const char *path, struct stat *st, uint32_t flags) {
|
||||
int fstatat(int dirfd, const char *path, struct stat *st, int flags) {
|
||||
struct ZiposUri zipname;
|
||||
if (IsAsan() && (!st || !__asan_is_valid(st, sizeof(*st)))) return efault();
|
||||
if (IsAsan() && (!__asan_is_valid(path, 1) ||
|
||||
(st && !__asan_is_valid(st, sizeof(*st))))) {
|
||||
return efault();
|
||||
}
|
||||
if (__isfdkind(dirfd, kFdZip)) return einval(); /* TODO(jart): implement me */
|
||||
if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||
return weaken(__zipos_stat)(&zipname, st);
|
||||
} else if (!IsWindows()) {
|
||||
|
|
|
@ -16,32 +16,70 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns current working directory.
|
||||
* Returns current working directory, e.g.
|
||||
*
|
||||
* const char *dirname = gc(getcwd(0,0)); // if malloc is linked
|
||||
* const char *dirname = getcwd(alloca(PATH_MAX),PATH_MAX);
|
||||
*
|
||||
* @param buf is where UTF-8 NUL-terminated path string gets written,
|
||||
* which may be NULL to ask this function to malloc a buffer
|
||||
* @param size is number of bytes available in buf, e.g. PATH_MAX,
|
||||
* which may be 0 if buf NULL
|
||||
* @return buf containing system-normative path or NULL w/ errno
|
||||
* @see get_current_dir_name() which is better
|
||||
* @error ERANGE, EINVAL
|
||||
* @error ERANGE, EINVAL, ENOMEM
|
||||
*/
|
||||
char *(getcwd)(char *buf, size_t size) {
|
||||
if (buf && size) buf[0] = '\0';
|
||||
if (!IsWindows()) {
|
||||
if (IsXnu()) {
|
||||
return sys_getcwd_xnu(buf, size);
|
||||
} else if (sys_getcwd(buf, size) != (void *)-1) {
|
||||
return buf;
|
||||
} else {
|
||||
return NULL;
|
||||
char *getcwd(char *buf, size_t size) {
|
||||
char *p, *r;
|
||||
if (buf) {
|
||||
p = buf;
|
||||
if (!size) {
|
||||
einval();
|
||||
return 0;
|
||||
}
|
||||
} else if (weaken(malloc)) {
|
||||
if (!size) size = PATH_MAX + 1;
|
||||
if (!(p = weaken(malloc)(size))) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return sys_getcwd_nt(buf, size);
|
||||
einval();
|
||||
return 0;
|
||||
}
|
||||
*p = '\0';
|
||||
if (!IsWindows()) {
|
||||
if (IsMetal()) {
|
||||
r = size >= 5 ? strcpy(p, "/zip") : 0;
|
||||
} else if (IsXnu()) {
|
||||
r = sys_getcwd_xnu(p, size);
|
||||
} else if (sys_getcwd(p, size) != (void *)-1) {
|
||||
r = p;
|
||||
} else {
|
||||
r = 0;
|
||||
}
|
||||
} else {
|
||||
r = sys_getcwd_nt(p, size);
|
||||
}
|
||||
if (!buf) {
|
||||
if (!r) {
|
||||
if (weaken(free)) {
|
||||
weaken(free)(p);
|
||||
}
|
||||
} else {
|
||||
if (weaken(realloc)) {
|
||||
if ((p = weaken(realloc)(r, strlen(r) + 1))) {
|
||||
r = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -28,9 +29,13 @@
|
|||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int getitimer(int which, struct itimerval *curvalue) {
|
||||
if (IsAsan() && !__asan_is_valid(curvalue, sizeof(*curvalue))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_getitimer(which, curvalue);
|
||||
} else {
|
||||
return sys_setitimer_nt(which, NULL, curvalue);
|
||||
if (!curvalue) return efault();
|
||||
return sys_setitimer_nt(which, 0, curvalue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -30,6 +31,7 @@
|
|||
* @see libc/sysv/consts.sh
|
||||
*/
|
||||
int getrlimit(int resource, struct rlimit *rlim) {
|
||||
if (resource == -1) return einval();
|
||||
if (resource == 127) return einval();
|
||||
if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) return efault();
|
||||
return sys_getrlimit(resource, rlim);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -27,6 +29,8 @@
|
|||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int getrusage(int who, struct rusage *usage) {
|
||||
if (who == 99) return einval();
|
||||
if (IsAsan() && !__asan_is_valid(usage, sizeof(*usage))) return efault();
|
||||
if (!IsWindows()) {
|
||||
return sys_getrusage(who, usage);
|
||||
} else {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
int sys_gettimeofday_nt(struct timeval *tv, struct timezone *tz) {
|
||||
struct NtFileTime ft;
|
||||
GetSystemTimeAsFileTime(&ft);
|
||||
*tv = FileTimeToTimeVal(ft);
|
||||
if (tv) *tv = FileTimeToTimeVal(ft);
|
||||
if (tz) memset(tz, 0, sizeof(*tz));
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/timeval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/struct/timezone.h"
|
||||
#include "libc/time/time.h"
|
||||
|
@ -35,6 +36,10 @@
|
|||
*/
|
||||
int gettimeofday(struct timeval *tv, struct timezone *tz) {
|
||||
axdx_t ad;
|
||||
if (IsAsan() && ((tv && !__asan_is_valid(tv, sizeof(*tv))) ||
|
||||
(tz && !__asan_is_valid(tz, sizeof(*tz))))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows() && !IsMetal()) {
|
||||
ad = sys_gettimeofday(tv, tz, NULL);
|
||||
assert(ad.ax != -1);
|
||||
|
|
|
@ -117,7 +117,6 @@ i32 __sys_openat(i32, const char *, i32, u32) hidden;
|
|||
i32 __sys_pipe2(i32[hasatleast 2], u32) hidden;
|
||||
i32 __sys_utimensat(i32, const char *, const struct timespec *, i32) hidden;
|
||||
i32 __sys_wait4(i32, i32 *, i32, struct rusage *) hidden;
|
||||
i32 getdents(i32, void *, u32, i64 *) hidden;
|
||||
i32 sys_chdir(const char *) hidden;
|
||||
i32 sys_clock_gettime(i32, struct timespec *) hidden;
|
||||
i32 sys_close(i32) hidden;
|
||||
|
@ -232,6 +231,7 @@ int gethostname_bsd(char *, size_t) hidden;
|
|||
int gethostname_nt(char *, size_t) hidden;
|
||||
size_t __iovec_size(const struct iovec *, size_t) hidden;
|
||||
void __rusage2linux(struct rusage *) hidden;
|
||||
int __notziposat(int, const char *);
|
||||
ssize_t WritevUninterruptible(int, struct iovec *, int);
|
||||
void flock2cosmo(uintptr_t);
|
||||
void cosmo2flock(uintptr_t);
|
||||
|
@ -264,14 +264,14 @@ int sys_fdatasync_nt(int) hidden;
|
|||
int sys_flock_nt(int, int) hidden;
|
||||
int sys_fork_nt(void) hidden;
|
||||
int sys_fstat_nt(i64, struct stat *) hidden;
|
||||
int sys_fstatat_nt(int, const char *, struct stat *, uint32_t) hidden;
|
||||
int sys_fstatat_nt(int, const char *, struct stat *, int) hidden;
|
||||
int sys_ftruncate_nt(i64, u64) hidden;
|
||||
int sys_getppid_nt(void) hidden;
|
||||
int sys_getpriority_nt(int) hidden;
|
||||
int sys_getrusage_nt(int, struct rusage *) hidden;
|
||||
int sys_gettimeofday_nt(struct timeval *, struct timezone *) hidden;
|
||||
int sys_kill_nt(int, int) hidden;
|
||||
int sys_link_nt(const char *, const char *) hidden;
|
||||
int sys_linkat_nt(int, const char *, int, const char *) hidden;
|
||||
int sys_lstat_nt(const char *, struct stat *) hidden;
|
||||
int sys_madvise_nt(void *, size_t, int) hidden;
|
||||
int sys_mkdirat_nt(int, const char *, uint32_t) hidden;
|
||||
|
@ -287,12 +287,12 @@ int sys_sync_nt(void) hidden;
|
|||
int sys_sysinfo_nt(struct sysinfo *) hidden;
|
||||
int sys_truncate_nt(const char *, u64) hidden;
|
||||
int sys_unlinkat_nt(int, const char *, int) hidden;
|
||||
int sys_utimes_nt(const char *, const struct timeval[2]) hidden;
|
||||
int sys_utimensat_nt(int, const char *, const struct timespec *, int) hidden;
|
||||
int sys_utimes_nt(const char *, const struct timeval[2]) hidden;
|
||||
ssize_t sys_open_nt(int, const char *, u32, i32) nodiscard hidden;
|
||||
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
||||
ssize_t sys_write_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
||||
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) hidden;
|
||||
ssize_t sys_write_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § syscalls » windows nt » support ─╬─│┼
|
||||
|
|
|
@ -13,10 +13,10 @@ COSMOPOLITAN_C_START_
|
|||
|
||||
int ioctl(int, uint64_t, ...);
|
||||
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » ioctl » undiamonding (size optimization) ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
/*───────────────────────────────────────────────────────────────────────────│─╗
|
||||
│ cosmopolitan § system calls » ioctl » undiamonding ─╬─│┼
|
||||
╚────────────────────────────────────────────────────────────────────────────│*/
|
||||
|
||||
#define ioctl(FD, REQUEST, ...) \
|
||||
__IOCTL_DISPATCH(__EQUIVALENT, ioctl_default(FD, REQUEST, ##__VA_ARGS__), \
|
||||
|
@ -63,22 +63,18 @@ int ioctl(int, uint64_t, ...);
|
|||
ReZ; \
|
||||
})
|
||||
|
||||
int ioctl_tcgets(int, void *);
|
||||
int ioctl_tcgets_nt(int, void *);
|
||||
int ioctl_tcsets(int, uint64_t, void *);
|
||||
int ioctl_tcsets_nt(int, uint64_t, void *);
|
||||
int ioctl_tiocgwinsz(int, void *);
|
||||
int ioctl_tiocgwinsz_nt(int, void *);
|
||||
int ioctl_tiocswinsz(int, void *);
|
||||
int ioctl_tiocswinsz_nt(int, void *);
|
||||
int ioctl_siocgifconf(int, void *);
|
||||
int ioctl_siocgifaddr(int, void *);
|
||||
int ioctl_siocgifdstaddr(int, void *);
|
||||
int ioctl_siocgifnetmask(int, void *);
|
||||
int ioctl_siocgifbrdaddr(int, void *);
|
||||
int ioctl_siocgifflags(int, void *);
|
||||
int ioctl_default(int, uint64_t, void *);
|
||||
int ioctl_default(int, uint64_t, ...);
|
||||
int ioctl_fioclex(int, int);
|
||||
int ioctl_siocgifaddr(int, ...);
|
||||
int ioctl_siocgifbrdaddr(int, ...);
|
||||
int ioctl_siocgifconf(int, ...);
|
||||
int ioctl_siocgifdstaddr(int, ...);
|
||||
int ioctl_siocgifflags(int, ...);
|
||||
int ioctl_siocgifnetmask(int, ...);
|
||||
int ioctl_tcgets(int, ...);
|
||||
int ioctl_tcsets(int, uint64_t, ...);
|
||||
int ioctl_tiocgwinsz(int, ...);
|
||||
int ioctl_tiocswinsz(int, ...);
|
||||
|
||||
#endif /* GNUC && !ANSI */
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
|
@ -23,15 +23,20 @@
|
|||
#include "libc/sock/internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int ioctl_default(int fd, uint64_t request, void *memory) {
|
||||
int ioctl_default(int fd, uint64_t request, ...) {
|
||||
int rc;
|
||||
void *arg;
|
||||
va_list va;
|
||||
int64_t handle;
|
||||
va_start(va, request);
|
||||
arg = va_arg(va, void *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, request, memory);
|
||||
return sys_ioctl(fd, request, arg);
|
||||
} else if (__isfdopen(fd)) {
|
||||
if (g_fds.p[fd].kind == kFdSocket) {
|
||||
handle = g_fds.p[fd].handle;
|
||||
if ((rc = weaken(__sys_ioctlsocket_nt)(handle, request, memory)) != -1) {
|
||||
if ((rc = weaken(__sys_ioctlsocket_nt)(handle, request, arg)) != -1) {
|
||||
return rc;
|
||||
} else {
|
||||
return weaken(__winsockerr)();
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
int ioctl_fioclex_nt(int, int);
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Sets "close on exec" on file descriptor the fast way.
|
||||
|
@ -28,9 +28,22 @@ int ioctl_fioclex_nt(int, int);
|
|||
* @see ioctl(fd, FIOCLEX, 0) dispatches here
|
||||
*/
|
||||
int ioctl_fioclex(int fd, int req) {
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, req, 0);
|
||||
if (fd >= 0) {
|
||||
if (IsWindows() || (fd < g_fds.n && g_fds.p[fd].kind == kFdZip)) {
|
||||
if (__isfdopen(fd)) {
|
||||
if (req == FIOCLEX) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return ebadf();
|
||||
}
|
||||
} else {
|
||||
return sys_ioctl(fd, req);
|
||||
}
|
||||
} else {
|
||||
return ioctl_fioclex_nt(fd, req);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/assert.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -35,7 +36,6 @@
|
|||
* The ifc_len is an input/output parameter: set it to the total size of
|
||||
* the ifcu_buf (ifcu_req) buffer on input.
|
||||
*/
|
||||
int ioctl_default(int, uint64_t, void *) hidden;
|
||||
int ioctl_siocgifconf_nt(int, struct ifconf *) hidden;
|
||||
int ioctl_siocgifaddr_nt(int, struct ifreq *) hidden;
|
||||
int ioctl_siocgifflags_nt(int, struct ifreq *) hidden;
|
||||
|
@ -103,41 +103,66 @@ static int ioctl_siocgifaddr_sysv(int fd, uint64_t op, struct ifreq *ifr) {
|
|||
*
|
||||
* @see ioctl(fd, SIOCGIFCONF, tio) dispatches here
|
||||
*/
|
||||
int ioctl_siocgifconf(int fd, void *ifc) {
|
||||
int ioctl_siocgifconf(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifconf *ifc;
|
||||
va_start(va, fd);
|
||||
ifc = va_arg(va, struct ifconf *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifconf_sysv(fd, (struct ifconf *)ifc);
|
||||
return ioctl_siocgifconf_sysv(fd, ifc);
|
||||
} else {
|
||||
return ioctl_siocgifconf_nt(fd, ifc);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifaddr(int fd, void *ifr) {
|
||||
int ioctl_siocgifaddr(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFADDR, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFADDR, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifaddr_nt(fd, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifaddr_nt(fd, ifr);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifnetmask(int fd, void *ifr) {
|
||||
int ioctl_siocgifnetmask(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFNETMASK, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFNETMASK, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifnetmask_nt(fd, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifnetmask_nt(fd, ifr);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifbrdaddr(int fd, void *ifr) {
|
||||
int ioctl_siocgifbrdaddr(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFBRDADDR, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFBRDADDR, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifbrdaddr_nt(fd, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifbrdaddr_nt(fd, ifr);
|
||||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifdstaddr(int fd, void *ifr) {
|
||||
int ioctl_siocgifdstaddr(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFDSTADDR, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifaddr_sysv(fd, SIOCGIFDSTADDR, ifr);
|
||||
} else {
|
||||
return enotsup();
|
||||
/* Not supported - Unknown how to find out how to retrieve the destination
|
||||
|
@ -149,11 +174,16 @@ int ioctl_siocgifdstaddr(int fd, void *ifr) {
|
|||
}
|
||||
}
|
||||
|
||||
int ioctl_siocgifflags(int fd, void *ifr) {
|
||||
int ioctl_siocgifflags(int fd, ...) {
|
||||
va_list va;
|
||||
struct ifreq *ifr;
|
||||
va_start(va, fd);
|
||||
ifr = va_arg(va, struct ifreq *);
|
||||
va_end(va);
|
||||
if (!IsWindows()) {
|
||||
/* Both XNU and Linux are for once compatible here... */
|
||||
return ioctl_default(fd, SIOCGIFFLAGS, ifr);
|
||||
} else {
|
||||
return ioctl_siocgifflags_nt(fd, (struct ifreq *)ifr);
|
||||
return ioctl_siocgifflags_nt(fd, ifr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,13 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/metatermios.internal.h"
|
||||
#include "libc/calls/termios.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int ioctl_tcgets_nt(int, struct termios *) hidden;
|
||||
|
||||
|
@ -39,10 +43,23 @@ static int ioctl_tcgets_sysv(int fd, struct termios *tio) {
|
|||
* @see ioctl(fd, TCGETS, tio) dispatches here
|
||||
* @see ioctl(fd, TIOCGETA, tio) dispatches here
|
||||
*/
|
||||
int ioctl_tcgets(int fd, struct termios *tio) {
|
||||
if (!IsWindows()) {
|
||||
return ioctl_tcgets_sysv(fd, tio);
|
||||
int ioctl_tcgets(int fd, ...) {
|
||||
va_list va;
|
||||
struct termios *tio;
|
||||
va_start(va, fd);
|
||||
tio = va_arg(va, struct termios *);
|
||||
va_end(va);
|
||||
if (fd >= 0) {
|
||||
if (!tio) return efault();
|
||||
if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault();
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return enotty();
|
||||
} else if (!IsWindows()) {
|
||||
return ioctl_tcgets_sysv(fd, tio);
|
||||
} else {
|
||||
return ioctl_tcgets_nt(fd, tio);
|
||||
}
|
||||
} else {
|
||||
return ioctl_tcgets_nt(fd, tio);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,9 +17,11 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/metatermios.internal.h"
|
||||
#include "libc/calls/termios.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -38,11 +40,23 @@ static int ioctl_tcsets_sysv(int fd, uint64_t request,
|
|||
* @see ioctl(fd, TCSETS{,W,F}, tio) dispatches here
|
||||
* @see ioctl(fd, TIOCGETA{,W,F}, tio) dispatches here
|
||||
*/
|
||||
int ioctl_tcsets(int fd, uint64_t request, const struct termios *tio) {
|
||||
int ioctl_tcsets(int fd, uint64_t request, ...) {
|
||||
va_list va;
|
||||
const struct termios *tio;
|
||||
va_start(va, request);
|
||||
tio = va_arg(va, const struct termios *);
|
||||
va_end(va);
|
||||
if (!tio) return efault();
|
||||
if (!IsWindows()) {
|
||||
return ioctl_tcsets_sysv(fd, request, tio);
|
||||
if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault();
|
||||
if (fd >= 0) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return enotty();
|
||||
} else if (!IsWindows()) {
|
||||
return ioctl_tcsets_sysv(fd, request, tio);
|
||||
} else {
|
||||
return ioctl_tcsets_nt(fd, request, tio);
|
||||
}
|
||||
} else {
|
||||
return ioctl_tcsets_nt(fd, request, tio);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ textwindows int ioctl_tiocgwinsz_nt(int fd, struct winsize *ws) {
|
|||
uint32_t mode;
|
||||
struct NtStartupInfo startinfo;
|
||||
struct NtConsoleScreenBufferInfoEx sbinfo;
|
||||
if (!ws) return efault();
|
||||
fds[0] = fd, fds[1] = 1, fds[2] = 0;
|
||||
GetStartupInfo(&startinfo);
|
||||
for (i = 0; i < ARRAYLEN(fds); ++i) {
|
||||
|
|
|
@ -17,9 +17,12 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int ioctl_tiocgwinsz_nt(int, struct winsize *);
|
||||
|
||||
|
@ -28,10 +31,22 @@ int ioctl_tiocgwinsz_nt(int, struct winsize *);
|
|||
*
|
||||
* @see ioctl(fd, TIOCGWINSZ, ws) dispatches here
|
||||
*/
|
||||
int ioctl_tiocgwinsz(int fd, struct winsize *ws) {
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, TIOCGWINSZ, ws);
|
||||
int ioctl_tiocgwinsz(int fd, ...) {
|
||||
va_list va;
|
||||
struct winsize *ws;
|
||||
va_start(va, fd);
|
||||
ws = va_arg(va, struct winsize *);
|
||||
va_end(va);
|
||||
if (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) return efault();
|
||||
if (fd >= 0) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return enotty();
|
||||
} else if (!IsWindows()) {
|
||||
return sys_ioctl(fd, TIOCGWINSZ, ws);
|
||||
} else {
|
||||
return ioctl_tiocgwinsz_nt(fd, ws);
|
||||
}
|
||||
} else {
|
||||
return ioctl_tiocgwinsz_nt(fd, ws);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,21 +17,36 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
int ioctl_tiocswinsz_nt(int, const struct winsize *);
|
||||
|
||||
/**
|
||||
* Returns width and height of terminal.
|
||||
* Sets width and height of terminal.
|
||||
*
|
||||
* @see ioctl(fd, TIOCSWINSZ, ws) dispatches here
|
||||
*/
|
||||
int ioctl_tiocswinsz(int fd, const struct winsize *ws) {
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, TIOCSWINSZ, ws);
|
||||
int ioctl_tiocswinsz(int fd, ...) {
|
||||
va_list va;
|
||||
const struct winsize *ws;
|
||||
va_start(va, fd);
|
||||
ws = va_arg(va, const struct winsize *);
|
||||
va_end(va);
|
||||
if (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) return efault();
|
||||
if (fd >= 0) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return enotty();
|
||||
} else if (!IsWindows()) {
|
||||
return sys_ioctl(fd, TIOCSWINSZ, ws);
|
||||
} else {
|
||||
return ioctl_tiocswinsz_nt(fd, ws);
|
||||
}
|
||||
} else {
|
||||
return ioctl_tiocswinsz_nt(fd, ws);
|
||||
return einval();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows bool32 sys_isatty_nt(int fd) {
|
||||
if (!__isfdkind(fd, kFdFile)) return ebadf();
|
||||
return GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar;
|
||||
return __isfdkind(fd, kFdConsole) ||
|
||||
(__isfdkind(fd, kFdFile) &&
|
||||
GetFileType(g_fds.p[fd].handle) == kNtFileTypeChar);
|
||||
}
|
||||
|
|
|
@ -18,18 +18,30 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
/**
|
||||
* Returns true if file descriptor is backed by a terminal device.
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
bool32 isatty(int fd) {
|
||||
_Alignas(short) char buf[sizeof(uint16_t) * 4];
|
||||
if (!IsWindows()) {
|
||||
return sys_ioctl(fd, TIOCGWINSZ, &buf) != -1;
|
||||
int err;
|
||||
bool32 res;
|
||||
struct winsize ws;
|
||||
if (fd >= 0) {
|
||||
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
|
||||
return false;
|
||||
} else if (!IsWindows()) {
|
||||
err = errno;
|
||||
res = sys_ioctl(fd, TIOCGWINSZ, &ws) != -1;
|
||||
errno = err;
|
||||
return res;
|
||||
} else {
|
||||
return sys_isatty_nt(fd);
|
||||
}
|
||||
} else {
|
||||
return sys_isatty_nt(fd);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns true if file exists and is a directory.
|
||||
|
@ -30,6 +32,7 @@
|
|||
bool isdirectory(const char *path) {
|
||||
struct stat st;
|
||||
int rc, olderr;
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (!IsWindows()) {
|
||||
olderr = errno;
|
||||
rc = sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW);
|
||||
|
|
|
@ -21,7 +21,9 @@
|
|||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns true if file exists and is a regular file.
|
||||
|
@ -29,6 +31,7 @@
|
|||
bool isregularfile(const char *path) {
|
||||
struct stat st;
|
||||
int rc, olderr;
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (!IsWindows()) {
|
||||
olderr = errno;
|
||||
rc = sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW);
|
||||
|
|
|
@ -21,8 +21,10 @@
|
|||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns true if file exists and is a symbolic link.
|
||||
|
@ -30,6 +32,7 @@
|
|||
bool issymlink(const char *path) {
|
||||
struct stat st;
|
||||
int rc, olderr;
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (!IsWindows()) {
|
||||
olderr = errno;
|
||||
rc = sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW);
|
||||
|
|
|
@ -31,5 +31,5 @@
|
|||
* @see /etc/group for group ids
|
||||
*/
|
||||
int lchown(const char *pathname, uint32_t uid, uint32_t gid) {
|
||||
return sys_fchownat(AT_FDCWD, pathname, uid, gid, AT_SYMLINK_NOFOLLOW);
|
||||
return fchownat(AT_FDCWD, pathname, uid, gid, AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
|
|
@ -32,9 +32,5 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int link(const char *existingpath, const char *newpath) {
|
||||
if (!IsWindows()) {
|
||||
return sys_linkat(AT_FDCWD, existingpath, AT_FDCWD, newpath, 0);
|
||||
} else {
|
||||
return sys_link_nt(existingpath, newpath);
|
||||
}
|
||||
return linkat(AT_FDCWD, existingpath, AT_FDCWD, newpath, 0);
|
||||
}
|
||||
|
|
|
@ -21,12 +21,13 @@
|
|||
#include "libc/nt/files.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
|
||||
textwindows int sys_link_nt(const char *existingpath, const char *newpath) {
|
||||
textwindows int sys_linkat_nt(int olddirfd, const char *oldpath, int newdirfd,
|
||||
const char *newpath) {
|
||||
char16_t newpath16[PATH_MAX];
|
||||
char16_t existingpath16[PATH_MAX];
|
||||
if (__mkntpath(existingpath, existingpath16) != -1 &&
|
||||
__mkntpath(newpath, newpath16) != -1) {
|
||||
if (CreateHardLink(newpath16, existingpath16, NULL)) {
|
||||
char16_t oldpath16[PATH_MAX];
|
||||
if (__mkntpathat(olddirfd, oldpath, 0, oldpath16) != -1 &&
|
||||
__mkntpathat(newdirfd, newpath, 0, newpath16) != -1) {
|
||||
if (CreateHardLink(newpath16, oldpath16, NULL)) {
|
||||
return 0;
|
||||
} else {
|
||||
return __winerr();
|
53
libc/calls/linkat.c
Normal file
53
libc/calls/linkat.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- 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 2021 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/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Creates hard filesystem link.
|
||||
*
|
||||
* This allows two names to point to the same file data on disk. They
|
||||
* can only be differentiated by examining the inode number.
|
||||
*
|
||||
* @param flags can have AT_EMPTY_PATH or AT_SYMLINK_NOFOLLOW
|
||||
* @return 0 on success, or -1 w/ errno
|
||||
* @asyncsignalsafe
|
||||
*/
|
||||
int linkat(int olddirfd, const char *oldpath, int newdirfd, const char *newpath,
|
||||
int flags) {
|
||||
if (IsAsan() &&
|
||||
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
|
||||
return efault();
|
||||
}
|
||||
if (weaken(__zipos_notat) &&
|
||||
(weaken(__zipos_notat)(olddirfd, oldpath) == -1 ||
|
||||
weaken(__zipos_notat)(newdirfd, newpath) == -1)) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_linkat(olddirfd, oldpath, newdirfd, newpath, flags);
|
||||
} else {
|
||||
return sys_linkat_nt(olddirfd, oldpath, newdirfd, newpath);
|
||||
}
|
||||
}
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Drops hints to O/S about intended access patterns of mmap()'d memory.
|
||||
|
@ -29,6 +31,7 @@
|
|||
* @see fadvise()
|
||||
*/
|
||||
int madvise(void *addr, size_t length, int advice) {
|
||||
if (IsAsan() && !__asan_is_valid(addr, length)) return efault();
|
||||
if (!IsWindows()) {
|
||||
return sys_madvise(addr, length, advice);
|
||||
} else {
|
||||
|
|
34
libc/calls/major.c
Normal file
34
libc/calls/major.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- 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 2021 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/makedev.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
uint32_t(major)(uint64_t x) {
|
||||
if (IsXnu()) {
|
||||
return (x >> 24) & 0xff;
|
||||
} else if (IsNetbsd()) {
|
||||
return (x & 0x000fff00) >> 8;
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x >> 8) & 0xff;
|
||||
} else if (IsFreebsd()) {
|
||||
return ((x >> 32) & 0xffffff00) | ((x >> 8) & 0x000000ff);
|
||||
} else {
|
||||
return ((x >> 32) & 0xfffff000) | ((x >> 8) & 0x00000fff);
|
||||
}
|
||||
}
|
37
libc/calls/makedev.c
Normal file
37
libc/calls/makedev.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*-*- 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 2021 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/makedev.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
uint64_t(makedev)(uint32_t x, uint32_t y) {
|
||||
if (IsXnu()) {
|
||||
return x << 24 | y;
|
||||
} else if (IsNetbsd()) {
|
||||
return ((x << 8) & 0x000fff00) | ((y << 12) & 0xfff00000) |
|
||||
(y & 0x000000ff);
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x & 0xff) << 8 | (y & 0xff) | (y & 0xffff00) << 8;
|
||||
} else if (IsFreebsd()) {
|
||||
return (uint64_t)(x & 0xffffff00) << 32 | (x & 0x000000ff) << 8 |
|
||||
(y & 0x0000ff00) << 24 | (y & 0xffff00ff);
|
||||
} else {
|
||||
return (uint64_t)(x & 0xfffff000) << 32 | (x & 0x00000fff) << 8 |
|
||||
(y & 0xffffff00) << 12 | (y & 0x000000ff);
|
||||
}
|
||||
}
|
|
@ -1,52 +1,10 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_CALLS_MAKEDEV_H_
|
||||
#define COSMOPOLITAN_LIBC_CALLS_MAKEDEV_H_
|
||||
#include "libc/dce.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
static inline uint64_t major(uint64_t x) {
|
||||
if (IsXnu()) {
|
||||
return (x >> 24) & 0xff;
|
||||
} else if (IsNetbsd()) {
|
||||
return (x & 0x000fff00) >> 8;
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x >> 8) & 0xff;
|
||||
} else if (IsFreebsd()) {
|
||||
return ((x >> 32) & 0xffffff00) | ((x >> 8) & 0x000000ff);
|
||||
} else {
|
||||
return ((x >> 32) & 0xfffff000) | ((x >> 8) & 0x00000fff);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t minor(uint64_t x) {
|
||||
if (IsXnu()) {
|
||||
return x & 0x00ffffff;
|
||||
} else if (IsNetbsd()) {
|
||||
return (x & 0x000000ff) | (x & 0xfff00000) >> 12;
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x & 0x000000ff) | (x & 0x0ffff000) >> 8;
|
||||
} else if (IsFreebsd()) {
|
||||
return ((x >> 24) & 0x0000ff00) | (x & 0xffff00ff);
|
||||
} else {
|
||||
return ((x >> 12) & 0xffffff00) | (x & 0x000000ff);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint64_t makedev(uint64_t x, uint64_t y) {
|
||||
if (IsXnu()) {
|
||||
return x << 24 | y;
|
||||
} else if (IsNetbsd()) {
|
||||
return ((x << 8) & 0x000fff00) | ((y << 12) & 0xfff00000u) |
|
||||
(y & 0x000000ff);
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x & 0xff) << 8 | (y & 0xff) | (y & 0xffff00) << 8;
|
||||
} else if (IsFreebsd()) {
|
||||
return (x & 0xffffff00) << 32 | (x & 0x000000ff) << 8 |
|
||||
(y & 0x0000ff00) << 24 | (y & 0xffff00ff);
|
||||
} else {
|
||||
return (x & 0xfffff000) << 32 | (x & 0x00000fff) << 8 |
|
||||
(y & 0xffffff00) << 12 | (y & 0x000000ff);
|
||||
}
|
||||
}
|
||||
uint64_t makedev(uint32_t, uint32_t);
|
||||
uint32_t major(uint64_t);
|
||||
uint32_t minor(uint64_t);
|
||||
|
||||
#define major(x) major(x)
|
||||
#define minor(x) minor(x)
|
||||
|
|
34
libc/calls/minor.c
Normal file
34
libc/calls/minor.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- 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 2021 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/makedev.h"
|
||||
#include "libc/dce.h"
|
||||
|
||||
uint32_t(minor)(uint64_t x) {
|
||||
if (IsXnu()) {
|
||||
return x & 0x00ffffff;
|
||||
} else if (IsNetbsd()) {
|
||||
return (x & 0x000000ff) | (x & 0xfff00000) >> 12;
|
||||
} else if (IsOpenbsd()) {
|
||||
return (x & 0x000000ff) | (x & 0x0ffff000) >> 8;
|
||||
} else if (IsFreebsd()) {
|
||||
return ((x >> 24) & 0x0000ff00) | (x & 0xffff00ff);
|
||||
} else {
|
||||
return ((x >> 12) & 0xffffff00) | (x & 0x000000ff);
|
||||
}
|
||||
}
|
|
@ -16,10 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Creates directory a.k.a. folder.
|
||||
|
@ -34,6 +38,10 @@
|
|||
* @see makedirs()
|
||||
*/
|
||||
int mkdirat(int dirfd, const char *path, unsigned mode) {
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_mkdirat(dirfd, path, mode);
|
||||
} else {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/nt/ipc.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -33,6 +34,7 @@
|
|||
*/
|
||||
int mkfifo(const char *pathname, unsigned mode) {
|
||||
/* TODO(jart): Windows? */
|
||||
if (IsAsan() && !__asan_is_valid(pathname, 1)) return efault();
|
||||
if (IsLinux()) {
|
||||
return sys_mknod(pathname, mode | S_IFIFO, 0);
|
||||
} else {
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Creates filesystem inode.
|
||||
|
@ -37,6 +38,7 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int mknod(const char *path, uint32_t mode, uint64_t dev) {
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (mode & S_IFREG) return creat(path, mode & ~S_IFREG);
|
||||
if (mode & S_IFDIR) return mkdir(path, mode & ~S_IFDIR);
|
||||
if (mode & S_IFIFO) return mkfifo(path, mode & ~S_IFIFO);
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/enum/accessmask.h"
|
||||
#include "libc/nt/enum/securityimpersonationlevel.h"
|
||||
#include "libc/nt/enum/securityinformation.h"
|
||||
|
@ -30,6 +32,13 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/ok.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
#if 0
|
||||
#define DEBUG(FMT, ...) (dprintf)(2, FMT "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define DEBUG(FMT, ...) (void)0
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Asks Microsoft if we're authorized to use a folder or file.
|
||||
|
@ -44,19 +53,20 @@
|
|||
* @see libc/sysv/consts.sh
|
||||
*/
|
||||
textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
|
||||
int rc;
|
||||
int rc, e;
|
||||
void *freeme;
|
||||
bool32 result;
|
||||
struct NtSecurityDescriptor *s;
|
||||
struct NtGenericMapping mapping;
|
||||
struct NtPrivilegeSet privileges;
|
||||
int64_t hToken, hImpersonatedToken;
|
||||
uint32_t secsize, granted, privsize;
|
||||
union NtSecurityDescriptorLol {
|
||||
struct NtSecurityDescriptor s;
|
||||
char b[1024];
|
||||
} security;
|
||||
intptr_t buffer[1024 / sizeof(intptr_t)];
|
||||
freeme = 0;
|
||||
granted = 0;
|
||||
result = false;
|
||||
secsize = sizeof(security);
|
||||
s = (void *)buffer;
|
||||
secsize = sizeof(buffer);
|
||||
privsize = sizeof(privileges);
|
||||
memset(&privileges, 0, sizeof(privileges));
|
||||
mapping.GenericRead = kNtFileGenericRead;
|
||||
|
@ -65,24 +75,55 @@ textwindows int ntaccesscheck(const char16_t *pathname, uint32_t flags) {
|
|||
mapping.GenericAll = kNtFileAllAccess;
|
||||
MapGenericMask(&flags, &mapping);
|
||||
hImpersonatedToken = hToken = -1;
|
||||
TryAgain:
|
||||
if (GetFileSecurity(pathname,
|
||||
kNtOwnerSecurityInformation |
|
||||
kNtGroupSecurityInformation |
|
||||
kNtDaclSecurityInformation,
|
||||
&security.s, 0, &secsize) &&
|
||||
OpenProcessToken(GetCurrentProcess(),
|
||||
kNtTokenImpersonate | kNtTokenQuery | kNtTokenDuplicate |
|
||||
kNtStandardRightsRead,
|
||||
&hToken) &&
|
||||
DuplicateToken(hToken, kNtSecurityImpersonation, &hImpersonatedToken) &&
|
||||
AccessCheck(&security.s, hImpersonatedToken, flags, &mapping, &privileges,
|
||||
&privsize, &granted, &result) &&
|
||||
(result || flags == F_OK)) {
|
||||
rc = 0;
|
||||
s, secsize, &secsize)) {
|
||||
if (OpenProcessToken(GetCurrentProcess(),
|
||||
kNtTokenImpersonate | kNtTokenQuery |
|
||||
kNtTokenDuplicate | kNtStandardRightsRead,
|
||||
&hToken)) {
|
||||
if (DuplicateToken(hToken, kNtSecurityImpersonation,
|
||||
&hImpersonatedToken)) {
|
||||
if (AccessCheck(s, hImpersonatedToken, flags, &mapping, &privileges,
|
||||
&privsize, &granted, &result)) {
|
||||
if (result || flags == F_OK) {
|
||||
rc = 0;
|
||||
} else {
|
||||
DEBUG("ntaccesscheck finale failed %d %d", result, flags);
|
||||
rc = eacces();
|
||||
}
|
||||
} else {
|
||||
rc = __winerr();
|
||||
DEBUG("AccessCheck failed: %m");
|
||||
}
|
||||
} else {
|
||||
rc = __winerr();
|
||||
DEBUG("DuplicateToken failed: %m");
|
||||
}
|
||||
} else {
|
||||
rc = __winerr();
|
||||
DEBUG("OpenProcessToken failed: %m");
|
||||
}
|
||||
} else {
|
||||
rc = __winerr();
|
||||
e = GetLastError();
|
||||
DEBUG("GetFileSecurity failed: %d %d", e, secsize);
|
||||
if (!IsTiny() && e == kNtErrorInsufficientBuffer) {
|
||||
if (!freeme && weaken(malloc) && (freeme = weaken(malloc)(secsize))) {
|
||||
s = freeme;
|
||||
goto TryAgain;
|
||||
} else {
|
||||
rc = enomem();
|
||||
}
|
||||
} else {
|
||||
errno = e;
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
close(hImpersonatedToken);
|
||||
close(hToken);
|
||||
if (freeme && weaken(free)) weaken(free)(freeme);
|
||||
if (hImpersonatedToken != -1) CloseHandle(hImpersonatedToken);
|
||||
if (hToken != -1) CloseHandle(hToken);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
@ -43,13 +45,19 @@ int openat(int dirfd, const char *file, int flags, ...) {
|
|||
va_list va;
|
||||
unsigned mode;
|
||||
struct ZiposUri zipname;
|
||||
if (strstr(file, "0/o/dbg/test")) {
|
||||
(dprintf)(2, "-- wut %`'s\n", file);
|
||||
if (weaken(__die)) weaken(__die)();
|
||||
}
|
||||
va_start(va, flags);
|
||||
mode = va_arg(va, unsigned);
|
||||
va_end(va);
|
||||
if (!file) return efault();
|
||||
if (IsAsan() && !__asan_is_valid(file, 1)) return efault();
|
||||
if (__isfdkind(dirfd, kFdZip)) return einval(); /* TODO(jart): implement me */
|
||||
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(file, &zipname) != -1) {
|
||||
if (__vforked) return einval();
|
||||
if (dirfd != AT_FDCWD) return einval();
|
||||
if (__vforked) return eopnotsupp();
|
||||
if (dirfd != AT_FDCWD) return eopnotsupp();
|
||||
return weaken(__zipos_open)(&zipname, flags, mode);
|
||||
} else if (!IsWindows() && !IsMetal()) {
|
||||
return sys_openat(dirfd, file, flags, mode);
|
||||
|
|
|
@ -22,11 +22,13 @@
|
|||
#include "libc/nt/enum/creationdisposition.h"
|
||||
#include "libc/nt/ipc.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
textwindows int sys_pipe_nt(int pipefd[2], unsigned flags) {
|
||||
int64_t hin, hout;
|
||||
int reader, writer;
|
||||
char16_t pipename[64];
|
||||
if (!pipefd) return efault();
|
||||
CreatePipeName(pipename);
|
||||
if ((reader = __reservefd()) == -1) return -1;
|
||||
if ((writer = __reservefd()) == -1) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -30,7 +31,7 @@
|
|||
* @see pipe2()
|
||||
*/
|
||||
int pipe(int pipefd[hasatleast 2]) {
|
||||
if (!pipefd) return efault();
|
||||
if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) return efault();
|
||||
if (!IsWindows()) {
|
||||
return sys_pipe(pipefd);
|
||||
} else {
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -28,6 +30,7 @@
|
|||
*/
|
||||
int pipe2(int pipefd[hasatleast 2], int flags) {
|
||||
if (!pipefd) return efault();
|
||||
if (IsAsan() && !__asan_is_valid(pipefd, sizeof(int) * 2)) return efault();
|
||||
if (!IsWindows()) {
|
||||
return sys_pipe2(pipefd, flags);
|
||||
} else {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/iovec.h"
|
||||
#include "libc/sock/sock.h"
|
||||
|
||||
|
|
|
@ -60,13 +60,14 @@
|
|||
* @see ECMA-48
|
||||
*/
|
||||
ssize_t readansi(int fd, char *buf, size_t size) {
|
||||
int i, j;
|
||||
wint_t x;
|
||||
uint8_t c;
|
||||
int i, j, rc;
|
||||
enum { kAscii, kUtf8, kEsc, kCsi, kSs } t;
|
||||
if (size) buf[0] = 0;
|
||||
for (j = i = 0, t = kAscii;;) {
|
||||
if (i + 2 >= size) return enomem();
|
||||
if (read(fd, &c, 1) != 1) return -1;
|
||||
if ((rc = read(fd, &c, 1)) != 1) return rc;
|
||||
buf[i++] = c;
|
||||
buf[i] = 0;
|
||||
switch (t) {
|
||||
|
@ -79,11 +80,24 @@ ssize_t readansi(int fd, char *buf, size_t size) {
|
|||
}
|
||||
} else if (c >= 0300) {
|
||||
t = kUtf8;
|
||||
x = ThomPikeByte(c);
|
||||
j = ThomPikeLen(c) - 1;
|
||||
}
|
||||
break;
|
||||
case kUtf8:
|
||||
if (!--j) return i;
|
||||
x = ThomPikeMerge(x, c);
|
||||
if (!--j) {
|
||||
switch (x) {
|
||||
case '\e':
|
||||
t = kEsc;
|
||||
break;
|
||||
case 0x9b:
|
||||
t = kCsi;
|
||||
break;
|
||||
default:
|
||||
return i;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case kEsc:
|
||||
switch (c) {
|
||||
|
|
|
@ -37,11 +37,12 @@
|
|||
|
||||
static textwindows ssize_t sys_readlinkat_nt_error(void) {
|
||||
uint32_t e;
|
||||
if ((e = GetLastError()) == kNtErrorNotAReparsePoint) {
|
||||
return einval();
|
||||
} else {
|
||||
errno = e;
|
||||
return -1;
|
||||
switch ((e = GetLastError())) {
|
||||
case kNtErrorNotAReparsePoint:
|
||||
return einval();
|
||||
default:
|
||||
errno = e;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,6 +56,7 @@ textwindows ssize_t sys_readlinkat_nt(int dirfd, const char *path, char *buf,
|
|||
uint32_t e, i, j, n, mem;
|
||||
char16_t path16[PATH_MAX], *p;
|
||||
struct NtReparseDataBuffer *rdb;
|
||||
if (!buf) return efault();
|
||||
if (weaken(malloc)) {
|
||||
mem = 16384;
|
||||
rdb = weaken(malloc)(mem);
|
||||
|
|
|
@ -48,8 +48,8 @@
|
|||
ssize_t readlinkat(int dirfd, const char *path, char *buf, size_t bufsiz) {
|
||||
struct ZiposUri zipname;
|
||||
if (IsAsan() && !__asan_is_valid(buf, bufsiz)) return efault();
|
||||
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
|
||||
return einval();
|
||||
if (weaken(__zipos_notat) && __zipos_notat(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): code me */
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_readlinkat(dirfd, path, buf, bufsiz);
|
||||
|
|
|
@ -90,8 +90,8 @@ char *realpath(const char *filename, char *resolved)
|
|||
return 0;
|
||||
}
|
||||
if (l >= PATH_MAX) goto toolong;
|
||||
if (l > 4 && (READ32LE(filename) == READ32LE("zip:") ||
|
||||
READ32LE(filename) == READ32LE("zip!"))) {
|
||||
if (l >= 4 && READ32LE(filename) == READ32LE("/zip") &&
|
||||
(!filename[4] || filename[4] == '/')) {
|
||||
return ResolvePath(resolved, filename, l);
|
||||
}
|
||||
p = sizeof stack - l - 1;
|
||||
|
|
|
@ -16,10 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Renames files relative to directories.
|
||||
|
@ -32,6 +36,15 @@
|
|||
*/
|
||||
int renameat(int olddirfd, const char *oldpath, int newdirfd,
|
||||
const char *newpath) {
|
||||
if (IsAsan() &&
|
||||
(!__asan_is_valid(oldpath, 1) || !__asan_is_valid(newpath, 1))) {
|
||||
return efault();
|
||||
}
|
||||
if (weaken(__zipos_notat) &&
|
||||
(weaken(__zipos_notat)(olddirfd, oldpath) == -1 ||
|
||||
weaken(__zipos_notat)(newdirfd, newpath) == -1)) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_renameat(olddirfd, oldpath, newdirfd, newpath);
|
||||
} else {
|
||||
|
|
|
@ -61,7 +61,7 @@ static uint32_t ItimerWorker(void *arg) {
|
|||
}
|
||||
|
||||
textwindows int sys_setitimer_nt(int which, const struct itimerval *newvalue,
|
||||
struct itimerval *out_opt_oldvalue) {
|
||||
struct itimerval *out_opt_oldvalue) {
|
||||
int32_t period;
|
||||
int64_t ith, duetime;
|
||||
if (which != ITIMER_REAL) return einval();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/itimerval.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
|
@ -62,14 +63,19 @@
|
|||
* @return 0 on success or -1 w/ errno
|
||||
*/
|
||||
int setitimer(int which, const struct itimerval *newvalue,
|
||||
struct itimerval *out_opt_oldvalue) {
|
||||
struct itimerval *oldvalue) {
|
||||
if (IsAsan() &&
|
||||
((newvalue && !__asan_is_valid(newvalue, sizeof(*newvalue))) ||
|
||||
(oldvalue && !__asan_is_valid(oldvalue, sizeof(*oldvalue))))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
if (newvalue) {
|
||||
return sys_setitimer(which, newvalue, out_opt_oldvalue);
|
||||
return sys_setitimer(which, newvalue, oldvalue);
|
||||
} else {
|
||||
return sys_getitimer(which, out_opt_oldvalue);
|
||||
return sys_getitimer(which, oldvalue);
|
||||
}
|
||||
} else {
|
||||
return sys_setitimer_nt(which, newvalue, out_opt_oldvalue);
|
||||
return sys_setitimer_nt(which, newvalue, oldvalue);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -31,9 +33,6 @@
|
|||
*/
|
||||
int setrlimit(int resource, const struct rlimit *rlim) {
|
||||
if (resource == 127) return einval();
|
||||
if (!IsWindows()) {
|
||||
return sys_setrlimit(resource, rlim);
|
||||
} else {
|
||||
return enosys(); /* TODO(jart): Implement me! */
|
||||
}
|
||||
if (IsAsan() && !__asan_is_valid(rlim, sizeof(*rlim))) return efault();
|
||||
return sys_setrlimit(resource, rlim);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "libc/calls/typedef/sigaction_f.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
@ -141,18 +142,23 @@ static void sigaction_native2cosmo(union metasigaction *sa) {
|
|||
* @vforksafe
|
||||
*/
|
||||
int(sigaction)(int sig, const struct sigaction *act, struct sigaction *oldact) {
|
||||
_Static_assert((sizeof(struct sigaction) > sizeof(struct sigaction_linux) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_netbsd)),
|
||||
"sigaction cosmo abi needs tuning");
|
||||
int64_t arg4, arg5;
|
||||
int rc, rva, oldrva;
|
||||
struct sigaction *ap, copy;
|
||||
assert(sizeof(struct sigaction) > sizeof(struct sigaction_linux) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_in) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_xnu_out) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_freebsd) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_openbsd) &&
|
||||
sizeof(struct sigaction) > sizeof(struct sigaction_netbsd));
|
||||
if (IsMetal()) return enosys(); /* TODO: Signals on Metal */
|
||||
if (!(0 < sig && sig < NSIG)) return einval();
|
||||
if (sig == SIGKILL || sig == SIGSTOP) return einval();
|
||||
if (IsAsan() && ((act && !__asan_is_valid(act, sizeof(*act))) ||
|
||||
(oldact && !__asan_is_valid(oldact, sizeof(*oldact))))) {
|
||||
return efault();
|
||||
}
|
||||
if (!act) {
|
||||
rva = (int32_t)(intptr_t)SIG_DFL;
|
||||
} else if ((intptr_t)act->sa_handler < kSigactionMinRva) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
|
@ -40,6 +41,12 @@
|
|||
*/
|
||||
int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
|
||||
int32_t x;
|
||||
if (IsAsan() &&
|
||||
((opt_set && !__asan_is_valid(opt_set, sizeof(*opt_set))) ||
|
||||
(opt_out_oldset &&
|
||||
!__asan_is_valid(opt_out_oldset, sizeof(*opt_out_oldset))))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows() && !IsOpenbsd()) {
|
||||
return sys_sigprocmask(how, opt_set, opt_out_oldset, 8);
|
||||
} else if (IsOpenbsd()) {
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/sigset.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
|
@ -31,6 +32,7 @@
|
|||
*/
|
||||
int sigsuspend(const sigset_t *ignore) {
|
||||
unsigned x;
|
||||
if (IsAsan() && !__asan_is_valid(ignore, sizeof(*ignore))) return efault();
|
||||
if (!IsWindows()) {
|
||||
if (IsOpenbsd()) ignore = (sigset_t *)(uintptr_t)(*(uint32_t *)ignore);
|
||||
return sys_sigsuspend(ignore, 8);
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Creates symbolic link.
|
||||
|
@ -35,6 +37,10 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int symlinkat(const char *target, int newdirfd, const char *linkpath) {
|
||||
if (IsAsan() &&
|
||||
(!__asan_is_valid(target, 1) || !__asan_is_valid(linkpath, 1))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_symlinkat(target, newdirfd, linkpath);
|
||||
} else {
|
||||
|
|
|
@ -17,10 +17,29 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/struct/termios.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Changes flow of teletypewriter data.
|
||||
*
|
||||
* - `TCOOFF` suspends output
|
||||
* - `TCOON` resumes output
|
||||
* - `TCIOFF` transmits a STOP character
|
||||
* - `TCION` transmits a START character
|
||||
*/
|
||||
int tcflow(int fd, int action) {
|
||||
/* TODO(jart): BSD support */
|
||||
return sys_ioctl(fd, TCXONC, (void *)(intptr_t)action);
|
||||
uint8_t c;
|
||||
struct termios t;
|
||||
if (!IsBsd()) return sys_ioctl(fd, TCXONC, action);
|
||||
if (action == TCOOFF) return sys_ioctl(fd, TIOCSTOP, 0);
|
||||
if (action == TCOON) return sys_ioctl(fd, TIOCSTART, 0);
|
||||
if (action != TCIOFF && action != TCION) return einval();
|
||||
if (tcgetattr(fd, &t) == -1) return -1;
|
||||
if ((c = t.c_cc[action == TCIOFF ? VSTOP : VSTART]) != 255) {
|
||||
if (sys_write(fd, &c, 1) == -1) return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -18,9 +18,15 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
|
||||
int tcflush(int fd, int x) {
|
||||
/* TODO(jart): BSD Support */
|
||||
return sys_ioctl(fd, TCFLSH, x);
|
||||
/**
|
||||
* Flushes teletypewriter data.
|
||||
*
|
||||
* - `TCIFLUSH` flushes data received but not read
|
||||
* - `TCOFLUSH` flushes data written but not transmitted
|
||||
* - `TCIOFLUSH` does both `TCOFLUSH` and `TCIFLUSH`
|
||||
*/
|
||||
int tcflush(int fd, int queue) {
|
||||
/* TODO(jart): Windows? */
|
||||
return sys_ioctl(fd, TCFLSH, queue);
|
||||
}
|
||||
|
|
|
@ -16,10 +16,14 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Deletes inode and maybe the file too.
|
||||
|
@ -31,6 +35,10 @@
|
|||
* @return 0 on success, or -1 w/ errno
|
||||
*/
|
||||
int unlinkat(int dirfd, const char *path, int flags) {
|
||||
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
|
||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_unlinkat(dirfd, path, flags);
|
||||
} else {
|
||||
|
|
|
@ -16,10 +16,12 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/sysv/consts/at.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
#define __NR_utimensat_linux 0x118 /*RHEL5:CVE-2010-3301*/
|
||||
|
||||
|
@ -27,6 +29,9 @@ int sys_utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
|||
int flags) {
|
||||
int rc, olderr;
|
||||
struct timeval tv[2];
|
||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
if (!IsXnu()) {
|
||||
olderr = errno;
|
||||
rc = __sys_utimensat(dirfd, path, ts, flags);
|
||||
|
|
|
@ -16,8 +16,13 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
#include "libc/zipos/zipos.internal.h"
|
||||
|
||||
/**
|
||||
* Sets atime/mtime on file, the modern way.
|
||||
|
@ -29,6 +34,13 @@
|
|||
*/
|
||||
int utimensat(int dirfd, const char *path, const struct timespec ts[2],
|
||||
int flags) {
|
||||
if (IsAsan() && (!__asan_is_valid(path, 1) ||
|
||||
(ts && !__asan_is_valid(ts, sizeof(struct timespec) * 2)))) {
|
||||
return efault();
|
||||
}
|
||||
if (weaken(__zipos_notat) && weaken(__zipos_notat)(dirfd, path) == -1) {
|
||||
return -1; /* TODO(jart): implement me */
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_utimensat(dirfd, path, ts, flags);
|
||||
} else {
|
||||
|
|
|
@ -37,15 +37,12 @@
|
|||
*/
|
||||
int wait4(int pid, int *opt_out_wstatus, int options,
|
||||
struct rusage *opt_out_rusage) {
|
||||
if (IsAsan()) {
|
||||
if (opt_out_wstatus &&
|
||||
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) {
|
||||
return efault();
|
||||
}
|
||||
if (opt_out_rusage &&
|
||||
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))) {
|
||||
return efault();
|
||||
}
|
||||
if (IsAsan() &&
|
||||
((opt_out_wstatus &&
|
||||
!__asan_is_valid(opt_out_wstatus, sizeof(*opt_out_wstatus))) ||
|
||||
(opt_out_rusage &&
|
||||
!__asan_is_valid(opt_out_rusage, sizeof(*opt_out_rusage))))) {
|
||||
return efault();
|
||||
}
|
||||
if (!IsWindows()) {
|
||||
return sys_wait4(pid, opt_out_wstatus, options, opt_out_rusage);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "libc/mem/mem.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
@ -100,6 +101,7 @@ int ResolveDns(const struct ResolvConf *resolvconf, int af, const char *name,
|
|||
a4 = (struct sockaddr_in *)addr;
|
||||
a4->sin_family = AF_INET;
|
||||
memcpy(&a4->sin_addr.s_addr, p + 10, 4);
|
||||
_firewall(a4, sizeof(struct sockaddr_in));
|
||||
break;
|
||||
}
|
||||
p += 10 + rdlength;
|
||||
|
|
944
libc/errno.h
944
libc/errno.h
|
@ -1,280 +1,690 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_ERRNO_H_
|
||||
#define COSMOPOLITAN_LIBC_ERRNO_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
/**
|
||||
* @fileoverview System error codes.
|
||||
* @see libc/sysv/consts.sh for numbers
|
||||
*/
|
||||
|
||||
#define EPERM EPERM /* operation not permitted */
|
||||
#define ENOENT ENOENT /* no such file or directory */
|
||||
#define ESRCH ESRCH /* no such process */
|
||||
#define EINTR EINTR /* interrupted system call */
|
||||
#define EIO EIO /* input/output error */
|
||||
#define ENXIO ENXIO /* no such device or address */
|
||||
#define E2BIG E2BIG /* argument list too long */
|
||||
#define ENOEXEC ENOEXEC /* exec format error */
|
||||
#define EBADF EBADF /* bad file descriptor */
|
||||
#define ECHILD ECHILD /* no child processes */
|
||||
#define EAGAIN EAGAIN /* resource temporarily unavailable */
|
||||
#define ENOMEM ENOMEM /* not enough space */
|
||||
#define EACCES EACCES /* permission denied */
|
||||
#define EFAULT EFAULT /* bad address */
|
||||
#define ENOTBLK ENOTBLK /* block device required */
|
||||
#define EBUSY EBUSY /* device or resource busy */
|
||||
#define EEXIST EEXIST /* file exists */
|
||||
#define EXDEV EXDEV /* improper link */
|
||||
#define ENODEV ENODEV /* no such device */
|
||||
#define ENOTDIR ENOTDIR /* not a directory */
|
||||
#define EISDIR EISDIR /* is a directory */
|
||||
#define EINVAL EINVAL /* invalid argument */
|
||||
#define ENFILE ENFILE /* too many open files in system */
|
||||
#define EMFILE EMFILE /* too many open files */
|
||||
#define ENOTTY ENOTTY /* inappropriate I/O control op */
|
||||
#define ETXTBSY ETXTBSY /* text file busy */
|
||||
#define EFBIG EFBIG /* file too large */
|
||||
#define ENOSPC ENOSPC /* no space left on device */
|
||||
#define ESPIPE ESPIPE /* invalid seek */
|
||||
#define EROFS EROFS /* read-only filesystem */
|
||||
#define EMLINK EMLINK /* too many links */
|
||||
#define EPIPE EPIPE /* broken pipe */
|
||||
#define EDOM EDOM /* argument out of function domain */
|
||||
#define ERANGE ERANGE /* result too large */
|
||||
#define EDEADLK EDEADLK /* resource deadlock avoided */
|
||||
#define ENAMETOOLONG ENAMETOOLONG /* filename too long */
|
||||
#define ENOLCK ENOLCK /* no locks available */
|
||||
#define ENOSYS ENOSYS /* system call not implemented */
|
||||
#define ENOTEMPTY ENOTEMPTY /* directory not empty */
|
||||
#define ELOOP ELOOP /* too many levels of symbolic links */
|
||||
#define ENOMSG ENOMSG /* no message of the desired type */
|
||||
#define EIDRM EIDRM /* identifier removed */
|
||||
#define ECHRNG ECHRNG /* channel number out of range */
|
||||
#define EL2NSYNC EL2NSYNC /* level 2 not synchronized */
|
||||
#define EL3HLT EL3HLT /* level 3 halted */
|
||||
#define EL3RST EL3RST /* level 3 halted */
|
||||
#define ELNRNG ELNRNG /* link number out of range */
|
||||
#define EUNATCH EUNATCH /* protocol driver not attached */
|
||||
#define ENOCSI ENOCSI /* no csi structure available */
|
||||
#define EL2HLT EL2HLT /* level 2 halted */
|
||||
#define EBADE EBADE /* invalid exchange */
|
||||
#define EBADR EBADR /* invalid request descriptor */
|
||||
#define EXFULL EXFULL /* exchange full */
|
||||
#define ENOANO ENOANO /* no anode */
|
||||
#define EBADRQC EBADRQC /* invalid request code */
|
||||
#define EBADSLT EBADSLT /* invalid slot */
|
||||
#define ENOSTR ENOSTR /* no string */
|
||||
#define ENODATA ENODATA /* no data */
|
||||
#define ETIME ETIME /* timer expired */
|
||||
#define ENOSR ENOSR /* out of streams resources */
|
||||
#define ENONET ENONET /* no network */
|
||||
#define ENOPKG ENOPKG /* package not installed */
|
||||
#define EREMOTE EREMOTE /* object is remote */
|
||||
#define ENOLINK ENOLINK /* link severed */
|
||||
#define EADV EADV /* todo */
|
||||
#define ESRMNT ESRMNT /* todo */
|
||||
#define ECOMM ECOMM /* communication error on send */
|
||||
#define EPROTO EPROTO /* protocol error */
|
||||
#define EMULTIHOP EMULTIHOP /* multihop attempted */
|
||||
#define EDOTDOT EDOTDOT /* todo */
|
||||
#define EBADMSG EBADMSG /* bad message */
|
||||
#define EOVERFLOW EOVERFLOW /* value too large for type */
|
||||
#define ENOTUNIQ ENOTUNIQ /* name not unique on network */
|
||||
#define EBADFD EBADFD /* fd in bad *state* (cf. EBADF) */
|
||||
#define EREMCHG EREMCHG /* remote address changed */
|
||||
#define ELIBACC ELIBACC /* cannot access dso */
|
||||
#define ELIBBAD ELIBBAD /* corrupted shared library */
|
||||
#define ELIBSCN ELIBSCN /* a.out section corrupted */
|
||||
#define ELIBMAX ELIBMAX /* too many shared libraries */
|
||||
#define ELIBEXEC ELIBEXEC /* cannot exec a dso directly */
|
||||
#define EILSEQ EILSEQ /* invalid wide character */
|
||||
#define ERESTART ERESTART /* please restart syscall */
|
||||
#define ESTRPIPE ESTRPIPE /* streams pipe error */
|
||||
#define EUSERS EUSERS /* too many users */
|
||||
#define ENOTSOCK ENOTSOCK /* not a socket */
|
||||
#define EDESTADDRREQ EDESTADDRREQ /* dest address needed */
|
||||
#define EMSGSIZE EMSGSIZE /* message too long */
|
||||
#define EPROTOTYPE EPROTOTYPE /* protocol wrong for socket */
|
||||
#define ENOPROTOOPT ENOPROTOOPT /* protocol not available */
|
||||
#define EPROTONOSUPPORT EPROTONOSUPPORT /* protocol not supported */
|
||||
#define ESOCKTNOSUPPORT ESOCKTNOSUPPORT /* socket type not supported */
|
||||
#define EOPNOTSUPP EOPNOTSUPP /* operation not supported on socket */
|
||||
#define EPFNOSUPPORT EPFNOSUPPORT /* protocol family not supported */
|
||||
#define EAFNOSUPPORT EAFNOSUPPORT /* address family not supported */
|
||||
#define EADDRINUSE EADDRINUSE /* address already in use */
|
||||
#define EADDRNOTAVAIL EADDRNOTAVAIL /* address not available */
|
||||
#define ENETDOWN ENETDOWN /* network is down */
|
||||
#define ENETUNREACH ENETUNREACH /* network unreachable */
|
||||
#define ENETRESET ENETRESET /* connection aborted by network */
|
||||
#define ECONNABORTED ECONNABORTED /* connection aborted */
|
||||
#define ECONNRESET ECONNRESET /* connection reset */
|
||||
#define ENOBUFS ENOBUFS /* no buffer space available */
|
||||
#define EISCONN EISCONN /* socket is connected */
|
||||
#define ENOTCONN ENOTCONN /* the socket is not connected */
|
||||
#define ESHUTDOWN ESHUTDOWN /* no send after endpoint shutdown */
|
||||
#define ETOOMANYREFS ETOOMANYREFS /* too many refs */
|
||||
#define ETIMEDOUT ETIMEDOUT /* connection timed out */
|
||||
#define ECONNREFUSED ECONNREFUSED /* connection refused */
|
||||
#define EHOSTDOWN EHOSTDOWN /* host is down */
|
||||
#define EHOSTUNREACH EHOSTUNREACH /* host is unreachable */
|
||||
#define EALREADY EALREADY /* connection already in progress */
|
||||
#define EINPROGRESS EINPROGRESS /* operation in progress */
|
||||
#define ESTALE ESTALE /* stale file handle */
|
||||
#define EUCLEAN EUCLEAN /* structure needs cleaning */
|
||||
#define ENOTNAM ENOTNAM /* todo */
|
||||
#define ENAVAIL ENAVAIL /* todo */
|
||||
#define EISNAM EISNAM /* is a named type file */
|
||||
#define EREMOTEIO EREMOTEIO /* remote i/o error */
|
||||
#define EDQUOT EDQUOT /* disk quota exceeded */
|
||||
#define ENOMEDIUM ENOMEDIUM /* no medium found */
|
||||
#define EMEDIUMTYPE EMEDIUMTYPE /* wrong medium type */
|
||||
#define ECANCELED ECANCELED /* operation canceled */
|
||||
#define ENOKEY ENOKEY /* required key not available */
|
||||
#define EKEYEXPIRED EKEYEXPIRED /* key has expired */
|
||||
#define EKEYREVOKED EKEYREVOKED /* key has been revoked */
|
||||
#define EKEYREJECTED EKEYREJECTED /* key was rejected by service */
|
||||
#define EOWNERDEAD EOWNERDEAD /* owner died */
|
||||
#define ENOTRECOVERABLE ENOTRECOVERABLE /* state not recoverable */
|
||||
#define ERFKILL ERFKILL /* can't op b/c RF-kill */
|
||||
#define EHWPOISON EHWPOISON /* mempage has h/w error */
|
||||
#define EWOULDBLOCK EAGAIN /* poll fd and try again */
|
||||
#define ENOTSUP ENOTSUP
|
||||
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
extern errno_t errno;
|
||||
|
||||
hidden extern const long EPERM;
|
||||
hidden extern const long ENOENT;
|
||||
hidden extern const long ESRCH;
|
||||
hidden extern const long EINTR;
|
||||
hidden extern const long EIO;
|
||||
hidden extern const long ENXIO;
|
||||
hidden extern const long E2BIG;
|
||||
hidden extern const long ENOEXEC;
|
||||
hidden extern const long EBADF;
|
||||
hidden extern const long ECHILD;
|
||||
hidden extern const long EAGAIN;
|
||||
hidden extern const long ENOMEM;
|
||||
hidden extern const long EACCES;
|
||||
hidden extern const long EFAULT;
|
||||
hidden extern const long ENOTBLK;
|
||||
hidden extern const long EBUSY;
|
||||
hidden extern const long EEXIST;
|
||||
hidden extern const long EXDEV;
|
||||
hidden extern const long ENODEV;
|
||||
hidden extern const long ENOTDIR;
|
||||
hidden extern const long EISDIR;
|
||||
hidden extern const long EINVAL;
|
||||
hidden extern const long ENFILE;
|
||||
hidden extern const long EMFILE;
|
||||
hidden extern const long ENOTTY;
|
||||
hidden extern const long ETXTBSY;
|
||||
hidden extern const long EFBIG;
|
||||
hidden extern const long ENOSPC;
|
||||
hidden extern const long ESPIPE;
|
||||
hidden extern const long EROFS;
|
||||
hidden extern const long EMLINK;
|
||||
hidden extern const long EPIPE;
|
||||
hidden extern const long EDOM;
|
||||
hidden extern const long ERANGE;
|
||||
hidden extern const long EDEADLK;
|
||||
hidden extern const long ENAMETOOLONG;
|
||||
hidden extern const long ENOLCK;
|
||||
hidden extern const long ENOSYS;
|
||||
hidden extern const long ENOTEMPTY;
|
||||
hidden extern const long ELOOP;
|
||||
hidden extern const long ENOMSG;
|
||||
hidden extern const long EIDRM;
|
||||
hidden extern const long ECHRNG;
|
||||
hidden extern const long EL2NSYNC;
|
||||
hidden extern const long EL3HLT;
|
||||
hidden extern const long EL3RST;
|
||||
hidden extern const long ELNRNG;
|
||||
hidden extern const long EUNATCH;
|
||||
hidden extern const long ENOCSI;
|
||||
hidden extern const long EL2HLT;
|
||||
hidden extern const long EBADE;
|
||||
hidden extern const long EBADR;
|
||||
hidden extern const long EXFULL;
|
||||
hidden extern const long ENOANO;
|
||||
hidden extern const long EBADRQC;
|
||||
hidden extern const long EBADSLT;
|
||||
hidden extern const long ENOSTR;
|
||||
hidden extern const long ENODATA;
|
||||
hidden extern const long ETIME;
|
||||
hidden extern const long ENOSR;
|
||||
hidden extern const long ENONET;
|
||||
hidden extern const long ENOPKG;
|
||||
hidden extern const long EREMOTE;
|
||||
hidden extern const long ENOLINK;
|
||||
hidden extern const long EADV;
|
||||
hidden extern const long ESRMNT;
|
||||
hidden extern const long ECOMM;
|
||||
hidden extern const long EPROTO;
|
||||
hidden extern const long EMULTIHOP;
|
||||
hidden extern const long EDOTDOT;
|
||||
hidden extern const long EBADMSG;
|
||||
hidden extern const long EOVERFLOW;
|
||||
hidden extern const long ENOTUNIQ;
|
||||
hidden extern const long EBADFD;
|
||||
hidden extern const long EREMCHG;
|
||||
hidden extern const long ELIBACC;
|
||||
hidden extern const long ELIBBAD;
|
||||
hidden extern const long ELIBSCN;
|
||||
hidden extern const long ELIBMAX;
|
||||
hidden extern const long ELIBEXEC;
|
||||
hidden extern const long EILSEQ;
|
||||
hidden extern const long ERESTART;
|
||||
hidden extern const long ESTRPIPE;
|
||||
hidden extern const long EUSERS;
|
||||
hidden extern const long ENOTSOCK;
|
||||
hidden extern const long EDESTADDRREQ;
|
||||
hidden extern const long EMSGSIZE;
|
||||
hidden extern const long EPROTOTYPE;
|
||||
hidden extern const long ENOPROTOOPT;
|
||||
hidden extern const long EPROTONOSUPPORT;
|
||||
hidden extern const long ESOCKTNOSUPPORT;
|
||||
hidden extern const long EOPNOTSUPP;
|
||||
hidden extern const long EPFNOSUPPORT;
|
||||
hidden extern const long EAFNOSUPPORT;
|
||||
hidden extern const long EADDRINUSE;
|
||||
hidden extern const long EADDRNOTAVAIL;
|
||||
hidden extern const long ENETDOWN;
|
||||
hidden extern const long ENETUNREACH;
|
||||
hidden extern const long ENETRESET;
|
||||
hidden extern const long ECONNABORTED;
|
||||
hidden extern const long ECONNRESET;
|
||||
hidden extern const long ENOBUFS;
|
||||
hidden extern const long EISCONN;
|
||||
hidden extern const long ENOTCONN;
|
||||
hidden extern const long ESHUTDOWN;
|
||||
hidden extern const long ETOOMANYREFS;
|
||||
hidden extern const long ETIMEDOUT;
|
||||
hidden extern const long ECONNREFUSED;
|
||||
hidden extern const long EHOSTDOWN;
|
||||
hidden extern const long EHOSTUNREACH;
|
||||
hidden extern const long EALREADY;
|
||||
hidden extern const long EINPROGRESS;
|
||||
hidden extern const long ESTALE;
|
||||
hidden extern const long EUCLEAN;
|
||||
hidden extern const long ENOTNAM;
|
||||
hidden extern const long ENAVAIL;
|
||||
hidden extern const long EISNAM;
|
||||
hidden extern const long EREMOTEIO;
|
||||
hidden extern const long EDQUOT;
|
||||
hidden extern const long ENOMEDIUM;
|
||||
hidden extern const long EMEDIUMTYPE;
|
||||
hidden extern const long ECANCELED;
|
||||
hidden extern const long ENOKEY;
|
||||
hidden extern const long EKEYEXPIRED;
|
||||
hidden extern const long EKEYREVOKED;
|
||||
hidden extern const long EKEYREJECTED;
|
||||
hidden extern const long EOWNERDEAD;
|
||||
hidden extern const long ENOTRECOVERABLE;
|
||||
hidden extern const long ERFKILL;
|
||||
hidden extern const long EHWPOISON;
|
||||
hidden extern const long ENOTSUP;
|
||||
/**
|
||||
* System call unavailable.
|
||||
* @note kNtErrorInvalidFunction on NT
|
||||
*/
|
||||
extern const long ENOSYS;
|
||||
|
||||
/**
|
||||
* Operation not permitted.
|
||||
* @note kNtErrorInvalidAccess on NT
|
||||
*/
|
||||
extern const long EPERM;
|
||||
|
||||
/**
|
||||
* No such file or directory.
|
||||
*/
|
||||
extern const long ENOENT;
|
||||
|
||||
/**
|
||||
* No such process.
|
||||
*/
|
||||
extern const long ESRCH;
|
||||
|
||||
/**
|
||||
* The greatest of all errnos.
|
||||
*/
|
||||
extern const long EINTR;
|
||||
|
||||
/**
|
||||
* Unix consensus.
|
||||
*/
|
||||
extern const long EIO;
|
||||
|
||||
/**
|
||||
* No such device or address.
|
||||
*/
|
||||
extern const long ENXIO;
|
||||
|
||||
/**
|
||||
* Argument list too long.
|
||||
*/
|
||||
extern const long E2BIG;
|
||||
|
||||
/**
|
||||
* Exec format error.
|
||||
*/
|
||||
extern const long ENOEXEC;
|
||||
|
||||
/**
|
||||
* Bad file descriptor.
|
||||
*/
|
||||
extern const long EBADF;
|
||||
|
||||
/**
|
||||
* No child process.
|
||||
*/
|
||||
extern const long ECHILD;
|
||||
|
||||
/**
|
||||
* Resource temporarily unavailable (e.g. SO_RCVTIMEO expired, too many
|
||||
* processes, too much memory locked, read or write with O_NONBLOCK needs
|
||||
* polling, etc.).
|
||||
*/
|
||||
extern const long EAGAIN;
|
||||
|
||||
/**
|
||||
* We require more vespene gas.
|
||||
*/
|
||||
extern const long ENOMEM;
|
||||
|
||||
/**
|
||||
* Permission denied.
|
||||
*/
|
||||
extern const long EACCES;
|
||||
|
||||
/**
|
||||
* Pointer passed to system call that would otherwise segfault.
|
||||
*/
|
||||
extern const long EFAULT;
|
||||
|
||||
/**
|
||||
* Block device required.
|
||||
*/
|
||||
extern const long ENOTBLK;
|
||||
|
||||
/**
|
||||
* Device or resource busy.
|
||||
*/
|
||||
extern const long EBUSY;
|
||||
|
||||
/**
|
||||
* File exists.
|
||||
*/
|
||||
extern const long EEXIST;
|
||||
|
||||
/**
|
||||
* Improper link.
|
||||
*/
|
||||
extern const long EXDEV;
|
||||
|
||||
/**
|
||||
* No such device.
|
||||
*/
|
||||
extern const long ENODEV;
|
||||
|
||||
/**
|
||||
* Not a directory.
|
||||
*/
|
||||
extern const long ENOTDIR;
|
||||
|
||||
/**
|
||||
* Is a a directory.
|
||||
*/
|
||||
extern const long EISDIR;
|
||||
|
||||
/**
|
||||
* Invalid argument.
|
||||
*/
|
||||
extern const long EINVAL;
|
||||
|
||||
/**
|
||||
* Too many open files in system.
|
||||
*/
|
||||
extern const long ENFILE;
|
||||
|
||||
/**
|
||||
* Too many open files.
|
||||
*/
|
||||
extern const long EMFILE;
|
||||
|
||||
/**
|
||||
* Inappropriate i/o control operation.
|
||||
*/
|
||||
extern const long ENOTTY;
|
||||
|
||||
/**
|
||||
* Won't open executable that's executing in write mode.
|
||||
*/
|
||||
extern const long ETXTBSY;
|
||||
|
||||
/**
|
||||
* File too large.
|
||||
*/
|
||||
extern const long EFBIG;
|
||||
|
||||
/**
|
||||
* No space left on device.
|
||||
*/
|
||||
extern const long ENOSPC;
|
||||
|
||||
/**
|
||||
* Disk quota exceeded.
|
||||
*/
|
||||
extern const long EDQUOT;
|
||||
|
||||
/**
|
||||
* Invalid seek.
|
||||
*/
|
||||
extern const long ESPIPE;
|
||||
|
||||
/**
|
||||
* Read-only filesystem.
|
||||
*/
|
||||
extern const long EROFS;
|
||||
|
||||
/**
|
||||
* Too many links.
|
||||
*/
|
||||
extern const long EMLINK;
|
||||
|
||||
/**
|
||||
* Broken pipe.
|
||||
*/
|
||||
extern const long EPIPE;
|
||||
|
||||
/**
|
||||
* Mathematics argument out of domain of function.
|
||||
*/
|
||||
extern const long EDOM;
|
||||
|
||||
/**
|
||||
* Result too large.
|
||||
*/
|
||||
extern const long ERANGE;
|
||||
|
||||
/**
|
||||
* Resource deadlock avoided.
|
||||
*/
|
||||
extern const long EDEADLK;
|
||||
|
||||
/**
|
||||
* Filename too long.
|
||||
*/
|
||||
extern const long ENAMETOOLONG;
|
||||
|
||||
/**
|
||||
* No locks available.
|
||||
*/
|
||||
extern const long ENOLCK;
|
||||
|
||||
/**
|
||||
* Directory not empty.
|
||||
*/
|
||||
extern const long ENOTEMPTY;
|
||||
|
||||
/**
|
||||
* Too many levels of symbolic links.
|
||||
*/
|
||||
extern const long ELOOP;
|
||||
|
||||
/**
|
||||
* No message error.
|
||||
*/
|
||||
extern const long ENOMSG;
|
||||
|
||||
/**
|
||||
* Identifier removed.
|
||||
*/
|
||||
extern const long EIDRM;
|
||||
|
||||
/**
|
||||
* Timer expired.
|
||||
*/
|
||||
extern const long ETIME;
|
||||
|
||||
/**
|
||||
* Protocol error.
|
||||
*/
|
||||
extern const long EPROTO;
|
||||
|
||||
/**
|
||||
* Overflow error.
|
||||
*/
|
||||
extern const long EOVERFLOW;
|
||||
|
||||
/**
|
||||
* Unicode decoding error.
|
||||
*/
|
||||
extern const long EILSEQ;
|
||||
|
||||
/**
|
||||
* Too many users.
|
||||
*/
|
||||
extern const long EUSERS;
|
||||
|
||||
/**
|
||||
* Not a socket.
|
||||
*/
|
||||
extern const long ENOTSOCK;
|
||||
|
||||
/**
|
||||
* Destination address required.
|
||||
*/
|
||||
extern const long EDESTADDRREQ;
|
||||
|
||||
/**
|
||||
* Message too long.
|
||||
*/
|
||||
extern const long EMSGSIZE;
|
||||
|
||||
/**
|
||||
* Protocol wrong type for socket.
|
||||
*/
|
||||
extern const long EPROTOTYPE;
|
||||
|
||||
/**
|
||||
* Protocol not available.
|
||||
*/
|
||||
extern const long ENOPROTOOPT;
|
||||
|
||||
/**
|
||||
* Protocol not supported.
|
||||
*/
|
||||
extern const long EPROTONOSUPPORT;
|
||||
|
||||
/**
|
||||
* Socket type not supported.
|
||||
*/
|
||||
extern const long ESOCKTNOSUPPORT;
|
||||
|
||||
/**
|
||||
* Operation not supported.
|
||||
*/
|
||||
extern const long ENOTSUP;
|
||||
|
||||
/**
|
||||
* Socket operation not supported.
|
||||
*/
|
||||
extern const long EOPNOTSUPP;
|
||||
|
||||
/**
|
||||
* Protocol family not supported.
|
||||
*/
|
||||
extern const long EPFNOSUPPORT;
|
||||
|
||||
/**
|
||||
* Address family not supported.
|
||||
*/
|
||||
extern const long EAFNOSUPPORT;
|
||||
|
||||
/**
|
||||
* Address already in use.
|
||||
*/
|
||||
extern const long EADDRINUSE;
|
||||
|
||||
/**
|
||||
* Address not available.
|
||||
*/
|
||||
extern const long EADDRNOTAVAIL;
|
||||
|
||||
/**
|
||||
* Network is down.
|
||||
*/
|
||||
extern const long ENETDOWN;
|
||||
|
||||
/**
|
||||
* Host is unreachable.
|
||||
*/
|
||||
extern const long ENETUNREACH;
|
||||
|
||||
/**
|
||||
* Connection reset by network.
|
||||
*/
|
||||
extern const long ENETRESET;
|
||||
|
||||
/**
|
||||
* Connection reset before accept.
|
||||
*/
|
||||
extern const long ECONNABORTED;
|
||||
|
||||
/**
|
||||
* Connection reset by client.
|
||||
*/
|
||||
extern const long ECONNRESET;
|
||||
|
||||
/**
|
||||
* No buffer space available.
|
||||
*/
|
||||
extern const long ENOBUFS;
|
||||
|
||||
/**
|
||||
* Socket is connected.
|
||||
*/
|
||||
extern const long EISCONN;
|
||||
|
||||
/**
|
||||
* Socket is not connected.
|
||||
*/
|
||||
extern const long ENOTCONN;
|
||||
|
||||
/**
|
||||
* Cannot send after transport endpoint shutdown.
|
||||
*/
|
||||
extern const long ESHUTDOWN;
|
||||
|
||||
/**
|
||||
* Too many references: cannot splice.
|
||||
*/
|
||||
extern const long ETOOMANYREFS;
|
||||
|
||||
/**
|
||||
* Connection timed out.
|
||||
*/
|
||||
extern const long ETIMEDOUT;
|
||||
|
||||
/**
|
||||
* Connection refused error.
|
||||
*/
|
||||
extern const long ECONNREFUSED;
|
||||
|
||||
/**
|
||||
* Host down error.
|
||||
*/
|
||||
extern const long EHOSTDOWN;
|
||||
|
||||
/**
|
||||
* Host unreachable error.
|
||||
*/
|
||||
extern const long EHOSTUNREACH;
|
||||
|
||||
/**
|
||||
* Connection already in progress.
|
||||
*/
|
||||
extern const long EALREADY;
|
||||
|
||||
/**
|
||||
* Operation already in progress.
|
||||
*/
|
||||
extern const long EINPROGRESS;
|
||||
|
||||
/**
|
||||
* Stale error.
|
||||
*/
|
||||
extern const long ESTALE;
|
||||
|
||||
/**
|
||||
* Remote error.
|
||||
*/
|
||||
extern const long EREMOTE;
|
||||
|
||||
/**
|
||||
* Bad message.
|
||||
*/
|
||||
extern const long EBADMSG;
|
||||
|
||||
/**
|
||||
* Operation canceled.
|
||||
*/
|
||||
extern const long ECANCELED;
|
||||
|
||||
/**
|
||||
* Owner died.
|
||||
*/
|
||||
extern const long EOWNERDEAD;
|
||||
|
||||
/**
|
||||
* State not recoverable.
|
||||
*/
|
||||
extern const long ENOTRECOVERABLE;
|
||||
|
||||
/**
|
||||
* No network.
|
||||
*/
|
||||
extern const long ENONET;
|
||||
|
||||
/**
|
||||
* Please restart syscall.
|
||||
*/
|
||||
extern const long ERESTART;
|
||||
|
||||
/**
|
||||
* Out of streams resources.
|
||||
*/
|
||||
extern const long ENOSR;
|
||||
|
||||
/**
|
||||
* No string.
|
||||
*/
|
||||
extern const long ENOSTR;
|
||||
|
||||
/**
|
||||
* No data.
|
||||
*/
|
||||
extern const long ENODATA;
|
||||
|
||||
/**
|
||||
* Multihop attempted.
|
||||
*/
|
||||
extern const long EMULTIHOP;
|
||||
|
||||
/**
|
||||
* Link severed.
|
||||
*/
|
||||
extern const long ENOLINK;
|
||||
|
||||
/**
|
||||
* No medium found.
|
||||
*/
|
||||
extern const long ENOMEDIUM;
|
||||
|
||||
/**
|
||||
* Wrong medium type.
|
||||
*/
|
||||
extern const long EMEDIUMTYPE;
|
||||
|
||||
/**
|
||||
* Inappropriate file type or format. (BSD only)
|
||||
*/
|
||||
extern const long EFTYPE;
|
||||
|
||||
extern const long EAUTH;
|
||||
extern const long EBADARCH;
|
||||
extern const long EBADEXEC;
|
||||
extern const long EBADMACHO;
|
||||
extern const long EBADRPC;
|
||||
extern const long EDEVERR;
|
||||
extern const long ENEEDAUTH;
|
||||
extern const long ENOATTR;
|
||||
extern const long ENOPOLICY;
|
||||
extern const long EPROCLIM;
|
||||
extern const long EPROCUNAVAIL;
|
||||
extern const long EPROGMISMATCH;
|
||||
extern const long EPROGUNAVAIL;
|
||||
extern const long EPWROFF;
|
||||
extern const long ERPCMISMATCH;
|
||||
extern const long ESHLIBVERS;
|
||||
|
||||
extern const long EADV;
|
||||
extern const long EBADE;
|
||||
extern const long EBADFD;
|
||||
extern const long EBADR;
|
||||
extern const long EBADRQC;
|
||||
extern const long EBADSLT;
|
||||
extern const long ECHRNG;
|
||||
extern const long ECOMM;
|
||||
extern const long EDOTDOT;
|
||||
extern const long EHWPOISON;
|
||||
extern const long EISNAM;
|
||||
extern const long EKEYEXPIRED;
|
||||
extern const long EKEYREJECTED;
|
||||
extern const long EKEYREVOKED;
|
||||
extern const long EL2HLT;
|
||||
extern const long EL2NSYNC;
|
||||
extern const long EL3HLT;
|
||||
extern const long EL3RST;
|
||||
extern const long ELIBACC;
|
||||
extern const long ELIBBAD;
|
||||
extern const long ELIBEXEC;
|
||||
extern const long ELIBMAX;
|
||||
extern const long ELIBSCN;
|
||||
extern const long ELNRNG;
|
||||
extern const long ENAVAIL;
|
||||
extern const long ENOANO;
|
||||
extern const long ENOCSI;
|
||||
extern const long ENOKEY;
|
||||
extern const long ENOPKG;
|
||||
extern const long ENOTNAM;
|
||||
extern const long ENOTUNIQ;
|
||||
extern const long EREMCHG;
|
||||
extern const long EREMOTEIO;
|
||||
extern const long ERFKILL;
|
||||
extern const long ESRMNT;
|
||||
extern const long ESTRPIPE;
|
||||
extern const long EUCLEAN;
|
||||
extern const long EUNATCH;
|
||||
extern const long EXFULL;
|
||||
|
||||
#define E2BIG E2BIG
|
||||
#define EACCES EACCES
|
||||
#define EADDRINUSE EADDRINUSE
|
||||
#define EADDRNOTAVAIL EADDRNOTAVAIL
|
||||
#define EADV EADV
|
||||
#define EAFNOSUPPORT EAFNOSUPPORT
|
||||
#define EAGAIN EAGAIN
|
||||
#define EALREADY EALREADY
|
||||
#define EAUTH EAUTH
|
||||
#define EBADARCH EBADARCH
|
||||
#define EBADE EBADE
|
||||
#define EBADEXEC EBADEXEC
|
||||
#define EBADF EBADF
|
||||
#define EBADFD EBADFD
|
||||
#define EBADMACHO EBADMACHO
|
||||
#define EBADMSG EBADMSG
|
||||
#define EBADR EBADR
|
||||
#define EBADRPC EBADRPC
|
||||
#define EBADRQC EBADRQC
|
||||
#define EBADSLT EBADSLT
|
||||
#define EBUSY EBUSY
|
||||
#define ECANCELED ECANCELED
|
||||
#define ECHILD ECHILD
|
||||
#define ECHRNG ECHRNG
|
||||
#define ECOMM ECOMM
|
||||
#define ECONNABORTED ECONNABORTED
|
||||
#define ECONNREFUSED ECONNREFUSED
|
||||
#define ECONNRESET ECONNRESET
|
||||
#define EDEADLK EDEADLK
|
||||
#define EDESTADDRREQ EDESTADDRREQ
|
||||
#define EDEVERR EDEVERR
|
||||
#define EDOM EDOM
|
||||
#define EDOTDOT EDOTDOT
|
||||
#define EDQUOT EDQUOT
|
||||
#define EEXIST EEXIST
|
||||
#define EFAULT EFAULT
|
||||
#define EFBIG EFBIG
|
||||
#define EFTYPE EFTYPE
|
||||
#define EHOSTDOWN EHOSTDOWN
|
||||
#define EHOSTUNREACH EHOSTUNREACH
|
||||
#define EHWPOISON EHWPOISON
|
||||
#define EIDRM EIDRM
|
||||
#define EILSEQ EILSEQ
|
||||
#define EINPROGRESS EINPROGRESS
|
||||
#define EINTR EINTR
|
||||
#define EINVAL EINVAL
|
||||
#define EIO EIO
|
||||
#define EISCONN EISCONN
|
||||
#define EISDIR EISDIR
|
||||
#define EISNAM EISNAM
|
||||
#define EKEYEXPIRED EKEYEXPIRED
|
||||
#define EKEYREJECTED EKEYREJECTED
|
||||
#define EKEYREVOKED EKEYREVOKED
|
||||
#define EL2HLT EL2HLT
|
||||
#define EL2NSYNC EL2NSYNC
|
||||
#define EL3HLT EL3HLT
|
||||
#define EL3RST EL3RST
|
||||
#define ELIBACC ELIBACC
|
||||
#define ELIBBAD ELIBBAD
|
||||
#define ELIBEXEC ELIBEXEC
|
||||
#define ELIBMAX ELIBMAX
|
||||
#define ELIBSCN ELIBSCN
|
||||
#define ELNRNG ELNRNG
|
||||
#define ELOOP ELOOP
|
||||
#define EMEDIUMTYPE EMEDIUMTYPE
|
||||
#define EMFILE EMFILE
|
||||
#define EMLINK EMLINK
|
||||
#define EMSGSIZE EMSGSIZE
|
||||
#define EMULTIHOP EMULTIHOP
|
||||
#define ENAMETOOLONG ENAMETOOLONG
|
||||
#define ENAVAIL ENAVAIL
|
||||
#define ENEEDAUTH ENEEDAUTH
|
||||
#define ENETDOWN ENETDOWN
|
||||
#define ENETRESET ENETRESET
|
||||
#define ENETUNREACH ENETUNREACH
|
||||
#define ENFILE ENFILE
|
||||
#define ENOANO ENOANO
|
||||
#define ENOATTR ENOATTR
|
||||
#define ENOBUFS ENOBUFS
|
||||
#define ENOCSI ENOCSI
|
||||
#define ENODATA ENODATA
|
||||
#define ENODEV ENODEV
|
||||
#define ENOENT ENOENT
|
||||
#define ENOEXEC ENOEXEC
|
||||
#define ENOKEY ENOKEY
|
||||
#define ENOLCK ENOLCK
|
||||
#define ENOLINK ENOLINK
|
||||
#define ENOMEDIUM ENOMEDIUM
|
||||
#define ENOMEM ENOMEM
|
||||
#define ENOMSG ENOMSG
|
||||
#define ENONET ENONET
|
||||
#define ENOPKG ENOPKG
|
||||
#define ENOPOLICY ENOPOLICY
|
||||
#define ENOPROTOOPT ENOPROTOOPT
|
||||
#define ENOSPC ENOSPC
|
||||
#define ENOSR ENOSR
|
||||
#define ENOSTR ENOSTR
|
||||
#define ENOSYS ENOSYS
|
||||
#define ENOTBLK ENOTBLK
|
||||
#define ENOTCONN ENOTCONN
|
||||
#define ENOTDIR ENOTDIR
|
||||
#define ENOTEMPTY ENOTEMPTY
|
||||
#define ENOTNAM ENOTNAM
|
||||
#define ENOTRECOVERABLE ENOTRECOVERABLE
|
||||
#define ENOTSOCK ENOTSOCK
|
||||
#define ENOTSUP ENOTSUP
|
||||
#define ENOTTY ENOTTY
|
||||
#define ENOTUNIQ ENOTUNIQ
|
||||
#define ENXIO ENXIO
|
||||
#define EOPNOTSUPP EOPNOTSUPP
|
||||
#define EOVERFLOW EOVERFLOW
|
||||
#define EOWNERDEAD EOWNERDEAD
|
||||
#define EPERM EPERM
|
||||
#define EPFNOSUPPORT EPFNOSUPPORT
|
||||
#define EPIPE EPIPE
|
||||
#define EPROCLIM EPROCLIM
|
||||
#define EPROCUNAVAIL EPROCUNAVAIL
|
||||
#define EPROGMISMATCH EPROGMISMATCH
|
||||
#define EPROGUNAVAIL EPROGUNAVAIL
|
||||
#define EPROTO EPROTO
|
||||
#define EPROTONOSUPPORT EPROTONOSUPPORT
|
||||
#define EPROTOTYPE EPROTOTYPE
|
||||
#define EPWROFF EPWROFF
|
||||
#define ERANGE ERANGE
|
||||
#define EREMCHG EREMCHG
|
||||
#define EREMOTE EREMOTE
|
||||
#define EREMOTEIO EREMOTEIO
|
||||
#define ERESTART ERESTART
|
||||
#define ERFKILL ERFKILL
|
||||
#define EROFS EROFS
|
||||
#define ERPCMISMATCH ERPCMISMATCH
|
||||
#define ESHLIBVERS ESHLIBVERS
|
||||
#define ESHUTDOWN ESHUTDOWN
|
||||
#define ESOCKTNOSUPPORT ESOCKTNOSUPPORT
|
||||
#define ESPIPE ESPIPE
|
||||
#define ESRCH ESRCH
|
||||
#define ESRMNT ESRMNT
|
||||
#define ESTALE ESTALE
|
||||
#define ESTRPIPE ESTRPIPE
|
||||
#define ETIME ETIME
|
||||
#define ETIMEDOUT ETIMEDOUT
|
||||
#define ETOOMANYREFS ETOOMANYREFS
|
||||
#define ETXTBSY ETXTBSY
|
||||
#define EUCLEAN EUCLEAN
|
||||
#define EUNATCH EUNATCH
|
||||
#define EUSERS EUSERS
|
||||
#define EWOULDBLOCK EAGAIN
|
||||
#define EXDEV EXDEV
|
||||
#define EXFULL EXFULL
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -48,7 +48,7 @@ struct timeval WindowsDurationToTimeVal(int64_t) nothrow;
|
|||
struct timespec WindowsDurationToTimeSpec(int64_t) nothrow;
|
||||
|
||||
static inline struct NtFileTime MakeFileTime(int64_t x) {
|
||||
return (struct NtFileTime){(uint32_t)x, x >> 32};
|
||||
return (struct NtFileTime){(uint32_t)x, (uint32_t)(x >> 32)};
|
||||
}
|
||||
|
||||
static inline int64_t ReadFileTime(struct NtFileTime t) {
|
||||
|
|
|
@ -348,35 +348,41 @@ void __asan_unpoison(uintptr_t p, size_t n) {
|
|||
bool __asan_is_valid(const void *p, size_t n) {
|
||||
signed char k, *s, *e;
|
||||
if (n) {
|
||||
k = (uintptr_t)p & 7;
|
||||
s = (signed char *)(((uintptr_t)p >> 3) + 0x7fff8000);
|
||||
if (UNLIKELY(k)) {
|
||||
if (n && !(!*s || *s >= k + n)) return false;
|
||||
++s, n -= MIN(8 - k, n);
|
||||
}
|
||||
e = s;
|
||||
k = n & 7;
|
||||
e += n >> 3;
|
||||
for (; s + 8 <= e; s += 8) {
|
||||
if ((uint64_t)(255 & s[0]) << 000 | (uint64_t)(255 & s[1]) << 010 |
|
||||
(uint64_t)(255 & s[2]) << 020 | (uint64_t)(255 & s[3]) << 030 |
|
||||
(uint64_t)(255 & s[4]) << 040 | (uint64_t)(255 & s[5]) << 050 |
|
||||
(uint64_t)(255 & s[6]) << 060 | (uint64_t)(255 & s[7]) << 070) {
|
||||
return false;
|
||||
if (p) {
|
||||
k = (uintptr_t)p & 7;
|
||||
s = (signed char *)(((uintptr_t)p >> 3) + 0x7fff8000);
|
||||
if (UNLIKELY(k)) {
|
||||
if (n && !(!*s || *s >= k + n)) return false;
|
||||
++s, n -= MIN(8 - k, n);
|
||||
}
|
||||
}
|
||||
while (s < e) {
|
||||
if (*s++) {
|
||||
return false;
|
||||
e = s;
|
||||
k = n & 7;
|
||||
e += n >> 3;
|
||||
for (; s + 8 <= e; s += 8) {
|
||||
if ((uint64_t)(255 & s[0]) << 000 | (uint64_t)(255 & s[1]) << 010 |
|
||||
(uint64_t)(255 & s[2]) << 020 | (uint64_t)(255 & s[3]) << 030 |
|
||||
(uint64_t)(255 & s[4]) << 040 | (uint64_t)(255 & s[5]) << 050 |
|
||||
(uint64_t)(255 & s[6]) << 060 | (uint64_t)(255 & s[7]) << 070) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (k) {
|
||||
if (!(!*s || *s >= k)) {
|
||||
return false;
|
||||
while (s < e) {
|
||||
if (*s++) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (k) {
|
||||
if (!(!*s || *s >= k)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool __asan_is_valid_iov(const struct iovec *iov, int iovlen) {
|
||||
|
|
|
@ -69,7 +69,7 @@ relegated void __check_fail(const char *suffix, const char *opstr,
|
|||
}
|
||||
|
||||
(dprintf)(STDERR_FILENO, "\t%s\n\t%s%s%s%s\n", strerror(lasterr), SUBTLE,
|
||||
getauxval(AT_EXECFN), __argc > 1 ? " \\" : "", RESET);
|
||||
program_invocation_name, __argc > 1 ? " \\" : "", RESET);
|
||||
|
||||
for (i = 1; i < __argc; ++i) {
|
||||
(dprintf)(STDERR_FILENO, "\t\t%s%s\n", __argv[i],
|
||||
|
|
|
@ -201,7 +201,7 @@ relegated static void ShowCrashReport(int err, int fd, int sig,
|
|||
" %s\n",
|
||||
RED2, RESET, TinyStrSignal(sig),
|
||||
si ? GetSiCodeName(sig, si->si_code) : "???", hostname,
|
||||
getauxval(AT_EXECFN), strerror(err));
|
||||
program_invocation_name, strerror(err));
|
||||
if (uname(&names) != -1) {
|
||||
dprintf(fd, " %s %s %s %s\n", names.sysname, names.nodename, names.release,
|
||||
names.version);
|
||||
|
|
|
@ -57,7 +57,6 @@ extern const unsigned char __oncrash_thunks[8][11];
|
|||
void ShowCrashReports(void) {
|
||||
size_t i;
|
||||
struct sigaction sa;
|
||||
FindDebugBinary();
|
||||
/* <SYNC-LIST>: showcrashreports.c, oncrashthunks.S, oncrash.c */
|
||||
kCrashSigs[0] = SIGQUIT; /* ctrl+\ aka ctrl+break */
|
||||
kCrashSigs[1] = SIGFPE; /* 1 / 0 */
|
||||
|
|
|
@ -68,9 +68,11 @@
|
|||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#define NAN __builtin_nanf("")
|
||||
#define INFINITY __builtin_inff()
|
||||
#define HUGE_VAL __builtin_inff()
|
||||
#define NAN __builtin_nanf("")
|
||||
#define INFINITY __builtin_inff()
|
||||
#define HUGE_VAL __builtin_inf()
|
||||
#define HUGE_VALF __builtin_inff()
|
||||
#define HUGE_VALL __builtin_infl()
|
||||
|
||||
#if __FLT_EVAL_METHOD__ + 0 == 2
|
||||
typedef long double float_t;
|
||||
|
|
|
@ -16,23 +16,23 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Returns current working directory.
|
||||
*
|
||||
* If the PWD environment variable is set, that'll be returned (since
|
||||
* it's faster than issuing a system call).
|
||||
* If the `PWD` environment variable is set, and it seems legit, then
|
||||
* that'll be returned.
|
||||
*
|
||||
* @return pointer that must be free()'d, or NULL w/ errno
|
||||
*/
|
||||
nodiscard char *get_current_dir_name(void) {
|
||||
char *buf, *res;
|
||||
if (!(buf = malloc(PATH_MAX))) return NULL;
|
||||
if (!(res = (getcwd)(buf, PATH_MAX))) free(buf);
|
||||
return res;
|
||||
const char *p;
|
||||
if ((p = getenv("PWD")) && _isabspath(p)) {
|
||||
return strdup(p);
|
||||
} else {
|
||||
return getcwd(0, 0);
|
||||
}
|
||||
}
|
|
@ -7,39 +7,39 @@
|
|||
* @see GetFileInformationByHandle()
|
||||
* @see libc/sysv/consts.sh
|
||||
*/
|
||||
#define kNtFileAttributeReadonly 0x00000001u
|
||||
#define kNtFileAttributeHidden 0x00000002u
|
||||
#define kNtFileAttributeSystem 0x00000004u
|
||||
#define kNtFileAttributeReadonly 0x00000001u
|
||||
#define kNtFileAttributeHidden 0x00000002u
|
||||
#define kNtFileAttributeSystem 0x00000004u
|
||||
#define kNtFileAttributeVolumelabel 0x00000008u
|
||||
#define kNtFileAttributeDirectory 0x00000010u
|
||||
#define kNtFileAttributeArchive 0x00000020u
|
||||
#define kNtFileAttributeDirectory 0x00000010u
|
||||
#define kNtFileAttributeArchive 0x00000020u
|
||||
|
||||
/**
|
||||
* NT File Attributes.
|
||||
*/
|
||||
#define kNtFileAttributeDevice 0x00000040u
|
||||
#define kNtFileAttributeNormal 0x00000080u
|
||||
#define kNtFileAttributeTemporary 0x00000100u
|
||||
#define kNtFileAttributeSparseFile 0x00000200u
|
||||
#define kNtFileAttributeReparsePoint 0x00000400u
|
||||
#define kNtFileAttributeCompressed 0x00000800u
|
||||
#define kNtFileAttributeOffline 0x00001000u
|
||||
#define kNtFileAttributeDevice 0x00000040u
|
||||
#define kNtFileAttributeNormal 0x00000080u
|
||||
#define kNtFileAttributeTemporary 0x00000100u
|
||||
#define kNtFileAttributeSparseFile 0x00000200u
|
||||
#define kNtFileAttributeReparsePoint 0x00000400u
|
||||
#define kNtFileAttributeCompressed 0x00000800u
|
||||
#define kNtFileAttributeOffline 0x00001000u
|
||||
#define kNtFileAttributeNotContentIndexed 0x00002000u
|
||||
#define kNtFileAttributeEncrypted 0x00004000u
|
||||
#define kNtFileAttributeEncrypted 0x00004000u
|
||||
|
||||
/**
|
||||
* NT File Flags.
|
||||
*/
|
||||
#define kNtFileFlagWriteThrough 0x80000000u
|
||||
#define kNtFileFlagOverlapped 0x40000000u
|
||||
#define kNtFileFlagNoBuffering 0x20000000u
|
||||
#define kNtFileFlagRandomAccess 0x10000000u
|
||||
#define kNtFileFlagSequentialScan 0x08000000u
|
||||
#define kNtFileFlagDeleteOnClose 0x04000000u
|
||||
#define kNtFileFlagBackupSemantics 0x02000000u
|
||||
#define kNtFileFlagPosixSemantics 0x01000000u
|
||||
#define kNtFileFlagOpenReparsePoint 0x00200000u /* or symlink */
|
||||
#define kNtFileFlagOpenNoRecall 0x00100000u
|
||||
#define kNtFileFlagWriteThrough 0x80000000u
|
||||
#define kNtFileFlagOverlapped 0x40000000u
|
||||
#define kNtFileFlagNoBuffering 0x20000000u
|
||||
#define kNtFileFlagRandomAccess 0x10000000u
|
||||
#define kNtFileFlagSequentialScan 0x08000000u
|
||||
#define kNtFileFlagDeleteOnClose 0x04000000u
|
||||
#define kNtFileFlagBackupSemantics 0x02000000u
|
||||
#define kNtFileFlagPosixSemantics 0x01000000u
|
||||
#define kNtFileFlagOpenReparsePoint 0x00200000u
|
||||
#define kNtFileFlagOpenNoRecall 0x00100000u
|
||||
#define kNtFileFlagFirstPipeInstance 0x00080000u
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_NT_ENUM_FILEFLAGANDATTRIBUTES_H_ */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue