Polish recent changes and make improvements

- Simulate SIGPIPE on Windows NT
- Fix commandv() regression on Windows NT
- Fix sigprocmask() strace bug on OpenBSD
- Add many more system calls to --strace logging
- Make errno state more pristine in redbean strace
This commit is contained in:
Justine Tunney 2022-03-19 03:37:00 -07:00
parent 10a766ebd0
commit 39688a73e4
69 changed files with 460 additions and 1976 deletions

View file

@ -39,6 +39,6 @@ int chdir(const char *path) {
} else {
rc = sys_chdir_nt(path);
}
STRACE("chdir(%#s) → %d% m", path, rc);
STRACE("%s(%#s) → %d% m", "chdir", path, rc);
return rc;
}

View file

@ -31,7 +31,16 @@
* This function may be used for file descriptors returned by socket,
* accept, epoll_create, and zipos file descriptors too.
*
* This function should never be called twice for the same file
* descriptor, regardless of whether or not an error happened. However
* that doesn't mean the error should be ignored.
*
* @return 0 on success, or -1 w/ errno
* @error EINTR means a signal was received while closing (possibly
* because linger is enabled) in which case close() does not need to
* be called again, since the fd will close in the background, and
* chances are that on linux, the fd is already closed, even if the
* underlying resource isn't closed yet
* @asyncsignalsafe
* @vforksafe
*/
@ -56,6 +65,7 @@ int close(int fd) {
g_fds.p[fd].kind == kFdProcess)) {
rc = sys_close_nt(g_fds.p + fd);
} else {
STRACE("close(%d) unknown kind: %d", fd, g_fds.p[fd].kind);
rc = ebadf();
}
}

View file

@ -146,8 +146,8 @@ noasan char *commandv(const char *name, char pathbuf[hasatleast PATH_MAX]) {
e = errno;
f = ENOENT;
if ((IsWindows() && (FindSuffixed(name, pathbuf, namelen, true, &f) ||
FindSuffixed(name, pathbuf, namelen, true, &f) ||
FindVerbatim(name, pathbuf, namelen, false, &f) ||
FindVerbatim(name, pathbuf, namelen, true, &f) ||
FindSuffixed(name, pathbuf, namelen, false, &f) ||
FindVerbatim(name, pathbuf, namelen, false, &f))) ||
(!IsWindows() && (FindVerbatim(name, pathbuf, namelen, true, &f) ||
FindSuffixed(name, pathbuf, namelen, true, &f) ||

View file

@ -33,11 +33,17 @@ static noasan char DescribeMapType(int flags) {
}
}
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
/* asan runtime depends on this function */
noasan char *DescribeProt(int prot, char p[hasatleast 4]) {
p[0] = (prot & PROT_READ) ? 'r' : '-';
p[1] = (prot & PROT_WRITE) ? 'w' : '-';
p[2] = (prot & PROT_EXEC) ? 'x' : '-';
p[3] = 0;
return p;
}
noasan char *DescribeMapping(int prot, int flags, char p[hasatleast 8]) {
/* asan runtime depends on this function */
DescribeProt(prot, p);
p[3] = DescribeMapType(flags);
p[4] = (flags & MAP_ANONYMOUS) ? 'a' : '-';
p[5] = (flags & MAP_GROWSDOWN) ? 'S' : '-';

View file

@ -33,6 +33,7 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
int prot, int flags,
int64_t handle, int64_t off) {
/* asan runtime depends on this function */
bool32 rc;
uint32_t got;
size_t i, upsize;
struct DirectMap dm;
@ -68,9 +69,11 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
if (i == size) {
return dm;
}
UnmapViewOfFile(dm.addr);
rc = UnmapViewOfFile(dm.addr);
STRACE("%s(addr:%p) → %hhhd% m", "UnmapViewOfFile", dm.maphandle, rc);
}
CloseHandle(dm.maphandle);
rc = CloseHandle(dm.maphandle);
STRACE("%s(%p) → %hhhd% m", "CloseHandle", dm.maphandle, rc);
}
} else {
dm.maphandle = CreateFileMappingNuma(
@ -91,7 +94,8 @@ textwindows noasan struct DirectMap sys_mmap_nt(void *addr, size_t size,
if (dm.addr) {
return dm;
} else {
CloseHandle(dm.maphandle);
rc = CloseHandle(dm.maphandle);
STRACE("%s(%p) → %d% m", "CloseHandle", dm.maphandle, rc);
}
}
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/consts/at.h"
@ -37,13 +38,17 @@
* @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);
int rc;
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (weaken(__zipos_notat) &&
weaken(__zipos_notat)(dirfd, path) == -1) {
rc = -1; /* TODO(jart): implement me */
} else if (!IsWindows()) {
rc = sys_faccessat(dirfd, path, mode, flags);
} else {
return sys_faccessat_nt(dirfd, path, mode, flags);
rc = sys_faccessat_nt(dirfd, path, mode, flags);
}
STRACE("faccessat(%d, %#s, %#o, %#x) → %d% m", dirfd, path, mode, flags, rc);
return rc;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/metastat.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
@ -49,8 +50,11 @@ bool fileexists(const char *path) {
struct ZiposUri zipname;
uint16_t path16[PATH_MAX];
e = errno;
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (weaken(__zipos_open) &&
weaken(__zipos_parseuri)(path, &zipname) != -1) {
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
res = true;
} else {
@ -69,7 +73,7 @@ bool fileexists(const char *path) {
} else {
res = false;
}
STRACE("fileexists(%#s) → %hhhd% m", path, res);
STRACE("%s(%#s) → %hhhd% m", "fileexists", path, res);
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
errno = e;
}

View file

@ -18,6 +18,7 @@
*/
#include "libc/bits/pushpop.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/nt/runtime.h"
#include "libc/sysv/consts/fileno.h"
@ -25,6 +26,13 @@ STATIC_YOINK("_init_g_fds");
hidden struct Fds g_fds;
static textwindows int64_t GetHandleNt(long a) {
int64_t b;
b = GetStdHandle(a);
STRACE("GetStdHandle(%ld) → %p% m", a, b);
return b;
}
hidden textstartup void InitializeFileDescriptors(void) {
struct Fds *fds;
fds = VEIL("r", &g_fds);
@ -44,10 +52,10 @@ hidden textstartup void InitializeFileDescriptors(void) {
fds->__init_p[STDOUT_FILENO].kind = pushpop(kFdFile);
fds->__init_p[STDERR_FILENO].kind = pushpop(kFdFile);
fds->__init_p[STDIN_FILENO].handle =
GetStdHandle(pushpop(kNtStdInputHandle));
GetHandleNt(pushpop(kNtStdInputHandle));
fds->__init_p[STDOUT_FILENO].handle =
GetStdHandle(pushpop(kNtStdOutputHandle));
GetHandleNt(pushpop(kNtStdOutputHandle));
fds->__init_p[STDERR_FILENO].handle =
GetStdHandle(pushpop(kNtStdErrorHandle));
GetHandleNt(pushpop(kNtStdErrorHandle));
}
}

View file

@ -299,7 +299,7 @@ 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_readlinkat_nt(int, const char *, char *, size_t) hidden;
ssize_t sys_write_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) hidden;
int ioctl_tiocgwinsz_nt(struct Fd *, struct winsize *) hidden;
/*───────────────────────────────────────────────────────────────────────────│─╗
@ -320,7 +320,7 @@ int sys_getsetpriority_nt(int, int, int, int (*)(int));
int64_t __winerr(void) nocallback privileged;
int64_t ntreturn(uint32_t);
ssize_t sys_readv_nt(struct Fd *, const struct iovec *, int) hidden;
ssize_t sys_writev_nt(struct Fd *, const struct iovec *, int) hidden;
ssize_t sys_writev_nt(int, const struct iovec *, int) hidden;
struct NtOverlapped *offset2overlap(int64_t, struct NtOverlapped *) hidden;
unsigned __wincrash_nt(struct NtExceptionPointers *);
void *GetProcAddressModule(const char *, const char *) hidden;

View file

@ -18,6 +18,7 @@
*/
#include "libc/calls/internal.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/errfuns.h"
@ -28,6 +29,7 @@
* @see ioctl(fd, FIOCLEX, 0) dispatches here
*/
int ioctl_fioclex(int fd, int req) {
int rc;
if (fd >= 0) {
if (IsWindows() || (fd < g_fds.n && g_fds.p[fd].kind == kFdZip)) {
if (__isfdopen(fd)) {
@ -36,14 +38,16 @@ int ioctl_fioclex(int fd, int req) {
} else {
g_fds.p[fd].flags &= ~O_CLOEXEC;
}
return 0;
rc = 0;
} else {
return ebadf();
rc = ebadf();
}
} else {
return sys_ioctl(fd, req);
rc = sys_ioctl(fd, req);
}
} else {
return einval();
rc = einval();
}
STRACE("%s(%d, %d) → %d% m", "ioctl_fioclex", fd, req, rc);
return rc;
}

View file

@ -21,6 +21,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/internal.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/strace.internal.h"
#include "libc/sock/internal.h"
#include "libc/sock/sock.h"
#include "libc/str/str.h"
@ -105,16 +106,19 @@ 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, ...) {
int rc;
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, ifc);
rc = ioctl_siocgifconf_sysv(fd, ifc);
} else {
return ioctl_siocgifconf_nt(fd, ifc);
rc = ioctl_siocgifconf_nt(fd, ifc);
}
STRACE("%s(%d) → %d% m", "ioctl_siocgifconf", fd, rc);
return rc;
}
int ioctl_siocgifaddr(int fd, ...) {

View file

@ -16,10 +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/calls/strace.internal.h"
#include "libc/calls/struct/termios.h"
#include "libc/calls/struct/winsize.h"
#include "libc/log/log.h"
#include "libc/nt/console.h"
#include "libc/nt/enum/startf.h"
#include "libc/nt/startupinfo.h"
@ -57,6 +60,7 @@ textwindows int ioctl_tiocgwinsz_nt(struct Fd *fd, struct winsize *ws) {
__winerr();
}
} else {
STRACE("%s() failed %m", "GetConsoleMode");
enotty();
}
} else {

View file

@ -18,6 +18,7 @@
*/
#include "libc/calls/internal.h"
#include "libc/calls/ioctl.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/winsize.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
@ -30,21 +31,25 @@
* @see ioctl(fd, TIOCGWINSZ, ws) dispatches here
*/
int ioctl_tiocgwinsz(int fd, ...) {
int rc;
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 (IsAsan() && !__asan_is_valid(ws, sizeof(*ws))) {
rc = efault();
} else if (fd >= 0) {
if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) {
return enotty();
rc = enotty();
} else if (!IsWindows()) {
return sys_ioctl(fd, TIOCGWINSZ, ws);
rc = sys_ioctl(fd, TIOCGWINSZ, ws);
} else {
return ioctl_tiocgwinsz_nt(g_fds.p + fd, ws);
rc = ioctl_tiocgwinsz_nt(g_fds.p + fd, ws);
}
} else {
return einval();
rc = einval();
}
STRACE("%s(%d) → %d% m", "ioctl_tiocgwinsz", fd, rc);
return rc;
}

View file

@ -39,7 +39,7 @@
* return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 &&
* S_ISDIR(st.st_mode);
*
* Except faster and with fewer dependencies.
* Except faster, with fewer dependencies, and less errno clobbering.
*
* @see isregularfile(), issymlink(), ischardev()
*/
@ -49,8 +49,11 @@ bool isdirectory(const char *path) {
union metastat st;
struct ZiposUri zipname;
e = errno;
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (weaken(__zipos_open) &&
weaken(__zipos_parseuri)(path, &zipname) != -1) {
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
res = S_ISDIR(st.cosmo.st_mode);
} else {
@ -59,7 +62,6 @@ bool isdirectory(const char *path) {
} else if (IsMetal()) {
res = false;
} else if (!IsWindows()) {
e = errno;
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
res = S_ISDIR(METASTAT(st, st_mode));
} else {
@ -68,7 +70,7 @@ bool isdirectory(const char *path) {
} else {
res = isdirectory_nt(path);
}
STRACE("isdirectory(%#s) → %hhhd% m", path, res);
STRACE("%s(%#s) → %hhhd% m", "isdirectory", path, res);
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
errno = e;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/metastat.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
@ -35,34 +36,40 @@
* return fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1 &&
* S_ISREG(st.st_mode);
*
* Except faster and with fewer dependencies.
* Except faster, with fewer dependencies, and less errno clobbering.
*
* @see isdirectory(), ischardev(), issymlink()
*/
bool isregularfile(const char *path) {
int e;
bool res;
union metastat st;
struct ZiposUri zipname;
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
e = errno;
e = errno;
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (weaken(__zipos_open) &&
weaken(__zipos_parseuri)(path, &zipname) != -1) {
if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) {
return S_ISREG(st.cosmo.st_mode);
res = !!S_ISREG(st.cosmo.st_mode);
} else {
errno = e;
return false;
res = false;
}
} else if (IsMetal()) {
return false;
res = false;
} else if (!IsWindows()) {
e = errno;
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
return S_ISREG(METASTAT(st, st_mode));
res = S_ISREG(METASTAT(st, st_mode));
} else {
errno = e;
return false;
res = false;
}
} else {
return isregularfile_nt(path);
res = isregularfile_nt(path);
}
STRACE("%s(%#s) → %hhhd% m", "isregularfile", path, res);
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
errno = e;
}
return res;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/metastat.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
@ -44,22 +45,30 @@
*/
bool issymlink(const char *path) {
int e;
bool res;
union metastat st;
struct ZiposUri zipname;
if (IsAsan() && !__asan_is_valid(path, 1)) return efault();
if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) {
return false;
e = errno;
if (IsAsan() && !__asan_is_valid(path, 1)) {
efault();
res = false;
} else if (weaken(__zipos_open) &&
weaken(__zipos_parseuri)(path, &zipname) != -1) {
res = false;
} else if (IsMetal()) {
return false;
res = false;
} else if (!IsWindows()) {
e = errno;
if (__sys_fstatat(AT_FDCWD, path, &st, AT_SYMLINK_NOFOLLOW) != -1) {
return S_ISLNK(METASTAT(st, st_mode));
res = S_ISLNK(METASTAT(st, st_mode));
} else {
errno = e;
return false;
res = false;
}
} else {
return issymlink_nt(path);
res = issymlink_nt(path);
}
STRACE("%s(%#s) → %hhhd% m", "issymlink", path, res);
if (!res && (errno == ENOENT || errno == ENOTDIR)) {
errno = e;
}
return res;
}

View file

@ -19,10 +19,12 @@
#define ShouldUseMsabiAttribute() 1
#include "libc/bits/bits.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/nt/memory.h"
#include "libc/nt/thunk/msabi.h"
#include "libc/runtime/memtrack.internal.h"
#include "libc/sysv/consts/nr.h"
/**
@ -32,10 +34,11 @@
* @return 0 on success, or -1 w/ errno
* @see mmap()
*/
noasan noubsan privileged int mprotect(void *addr, uint64_t len, int prot) {
noasan noubsan privileged int mprotect(void *addr, size_t len, int prot) {
bool cf;
int64_t rc;
uint32_t oldprot;
char protbuf[4];
if (!IsWindows()) {
asm volatile(CFLAG_ASM("clc\n\tsyscall")
: CFLAG_CONSTRAINT(cf), "=a"(rc)
@ -48,12 +51,14 @@ noasan noubsan privileged int mprotect(void *addr, uint64_t len, int prot) {
errno = -rc;
rc = -1;
}
return rc;
} else {
if (__imp_VirtualProtect(addr, len, __prot2nt(prot, 0), &oldprot)) {
return 0;
rc = 0;
} else {
return __winerr();
rc = __winerr();
}
}
STRACE("mprotect(%p, %'zu, %s[%#x]) → %d% m", addr, len,
DescribeProt(prot, protbuf), prot, rc);
return rc;
}

View file

@ -20,6 +20,7 @@
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/fmt/fmt.h"
#include "libc/mem/mem.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/securityimpersonationlevel.h"
@ -31,6 +32,7 @@
#include "libc/nt/struct/privilegeset.h"
#include "libc/nt/struct/securitydescriptor.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/internal.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/ok.h"
#include "libc/sysv/errfuns.h"
@ -104,7 +106,6 @@ TryAgain:
}
} else {
e = GetLastError();
STRACE("GetFileSecurity failed: %d %u", e, secsize);
if (!IsTiny() && e == kNtErrorInsufficientBuffer) {
if (!freeme && weaken(malloc) && (freeme = weaken(malloc)(secsize))) {
s = freeme;

View file

@ -19,6 +19,7 @@
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/calls/ntmagicpaths.internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/nt/createfile.h"
#include "libc/nt/enum/accessmask.h"
#include "libc/nt/enum/creationdisposition.h"
@ -63,14 +64,15 @@ static textwindows int64_t sys_open_nt_impl(int dirfd, const char *path,
kNtFileFlagBackupSemantics | kNtFileFlagPosixSemantics |
kNtFileAttributeTemporary)))),
0)) != -1) {
return handle;
} else if (GetLastError() == kNtErrorFileExists &&
((flags & O_CREAT) &&
(flags & O_TRUNC))) { /* TODO(jart): What was this? */
return eisdir();
handle = eisdir();
} else {
return __winerr();
handle = __winerr();
}
STRACE("CreateFile() → %ld% m", handle);
return handle;
}
static textwindows ssize_t sys_open_nt_console(int dirfd,

View file

@ -61,11 +61,15 @@
char program_executable_name[SIZE];
static textwindows bool GetNtExePath(char executable[SIZE]) {
bool32 rc;
uint64_t w;
wint_t x, y;
uint32_t i, j;
char16_t path16[PATH_MAX + 1];
if (!GetModuleFileName(0, path16, ARRAYLEN(path16))) return 0;
path16[0] = 0;
rc = GetModuleFileName(0, path16, ARRAYLEN(path16));
STRACE("GetModuleFileName(0, [%#hs]) → %hhhd", path16, rc);
if (!rc) return false;
for (i = j = 0; (x = path16[i++] & 0xffff);) {
if (!IsUcs2(x)) {
y = path16[i++] & 0xffff;

View file

@ -45,7 +45,7 @@ ssize_t pwrite(int fd, const void *buf, size_t size, int64_t offset) {
if (!IsWindows()) {
rc = sys_pwrite(fd, buf, size, offset, offset);
} else if (__isfdkind(fd, kFdFile)) {
rc = sys_write_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, offset);
rc = sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, offset);
} else {
return ebadf();
}

View file

@ -56,7 +56,7 @@ ssize_t pwritev(int fd, const struct iovec *iov, int iovlen, int64_t off) {
(struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, iov, iovlen, off);
} else if (IsWindows()) {
if (fd < g_fds.n) {
return sys_write_nt(g_fds.p + fd, iov, iovlen, off);
return sys_write_nt(fd, iov, iovlen, off);
} else {
return ebadf();
}

View file

@ -16,6 +16,7 @@
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/calls/strace.internal.h"
@ -23,6 +24,8 @@
#include "libc/dce.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/asan.internal.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
@ -55,6 +58,7 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
char howbuf[12];
char buf[2][41];
sigset_t old, *oldp;
const sigset_t *arg;
if (!(IsAsan() &&
((opt_set && !__asan_is_valid(opt_set, sizeof(*opt_set))) ||
(opt_out_oldset &&
@ -75,9 +79,14 @@ int sigprocmask(int how, const sigset_t *opt_set, sigset_t *opt_out_oldset) {
rc = -1;
}
} else if (IsOpenbsd()) {
if (!opt_set) how = 1;
if (opt_set) opt_set = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
if ((x = sys_sigprocmask(how, opt_set, 0, 0)) != -1) {
if (opt_set) {
/* openbsd only supports 32 signals so it passses them in a reg */
arg = (sigset_t *)(uintptr_t)(*(uint32_t *)opt_set);
} else {
how = 1; /* SIG_BLOCK */
arg = 0; /* changes nothing */
}
if ((x = sys_sigprocmask(how, arg, 0, 0)) != -1) {
if (opt_out_oldset) {
bzero(opt_out_oldset, sizeof(*opt_out_oldset));
memcpy(opt_out_oldset, &x, sizeof(x));

View file

@ -16,12 +16,16 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/assert.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/stat.h"
#include "libc/dce.h"
#include "libc/errno.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/intrin/kprintf.h"
#include "libc/log/log.h"
#include "libc/nt/console.h"
#include "libc/nt/enum/consolemodeflags.h"
@ -75,17 +79,20 @@ static int ttyname_linux(int fd, char *buf, size_t size) {
* Returns name of terminal, reentrantly.
*/
int ttyname_r(int fd, char *buf, size_t size) {
int rc;
if (IsLinux()) {
return ttyname_linux(fd, buf, size);
rc = ttyname_linux(fd, buf, size);
} else if (IsFreebsd()) {
return ttyname_freebsd(fd, buf, size);
rc = ttyname_freebsd(fd, buf, size);
} else if (IsWindows()) {
if (__isfdkind(fd, kFdFile)) {
return sys_ttyname_nt(fd, buf, size);
rc = sys_ttyname_nt(fd, buf, size);
} else {
return ebadf();
rc = ebadf();
}
} else {
return enosys();
rc = enosys();
}
STRACE("ttyname_r(%d, %s) → %d% m", fd, buf, rc);
return rc;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/consts/at.h"
@ -35,13 +36,16 @@
* @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);
int rc;
if (IsAsan() && !__asan_is_valid(path, 1)) {
rc = efault();
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
STRACE("zipos unlinkat not supported yet");
} else if (!IsWindows()) {
rc = sys_unlinkat(dirfd, path, flags);
} else {
return sys_unlinkat_nt(dirfd, path, flags);
rc = sys_unlinkat_nt(dirfd, path, flags);
}
STRACE("unlinkat(%d, %#s, %#b) → %d% m", dirfd, path, flags, rc);
return rc;
}

View file

@ -19,6 +19,7 @@
#include "libc/bits/weaken.h"
#include "libc/calls/calls.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/dce.h"
#include "libc/intrin/asan.internal.h"
#include "libc/sysv/errfuns.h"
@ -34,16 +35,23 @@
*/
int utimensat(int dirfd, const char *path, const struct timespec ts[2],
int flags) {
int rc;
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);
rc = efault();
} else if (weaken(__zipos_notat) && (rc = __zipos_notat(dirfd, path)) == -1) {
STRACE("zipos mkdirat not supported yet");
} else if (!IsWindows()) {
rc = sys_utimensat(dirfd, path, ts, flags);
} else {
return sys_utimensat_nt(dirfd, path, ts, flags);
rc = sys_utimensat_nt(dirfd, path, ts, flags);
}
if (ts) {
STRACE("utimensat(%d, %#s, {{%,ld, %,ld}, {%,ld, %,ld}}, %#b) → %d% m",
dirfd, path, ts[0].tv_sec, ts[0].tv_nsec, ts[1].tv_sec,
ts[1].tv_nsec, flags, rc);
} else {
STRACE("utimensat(%d, %#s, 0, %#b) → %d% m", dirfd, path, flags, rc);
}
return rc;
}

View file

@ -16,6 +16,7 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#define ShouldUseMsabiAttribute() 1
#include "libc/bits/weaken.h"
#include "libc/dce.h"
#include "libc/errno.h"
@ -30,16 +31,16 @@
* @return -1 w/ few exceptions
* @note this is a code-size saving device
*/
privileged noasan int64_t __winerr(void) {
privileged int64_t __winerr(void) {
errno_t e;
if (IsWindows()) {
e = GetLastError();
e = __imp_GetLastError();
if (weaken(__dos2errno)) {
e = weaken(__dos2errno)(e);
}
errno = e;
return -1;
} else {
return enosys();
e = ENOSYS;
}
errno = e;
return -1;
}

View file

@ -18,28 +18,47 @@
*/
#include "libc/assert.h"
#include "libc/calls/internal.h"
#include "libc/calls/strace.internal.h"
#include "libc/calls/struct/iovec.h"
#include "libc/calls/struct/siginfo.h"
#include "libc/calls/typedef/sigaction_f.h"
#include "libc/limits.h"
#include "libc/nt/errors.h"
#include "libc/nt/files.h"
#include "libc/nt/runtime.h"
#include "libc/nt/struct/overlapped.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/sysv/errfuns.h"
static textwindows ssize_t sys_write_nt_impl(struct Fd *fd, void *data,
size_t size, ssize_t offset) {
static textwindows ssize_t sys_write_nt_epipe(int fd) {
siginfo_t info;
STRACE("WriteFile(%d:%p) → %m", fd, g_fds.p[fd].handle);
if (!__sighandrvas[SIGPIPE]) {
_Exit(128 + SIGPIPE);
} else if (__sighandrvas[SIGPIPE] >= kSigactionMinRva) {
bzero(&info, sizeof(info));
((sigaction_f)(_base + __sighandrvas[SIGPIPE]))(SIGPIPE, &info, 0);
}
return epipe();
}
static textwindows ssize_t sys_write_nt_impl(int fd, void *data, size_t size,
ssize_t offset) {
uint32_t sent;
struct NtOverlapped overlap;
if (WriteFile(fd->handle, data, clampio(size), &sent,
if (WriteFile(g_fds.p[fd].handle, data, clampio(size), &sent,
offset2overlap(offset, &overlap))) {
/* TODO(jart): Trigger SIGPIPE on kNtErrorBrokenPipe */
return sent;
} else if (GetLastError() == kNtErrorBrokenPipe) {
return sys_write_nt_epipe(fd);
} else {
return __winerr();
}
}
textwindows ssize_t sys_write_nt(struct Fd *fd, const struct iovec *iov,
size_t iovlen, ssize_t opt_offset) {
textwindows ssize_t sys_write_nt(int fd, const struct iovec *iov, size_t iovlen,
ssize_t opt_offset) {
ssize_t rc;
size_t i, total;
uint32_t size, wrote;

View file

@ -50,7 +50,7 @@ ssize_t write(int fd, const void *buf, size_t size) {
} else if (IsMetal()) {
return sys_writev_metal(g_fds.p + fd, &(struct iovec){buf, size}, 1);
} else {
return sys_writev_nt(g_fds.p + fd, &(struct iovec){buf, size}, 1);
return sys_writev_nt(fd, &(struct iovec){buf, size}, 1);
}
} else {
return einval();

View file

@ -21,9 +21,8 @@
#include "libc/sock/internal.h"
#include "libc/sysv/errfuns.h"
textwindows ssize_t sys_writev_nt(struct Fd *fd, const struct iovec *iov,
int iovlen) {
switch (fd->kind) {
textwindows ssize_t sys_writev_nt(int fd, const struct iovec *iov, int iovlen) {
switch (g_fds.p[fd].kind) {
case kFdFile:
case kFdConsole:
return sys_write_nt(fd, iov, iovlen, -1);

View file

@ -47,7 +47,7 @@ ssize_t writev(int fd, const struct iovec *iov, int iovlen) {
} else if (IsMetal()) {
return sys_writev_metal(g_fds.p + fd, iov, iovlen);
} else {
return sys_writev_nt(g_fds.p + fd, iov, iovlen);
return sys_writev_nt(fd, iov, iovlen);
}
} else {
return einval();