mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
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:
parent
10a766ebd0
commit
39688a73e4
69 changed files with 460 additions and 1976 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) ||
|
||||
|
|
|
@ -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' : '-';
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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, ...) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
|
|
|
@ -29,12 +29,21 @@ extern const struct Dos2Errno kDos2Errno[];
|
|||
|
||||
/**
|
||||
* Translates Windows error using superset of consts.sh.
|
||||
*
|
||||
* This function is called by __winerr(). It can only be used on
|
||||
* Windows, because it returns an errno. Normally, errnos will be
|
||||
* programmed to be the same as DOS errnos, per consts.sh. But since
|
||||
* there's so many more errors in DOS, this function provides an added
|
||||
* optional benefit mapping additional constants onto the errnos in
|
||||
* consts.sh.
|
||||
*/
|
||||
privileged errno_t __dos2errno(uint32_t error) {
|
||||
int i;
|
||||
for (i = 0; kDos2Errno[i].doscode; ++i) {
|
||||
if (error == kDos2Errno[i].doscode) {
|
||||
return *(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv);
|
||||
if (error) {
|
||||
for (i = 0; kDos2Errno[i].doscode; ++i) {
|
||||
if (error == kDos2Errno[i].doscode) {
|
||||
return *(const int *)((intptr_t)kDos2Errno + kDos2Errno[i].systemv);
|
||||
}
|
||||
}
|
||||
}
|
||||
return error;
|
|
@ -16,8 +16,11 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
forceinline int Identity(int c) {
|
||||
|
|
|
@ -18,20 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/log/log.h"
|
||||
|
||||
static const char *__addr2line;
|
||||
|
||||
static textstartup void __addr2line_init() {
|
||||
static bool once;
|
||||
if (!once) {
|
||||
__addr2line = commandvenv("ADDR2LINE", "addr2line");
|
||||
once = true;
|
||||
}
|
||||
}
|
||||
|
||||
const char *GetAddr2linePath(void) {
|
||||
return __addr2line;
|
||||
return commandvenv("ADDR2LINE", "addr2line");
|
||||
}
|
||||
|
||||
const void *const __addr2line_ctor[] initarray = {
|
||||
__addr2line_init,
|
||||
};
|
||||
|
|
|
@ -76,13 +76,11 @@ static int PrintBacktraceUsingAddr2line(int fd, const struct StackFrame *bp) {
|
|||
}
|
||||
|
||||
/*
|
||||
* DWARF is a weak standard. If we build on Linux then only the
|
||||
* precice same version of the same tools on Linux can be counted upon
|
||||
* to work reliably. So if it's not Linux, we fall back to our builtin
|
||||
* tooling which can be counted upon.
|
||||
* DWARF is a weak standard. Platforms that use LLVM or old GNU
|
||||
* usually can't be counted upon to print backtraces correctly.
|
||||
*/
|
||||
if (!IsLinux()) {
|
||||
ShowHint("won't print addr2line backtrace on non-linux");
|
||||
if (!IsLinux() /* && !IsWindows() */) {
|
||||
ShowHint("won't print addr2line backtrace because probably llvm");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -242,6 +242,20 @@ forceinline char *__strstr(const char *haystack, const char *needle) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
forceinline char16_t *__strstr16(const char16_t *haystack,
|
||||
const char16_t *needle) {
|
||||
size_t i;
|
||||
for (;;) {
|
||||
for (i = 0;; ++i) {
|
||||
if (!needle[i]) return (/*unconst*/ char16_t *)haystack;
|
||||
if (!haystack[i]) break;
|
||||
if (needle[i] != haystack[i]) break;
|
||||
}
|
||||
if (!*haystack++) break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
forceinline char *__getenv(char **p, const char *s) {
|
||||
size_t i, j;
|
||||
if (p) {
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nexgen32e/kcpuids.h"
|
||||
|
@ -67,18 +68,21 @@ ssize_t getrandom(void *p, size_t n, unsigned f) {
|
|||
char cf;
|
||||
ssize_t rc;
|
||||
uint64_t x;
|
||||
size_t i, j, m;
|
||||
int fd, cmd[2];
|
||||
size_t i, j, m;
|
||||
const char *via;
|
||||
sigset_t neu, old;
|
||||
if (n > 256) n = 256;
|
||||
if ((f & ~(GRND_RANDOM | GRND_NONBLOCK))) return einval();
|
||||
if (IsWindows()) {
|
||||
via = "RtlGenRandom";
|
||||
if (RtlGenRandom(p, n)) {
|
||||
rc = n;
|
||||
} else {
|
||||
return __winerr();
|
||||
rc = __winerr();
|
||||
}
|
||||
} else if (IsFreebsd() || IsNetbsd()) {
|
||||
via = "KERN_ARND";
|
||||
if (IsFreebsd()) {
|
||||
cmd[0] = 1; /* CTL_KERN */
|
||||
cmd[1] = 37; /* KERN_ARND */
|
||||
|
@ -91,27 +95,34 @@ ssize_t getrandom(void *p, size_t n, unsigned f) {
|
|||
rc = m;
|
||||
}
|
||||
} else if (have_getrandom) {
|
||||
via = "getrandom";
|
||||
if ((rc = sys_getrandom(p, n, f & (GRND_RANDOM | GRND_NONBLOCK))) != -1) {
|
||||
if (!rc && (IsXnu() || IsOpenbsd())) {
|
||||
rc = n;
|
||||
}
|
||||
}
|
||||
} else if ((fd = __sys_openat(
|
||||
AT_FDCWD, (f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom",
|
||||
AT_FDCWD,
|
||||
(via = (f & GRND_RANDOM) ? "/dev/random" : "/dev/urandom"),
|
||||
O_RDONLY | ((f & GRND_NONBLOCK) ? O_NONBLOCK : 0), 0)) !=
|
||||
-1) {
|
||||
rc = sys_read(fd, p, n);
|
||||
sys_close(fd);
|
||||
} else {
|
||||
return enosys();
|
||||
rc = enosys();
|
||||
}
|
||||
STRACE("getrandom(%p, %'zu, %#x) via %s → %'ld% m", p, n, f, via, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static textstartup void getrandom_init(void) {
|
||||
if (sys_getrandom(0, 0, 0) == 0) {
|
||||
int e, rc;
|
||||
e = errno;
|
||||
if (!(rc = sys_getrandom(0, 0, 0))) {
|
||||
have_getrandom = true;
|
||||
}
|
||||
STRACE("sys_getrandom(0,0,0) → %d% m");
|
||||
errno = e;
|
||||
}
|
||||
|
||||
const void *const g_getrandom_init[] initarray = {getrandom_init};
|
||||
|
|
|
@ -46,6 +46,7 @@ extern hidden struct MemoryIntervals _mmi;
|
|||
|
||||
const char *DescribeFrame(int);
|
||||
void PrintSystemMappings(int) hidden;
|
||||
char *DescribeProt(int, char[hasatleast 4]);
|
||||
char *DescribeMapping(int, int, char[hasatleast 8]) hidden;
|
||||
bool AreMemoryIntervalsOk(const struct MemoryIntervals *) nosideeffect hidden;
|
||||
void PrintMemoryIntervals(int, const struct MemoryIntervals *) hidden;
|
||||
|
|
|
@ -109,7 +109,7 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
|||
dm = sys_mmap(addr, size, prot, f, fd, off);
|
||||
if (UNLIKELY(dm.addr == MAP_FAILED)) {
|
||||
if (IsWindows() && (flags & MAP_FIXED)) {
|
||||
STRACE("mmap(%.12p, %'ld) → %s (%s)", addr, size, strerror(errno),
|
||||
STRACE("mmap(%.12p, %'ld) → %m (%s)", addr, size,
|
||||
"can't recover from MAP_FIXED errors on Windows");
|
||||
assert(!"MapMemory() failed");
|
||||
Die();
|
||||
|
@ -123,14 +123,14 @@ static noasan void *MapMemory(void *addr, size_t size, int prot, int flags,
|
|||
}
|
||||
if (!IsWindows() && (flags & MAP_FIXED)) {
|
||||
if (UntrackMemoryIntervals(addr, size)) {
|
||||
STRACE("FIXED UNTRACK FAILED %s", strerror(errno));
|
||||
STRACE("FIXED UNTRACK FAILED %m");
|
||||
assert(!"MapMemory() failed");
|
||||
Die();
|
||||
}
|
||||
}
|
||||
if (TrackMemoryInterval(&_mmi, x, x + (n - 1), dm.maphandle, prot, flags)) {
|
||||
if (sys_munmap(addr, n) == -1) {
|
||||
STRACE("TRACK MUNMAP FAILED %s", strerror(errno));
|
||||
STRACE("TRACK MUNMAP FAILED %m");
|
||||
assert(!"MapMemory() failed");
|
||||
Die();
|
||||
}
|
||||
|
|
|
@ -187,7 +187,7 @@ RaiseEnobufs:
|
|||
RaiseEnoexec:
|
||||
errno = ENOEXEC;
|
||||
SystemError:
|
||||
STRACE("OpenSymbolTable() %m");
|
||||
STRACE("OpenSymbolTable()% m");
|
||||
if (map != MAP_FAILED) {
|
||||
munmap(map, st.st_size);
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "libc/calls/internal.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
|
@ -100,7 +101,9 @@ forceinline void MakeLongDoubleLongAgain(void) {
|
|||
asm volatile("fldcw\t%0" : /* no outputs */ : "m"(x87cw));
|
||||
}
|
||||
|
||||
static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
||||
static noasan textwindows wontreturn noinstrument void WinMainNew(
|
||||
const char16_t *cmdline) {
|
||||
bool32 rc;
|
||||
int64_t h;
|
||||
int version;
|
||||
int i, count;
|
||||
|
@ -112,13 +115,17 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
|||
version = NtGetPeb()->OSMajorVersion;
|
||||
__oldstack = (intptr_t)__builtin_frame_address(0);
|
||||
if ((intptr_t)v_ntsubsystem == kNtImageSubsystemWindowsCui && version >= 10) {
|
||||
SetConsoleCP(kNtCpUtf8);
|
||||
SetConsoleOutputCP(kNtCpUtf8);
|
||||
rc = SetConsoleCP(kNtCpUtf8);
|
||||
STRACE("SetConsoleCP(kNtCpUtf8) → %hhhd", rc);
|
||||
rc = SetConsoleOutputCP(kNtCpUtf8);
|
||||
STRACE("SetConsoleOutputCP(kNtCpUtf8) → %hhhd", rc);
|
||||
SetEnvironmentVariable(u"TERM", u"xterm-truecolor");
|
||||
for (i = 0; i < 2; ++i) {
|
||||
hand = GetStdHandle(kConsoleHandles[i]);
|
||||
GetConsoleMode(hand, __ntconsolemode + i);
|
||||
SetConsoleMode(hand, kConsoleModes[i]);
|
||||
rc = GetConsoleMode(hand, __ntconsolemode + i);
|
||||
STRACE("GetConsoleMode(%p, [%#x]) → %hhhd", hand, __ntconsolemode[i], rc);
|
||||
rc = SetConsoleMode(hand, kConsoleModes[i]);
|
||||
STRACE("SetConsoleMode(%p, %#x) → %hhhd", hand, kConsoleModes[i], rc);
|
||||
}
|
||||
}
|
||||
_mmi.p = _mmi.s;
|
||||
|
@ -128,7 +135,8 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
|||
stacksize = GetStackSize();
|
||||
allocsize = argsize + stacksize;
|
||||
allocaddr = stackaddr - argsize;
|
||||
STRACE("WinMainNew() mapping arg block / stack");
|
||||
STRACE("WinMainNew() mapping %'zu byte arg block + stack at %p", allocsize,
|
||||
allocaddr);
|
||||
MapViewOfFileExNuma(
|
||||
(_mmi.p[0].h = CreateFileMappingNuma(
|
||||
-1, &kNtIsInheritable, kNtPageExecuteReadwrite, allocsize >> 32,
|
||||
|
@ -142,8 +150,8 @@ static noasan textwindows wontreturn noinstrument void WinMainNew(void) {
|
|||
_mmi.i = 1;
|
||||
wa = (struct WinArgs *)allocaddr;
|
||||
STRACE("WinMainNew() loading arg block");
|
||||
count = GetDosArgv(GetCommandLine(), wa->argblock, ARRAYLEN(wa->argblock),
|
||||
wa->argv, ARRAYLEN(wa->argv));
|
||||
count = GetDosArgv(cmdline, wa->argblock, ARRAYLEN(wa->argblock), wa->argv,
|
||||
ARRAYLEN(wa->argv));
|
||||
for (i = 0; wa->argv[0][i]; ++i) {
|
||||
if (wa->argv[0][i] == '\\') {
|
||||
wa->argv[0][i] = '/';
|
||||
|
@ -197,15 +205,21 @@ noasan textwindows noinstrument int64_t WinMain(int64_t hInstance,
|
|||
int64_t hPrevInstance,
|
||||
const char *lpCmdLine,
|
||||
int nCmdShow) {
|
||||
const char16_t *cmdline;
|
||||
extern char os asm("__hostos");
|
||||
extern uint64_t ts asm("kStartTsc");
|
||||
os = WINDOWS; /* madness https://news.ycombinator.com/item?id=21019722 */
|
||||
ts = rdtsc();
|
||||
__nomultics = true;
|
||||
__pid = GetCurrentProcessId();
|
||||
cmdline = GetCommandLine();
|
||||
#ifdef SYSDEBUG
|
||||
/* sloppy flag-only check for early initialization */
|
||||
if (__strstr16(cmdline, u"--strace")) ++__strace;
|
||||
#endif
|
||||
STRACE("WinMain()");
|
||||
MakeLongDoubleLongAgain();
|
||||
if (weaken(WinSockInit)) weaken(WinSockInit)();
|
||||
if (weaken(WinMainForked)) weaken(WinMainForked)();
|
||||
WinMainNew();
|
||||
WinMainNew(cmdline);
|
||||
}
|
||||
|
|
|
@ -130,8 +130,8 @@ int sys_setsockopt_nt(struct Fd *, int, int, const void *, uint32_t) hidden;
|
|||
|
||||
size_t __iovec2nt(struct NtIovec[hasatleast 16], const struct iovec *,
|
||||
size_t) hidden;
|
||||
ssize_t sys_sendto_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
||||
void *, uint32_t) hidden;
|
||||
ssize_t sys_sendto_nt(int, const struct iovec *, size_t, uint32_t, void *,
|
||||
uint32_t) hidden;
|
||||
ssize_t sys_recvfrom_nt(struct Fd *, const struct iovec *, size_t, uint32_t,
|
||||
void *, uint32_t *) hidden;
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/winsock.h"
|
||||
|
@ -40,6 +41,7 @@ static textwindows void WinSockCleanup(void) {
|
|||
textwindows noasan void WinSockInit(void) {
|
||||
int rc;
|
||||
atexit(WinSockCleanup);
|
||||
STRACE("WSAStartup()");
|
||||
if ((rc = WSAStartup(VERSION, &kNtWsaData)) != 0 ||
|
||||
kNtWsaData.wVersion != VERSION) {
|
||||
ExitProcess(123);
|
||||
|
|
|
@ -58,10 +58,10 @@ ssize_t sendmsg(int fd, const struct msghdr *msg, int flags) {
|
|||
if (__isfdopen(fd)) {
|
||||
if (msg->msg_control) return einval(); /* control msg not supported */
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
return sys_sendto_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, flags,
|
||||
return sys_sendto_nt(fd, msg->msg_iov, msg->msg_iovlen, flags,
|
||||
msg->msg_name, msg->msg_namelen);
|
||||
} else if (__isfdkind(fd, kFdFile)) {
|
||||
return sys_write_nt(&g_fds.p[fd], msg->msg_iov, msg->msg_iovlen, -1);
|
||||
return sys_write_nt(fd, msg->msg_iov, msg->msg_iovlen, -1);
|
||||
} else {
|
||||
return enotsock();
|
||||
}
|
||||
|
|
|
@ -30,13 +30,13 @@
|
|||
* @param fd must be a socket
|
||||
* @return number of bytes handed off, or -1 w/ errno
|
||||
*/
|
||||
textwindows ssize_t sys_sendto_nt(struct Fd *fd, const struct iovec *iov,
|
||||
textwindows ssize_t sys_sendto_nt(int fd, const struct iovec *iov,
|
||||
size_t iovlen, uint32_t flags,
|
||||
void *opt_in_addr, uint32_t in_addrsize) {
|
||||
uint32_t sent;
|
||||
struct NtIovec iovnt[16];
|
||||
if (WSASendTo(fd->handle, iovnt, __iovec2nt(iovnt, iov, iovlen), &sent, flags,
|
||||
opt_in_addr, in_addrsize, NULL, NULL) != -1) {
|
||||
if (WSASendTo(g_fds.p[fd].handle, iovnt, __iovec2nt(iovnt, iov, iovlen),
|
||||
&sent, flags, opt_in_addr, in_addrsize, NULL, NULL) != -1) {
|
||||
return sent;
|
||||
} else {
|
||||
return __winsockerr();
|
||||
|
|
|
@ -67,12 +67,12 @@ ssize_t sendto(int fd, const void *buf, size_t size, uint32_t flags,
|
|||
} else {
|
||||
if (__isfdopen(fd)) {
|
||||
if (__isfdkind(fd, kFdSocket)) {
|
||||
return sys_sendto_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1,
|
||||
flags, opt_addr, addrsize);
|
||||
return sys_sendto_nt(fd, (struct iovec[]){{buf, size}}, 1, flags,
|
||||
opt_addr, addrsize);
|
||||
} else if (__isfdkind(fd, kFdFile)) { /* e.g. socketpair() */
|
||||
if (flags) return einval();
|
||||
if (opt_addr) return eisconn();
|
||||
return sys_write_nt(&g_fds.p[fd], (struct iovec[]){{buf, size}}, 1, -1);
|
||||
return sys_write_nt(fd, (struct iovec[]){{buf, size}}, 1, -1);
|
||||
} else {
|
||||
return enotsock();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,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/dirent.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
@ -234,7 +235,6 @@ DIR *opendir(const char *name) {
|
|||
struct Zipos *zip;
|
||||
struct ZiposUri zipname;
|
||||
if (weaken(__zipos_get) && weaken(__zipos_parseuri)(name, &zipname) != -1) {
|
||||
ZTRACE("__zipos_opendir(%`'s)", name);
|
||||
if (weaken(__zipos_stat)(&zipname, &st) != -1) {
|
||||
if (S_ISDIR(st.st_mode)) {
|
||||
zip = weaken(__zipos_get)();
|
||||
|
@ -250,25 +250,25 @@ DIR *opendir(const char *name) {
|
|||
}
|
||||
res->zip.prefix[zipname.len] = '\0';
|
||||
res->zip.prefixlen = zipname.len;
|
||||
return res;
|
||||
} else {
|
||||
errno = ENOTDIR;
|
||||
return 0;
|
||||
res = 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
res = 0;
|
||||
}
|
||||
} else if (!IsWindows()) {
|
||||
res = NULL;
|
||||
res = 0;
|
||||
if ((fd = open(name, O_RDONLY | O_DIRECTORY | O_CLOEXEC)) != -1) {
|
||||
if (!(res = fdopendir(fd))) {
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
} else {
|
||||
return opendir_nt(name);
|
||||
res = opendir_nt(name);
|
||||
}
|
||||
STRACE("opendir(%#s) → %p% m", name, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -284,10 +284,11 @@ DIR *fdopendir(int fd) {
|
|||
if (!IsWindows()) {
|
||||
if (!(dir = calloc(1, sizeof(*dir)))) return NULL;
|
||||
dir->fd = fd;
|
||||
return dir;
|
||||
} else {
|
||||
return fdopendir_nt(fd);
|
||||
dir = fdopendir_nt(fd);
|
||||
}
|
||||
STRACE("fdopendir(%d) → %p% m", fd, dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -403,6 +404,7 @@ int closedir(DIR *dir) {
|
|||
} else {
|
||||
rc = 0;
|
||||
}
|
||||
STRACE("closedir(%p) → %d% m", dir, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -410,6 +412,7 @@ int closedir(DIR *dir) {
|
|||
* Returns offset into directory data.
|
||||
*/
|
||||
long telldir(DIR *dir) {
|
||||
STRACE("telldir(%p) → %d", dir, dir->tell);
|
||||
return dir->tell;
|
||||
}
|
||||
|
||||
|
@ -417,9 +420,16 @@ long telldir(DIR *dir) {
|
|||
* Returns file descriptor associated with DIR object.
|
||||
*/
|
||||
int dirfd(DIR *dir) {
|
||||
if (dir->iszip) return eopnotsupp();
|
||||
if (IsWindows()) return eopnotsupp();
|
||||
return dir->fd;
|
||||
int rc;
|
||||
if (dir->iszip) {
|
||||
rc = eopnotsupp();
|
||||
} else if (IsWindows()) {
|
||||
rc = eopnotsupp();
|
||||
} else {
|
||||
rc = dir->fd;
|
||||
}
|
||||
STRACE("dirfd(%p) → %d% m", dir, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -443,4 +453,5 @@ void rewinddir(DIR *dir) {
|
|||
dir->isdone = true;
|
||||
}
|
||||
}
|
||||
STRACE("rewinddir(%p)", dir);
|
||||
}
|
||||
|
|
|
@ -56,9 +56,9 @@ textstartup int __fflush_register(FILE *f) {
|
|||
struct StdioFlush *sf;
|
||||
sf = &__fflush;
|
||||
if (!sf->handles.p) {
|
||||
sf->handles.p = &sf->handles_initmem[0];
|
||||
sf->handles.p = sf->handles_initmem;
|
||||
pushmov(&sf->handles.n, ARRAYLEN(sf->handles_initmem));
|
||||
__cxa_atexit(fflush, NULL, NULL);
|
||||
__cxa_atexit(fflush, 0, 0);
|
||||
}
|
||||
for (i = sf->handles.i; i; --i) {
|
||||
if (!sf->handles.p[i - 1]) {
|
||||
|
@ -76,7 +76,7 @@ void __fflush_unregister(FILE *f) {
|
|||
sf = pushpop(sf);
|
||||
for (i = sf->handles.i; i; --i) {
|
||||
if (sf->handles.p[i - 1] == f) {
|
||||
pushmov(&sf->handles.p[i - 1], NULL);
|
||||
pushmov(&sf->handles.p[i - 1], 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ FILE *popen(const char *cmdline, const char *mode) {
|
|||
if (pipe(pipefds) == -1) return NULL;
|
||||
fcntl(pipefds[dir], F_SETFD, FD_CLOEXEC);
|
||||
if ((f = fdopen(pipefds[dir], mode))) {
|
||||
switch ((pid = vfork())) {
|
||||
switch ((pid = fork())) {
|
||||
case 0:
|
||||
dup2(pipefds[!dir], !dir);
|
||||
systemexec(cmdline);
|
||||
|
|
|
@ -45,7 +45,7 @@ int posix_spawn(int *pid, const char *path,
|
|||
if (!(*pid = vfork())) {
|
||||
if (attrp) {
|
||||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETPGROUP) {
|
||||
if (setpgid(0, attrp->posix_attr_pgroup)) _exit(127);
|
||||
if (setpgid(0, attrp->posix_attr_pgroup)) _Exit(127);
|
||||
}
|
||||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSIGMASK) {
|
||||
sigprocmask(SIG_SETMASK, &attrp->posix_attr_sigmask, NULL);
|
||||
|
@ -60,7 +60,7 @@ int posix_spawn(int *pid, const char *path,
|
|||
sigfillset(&allsigs);
|
||||
for (s = 0; sigismember(&allsigs, s); s++) {
|
||||
if (sigismember(&attrp->posix_attr_sigdefault, s)) {
|
||||
if (sigaction(s, &dfl, NULL) == -1) _exit(127);
|
||||
if (sigaction(s, &dfl, NULL) == -1) _Exit(127);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,28 +68,28 @@ int posix_spawn(int *pid, const char *path,
|
|||
if (file_actions) {
|
||||
for (p = *file_actions; *p; p = strchr(p, ')') + 1) {
|
||||
if (!strncmp(p, "close(", 6)) {
|
||||
if (sscanf(p + 6, "%d)", &fd) != 1) _exit(127);
|
||||
if (close(fd) == -1) _exit(127);
|
||||
if (sscanf(p + 6, "%d)", &fd) != 1) _Exit(127);
|
||||
if (close(fd) == -1) _Exit(127);
|
||||
} else if (!strncmp(p, "dup2(", 5)) {
|
||||
if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) _exit(127);
|
||||
if (dup2(fd, newfd) == -1) _exit(127);
|
||||
if (sscanf(p + 5, "%d,%d)", &fd, &newfd) != 2) _Exit(127);
|
||||
if (dup2(fd, newfd) == -1) _Exit(127);
|
||||
} else if (!strncmp(p, "open(", 5)) {
|
||||
if (sscanf(p + 5, "%d,", &fd) != 1) _exit(127);
|
||||
if (sscanf(p + 5, "%d,", &fd) != 1) _Exit(127);
|
||||
p = strchr(p, ',') + 1;
|
||||
q = strchr(p, '*');
|
||||
if (!q || q - p + 1 > PATH_MAX) _exit(127);
|
||||
if (!q || q - p + 1 > PATH_MAX) _Exit(127);
|
||||
strncpy(opath, p, q - p);
|
||||
opath[q - p] = '\0';
|
||||
if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) _exit(127);
|
||||
if (close(fd) == -1 && errno != EBADF) _exit(127);
|
||||
if (sscanf(q + 1, "%o,%o)", &oflag, &mode) != 2) _Exit(127);
|
||||
if (close(fd) == -1 && errno != EBADF) _Exit(127);
|
||||
tempfd = open(opath, oflag, mode);
|
||||
if (tempfd == -1) _exit(127);
|
||||
if (tempfd == -1) _Exit(127);
|
||||
if (tempfd != fd) {
|
||||
if (dup2(tempfd, fd) == -1) _exit(127);
|
||||
if (close(tempfd) == -1) _exit(127);
|
||||
if (dup2(tempfd, fd) == -1) _Exit(127);
|
||||
if (close(tempfd) == -1) _Exit(127);
|
||||
}
|
||||
} else {
|
||||
_exit(127);
|
||||
_Exit(127);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -97,17 +97,17 @@ int posix_spawn(int *pid, const char *path,
|
|||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDULER) {
|
||||
if (sched_setscheduler(0, attrp->posix_attr_schedpolicy,
|
||||
&attrp->posix_attr_schedparam) == -1) {
|
||||
_exit(127);
|
||||
_Exit(127);
|
||||
}
|
||||
}
|
||||
if (attrp->posix_attr_flags & POSIX_SPAWN_SETSCHEDPARAM) {
|
||||
if (sched_setparam(0, &attrp->posix_attr_schedparam) == -1) {
|
||||
_exit(127);
|
||||
_Exit(127);
|
||||
}
|
||||
}
|
||||
}
|
||||
execve(path, argv, envp);
|
||||
_exit(127);
|
||||
_Exit(127);
|
||||
} else {
|
||||
if (*pid == -1) return errno;
|
||||
return 0;
|
||||
|
|
|
@ -29,19 +29,17 @@
|
|||
* @param fd is vetted by close()
|
||||
*/
|
||||
int __zipos_close(int fd) {
|
||||
int rc;
|
||||
struct ZiposHandle *h;
|
||||
h = (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle;
|
||||
ZTRACE("__zipos_close(%.*s)",
|
||||
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
|
||||
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile));
|
||||
if (!IsWindows()) {
|
||||
sys_close(fd);
|
||||
rc = sys_close(fd);
|
||||
} else {
|
||||
CloseHandle(h->handle);
|
||||
rc = 0; /* no system file descriptor needed on nt */
|
||||
}
|
||||
if (!__vforked) {
|
||||
free(h->freeme);
|
||||
free(h);
|
||||
}
|
||||
return 0;
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -28,30 +28,23 @@
|
|||
#define HANDLE ((struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle)
|
||||
|
||||
int __zipos_fcntl(int fd, int cmd, uintptr_t arg) {
|
||||
int rc;
|
||||
if (cmd == F_GETFD) {
|
||||
ZTRACE("__zipos_fcntl(%.*s, %s)",
|
||||
ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile),
|
||||
ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), "F_GETFD");
|
||||
if (g_fds.p[fd].flags & O_CLOEXEC) {
|
||||
return FD_CLOEXEC;
|
||||
rc = FD_CLOEXEC;
|
||||
} else {
|
||||
return 0;
|
||||
rc = 0;
|
||||
}
|
||||
} else if (cmd == F_SETFD) {
|
||||
ZTRACE("__zipos_fcntl(%.*s, %s, 0x%x)",
|
||||
ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile),
|
||||
ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), "F_SETFD", arg);
|
||||
if (arg & FD_CLOEXEC) {
|
||||
g_fds.p[fd].flags |= O_CLOEXEC;
|
||||
return FD_CLOEXEC;
|
||||
rc = FD_CLOEXEC;
|
||||
} else {
|
||||
g_fds.p[fd].flags &= ~O_CLOEXEC;
|
||||
return 0;
|
||||
rc = 0;
|
||||
}
|
||||
} else {
|
||||
ZTRACE("__zipos_fcntl(%.*s, %d, 0x%x) → EINVAL",
|
||||
ZIP_CFILE_NAMESIZE(ZIPOS->map + HANDLE->cfile),
|
||||
ZIP_CFILE_NAME(ZIPOS->map + HANDLE->cfile), cmd, arg);
|
||||
return einval();
|
||||
rc = einval();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -29,13 +29,10 @@
|
|||
*/
|
||||
int __zipos_fstat(const struct ZiposHandle *h, struct stat *st) {
|
||||
int rc;
|
||||
if (!st) return efault();
|
||||
if (!(rc = __zipos_stat_impl(__zipos_get(), h->cfile, st))) {
|
||||
ZTRACE("__zipos_fstat(%.*s) → %d",
|
||||
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
|
||||
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), st->st_size);
|
||||
return 0;
|
||||
if (st) {
|
||||
rc = __zipos_stat_impl(__zipos_get(), h->cfile, st);
|
||||
} else {
|
||||
return rc;
|
||||
rc = efault();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -19,10 +19,11 @@
|
|||
#include "libc/bits/safemacros.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/sigbits.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
@ -84,16 +85,10 @@ struct Zipos *__zipos_get(void) {
|
|||
zipos.cdir = cdir;
|
||||
} else {
|
||||
munmap(map, size);
|
||||
ZTRACE("__zipos_get(%s) → eocd not found", program_executable_name);
|
||||
STRACE("__zipos_get(%#s) → eocd not found", program_executable_name);
|
||||
}
|
||||
} else {
|
||||
ZTRACE("__zipos_get(%s) → stat/mmap %s", program_executable_name,
|
||||
strerror(errno));
|
||||
}
|
||||
close(fd);
|
||||
} else {
|
||||
ZTRACE("__zipos_get(%s) → open %s", program_executable_name,
|
||||
strerror(errno));
|
||||
}
|
||||
once = true;
|
||||
sigprocmask(SIG_SETMASK, &old, 0);
|
||||
|
|
|
@ -30,26 +30,25 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int64_t __zipos_lseek(struct ZiposHandle *h, int64_t offset, unsigned whence) {
|
||||
int64_t i;
|
||||
int64_t rc;
|
||||
switch (whence) {
|
||||
case SEEK_SET:
|
||||
i = offset;
|
||||
rc = offset;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
i = h->pos + offset;
|
||||
rc = h->pos + offset;
|
||||
break;
|
||||
case SEEK_END:
|
||||
i = h->size - offset;
|
||||
rc = h->size - offset;
|
||||
break;
|
||||
default:
|
||||
return einval();
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
if (i < 0) {
|
||||
return einval();
|
||||
if (rc >= 0) {
|
||||
h->pos = rc;
|
||||
} else {
|
||||
rc = einval();
|
||||
}
|
||||
h->pos = i;
|
||||
ZTRACE("__zipos_lseek(%.*s, %d)",
|
||||
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
|
||||
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), i);
|
||||
return i;
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ int __zipos_notat(int dirfd, const char *path) {
|
|||
struct ZiposUri zipname;
|
||||
if (!path) return efault();
|
||||
if (__isfdkind(dirfd, kFdZip) || __zipos_parseuri(path, &zipname) != -1) {
|
||||
ZTRACE("__zipos_notat(%d, %s) → EINVAL", dirfd, path);
|
||||
return einval();
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -124,7 +124,7 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
|
|||
h->mem = NULL;
|
||||
}
|
||||
if (h->mem) {
|
||||
if ((fd = dup(2)) != -1) {
|
||||
if ((fd = IsWindows() ? __reservefd() : dup(2)) != -1) {
|
||||
if (__ensurefds(fd) != -1) {
|
||||
h->handle = g_fds.p[fd].handle;
|
||||
g_fds.p[fd].kind = kFdZip;
|
||||
|
@ -147,22 +147,22 @@ static int __zipos_load(struct Zipos *zipos, size_t cf, unsigned flags,
|
|||
* @note don't call open() from signal handlers
|
||||
*/
|
||||
int __zipos_open(const struct ZiposUri *name, unsigned flags, int mode) {
|
||||
int fd;
|
||||
int rc;
|
||||
ssize_t cf;
|
||||
sigset_t oldmask;
|
||||
struct Zipos *zipos;
|
||||
if ((flags & O_ACCMODE) != O_RDONLY) return einval();
|
||||
if ((zipos = __zipos_get())) {
|
||||
if ((cf = __zipos_find(zipos, name)) != -1) {
|
||||
fd = __zipos_load(zipos, cf, flags, mode);
|
||||
ZTRACE("__zipos_open(%.*s)", name->len, name->path);
|
||||
if ((flags & O_ACCMODE) == O_RDONLY) {
|
||||
if ((zipos = __zipos_get())) {
|
||||
if ((cf = __zipos_find(zipos, name)) != -1) {
|
||||
rc = __zipos_load(zipos, cf, flags, mode);
|
||||
} else {
|
||||
rc = enoent();
|
||||
}
|
||||
} else {
|
||||
ZTRACE("__zipos_open(%.*s) enoent", name->len, name->path);
|
||||
fd = enoent();
|
||||
rc = enoexec();
|
||||
}
|
||||
} else {
|
||||
fd = enoexec();
|
||||
ZTRACE("__zipos_open(%.*s) enoexec", name->len, name->path);
|
||||
rc = einval();
|
||||
}
|
||||
return fd;
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -46,9 +46,5 @@ ssize_t __zipos_read(struct ZiposHandle *h, const struct iovec *iov,
|
|||
memcpy(iov[i].iov_base, h->mem + y, b);
|
||||
}
|
||||
if (opt_offset == -1) h->pos = y;
|
||||
ZTRACE("__zipos_read(%.*s, cap=%d, off=%d) -> %d",
|
||||
ZIP_CFILE_NAMESIZE(__zipos_get()->map + h->cfile),
|
||||
ZIP_CFILE_NAME(__zipos_get()->map + h->cfile), GetIovSize(iov, iovlen),
|
||||
x, y - x);
|
||||
return y - x;
|
||||
}
|
||||
|
|
|
@ -28,18 +28,21 @@
|
|||
* @asyncsignalsafe
|
||||
*/
|
||||
int __zipos_stat(const struct ZiposUri *name, struct stat *st) {
|
||||
int rc;
|
||||
ssize_t cf;
|
||||
struct Zipos *zipos;
|
||||
if (!st) return efault();
|
||||
if ((zipos = __zipos_get())) {
|
||||
if ((cf = __zipos_find(zipos, name)) != -1) {
|
||||
return __zipos_stat_impl(zipos, cf, st);
|
||||
if (st) {
|
||||
if ((zipos = __zipos_get())) {
|
||||
if ((cf = __zipos_find(zipos, name)) != -1) {
|
||||
rc = __zipos_stat_impl(zipos, cf, st);
|
||||
} else {
|
||||
rc = enoent();
|
||||
}
|
||||
} else {
|
||||
ZTRACE("__zipos_stat(%.*s) -> enoent", name->len, name->path);
|
||||
return enoent();
|
||||
rc = enoexec();
|
||||
}
|
||||
} else {
|
||||
ZTRACE("__zipos_stat(%.*s) → enoexec", name->len, name->path);
|
||||
return enoexec();
|
||||
rc = efault();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
|
||||
#define COSMOPOLITAN_LIBC_ZIPOS_ZIPOS_H_
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
#if DEBUGSYS
|
||||
#define ZTRACE(FMT, ...) kprintf("ZIP: " FMT "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define ZTRACE(FMT, ...) (void)0
|
||||
#endif
|
||||
|
||||
struct stat;
|
||||
struct iovec;
|
||||
|
||||
|
|
|
@ -17,12 +17,15 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/nt/errors.h"
|
||||
#include "libc/sock/internal.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(__dos2errno, test) {
|
||||
EXPECT_EQ(0, __dos2errno(0));
|
||||
EXPECT_EQ(EACCES, __dos2errno(kNtErrorSectorNotFound));
|
||||
EXPECT_EQ(EADDRNOTAVAIL, __dos2errno(kNtErrorInvalidNetname));
|
||||
}
|
13
third_party/make/lib/dup2.c
vendored
13
third_party/make/lib/dup2.c
vendored
|
@ -28,19 +28,6 @@
|
|||
|
||||
# if defined _WIN32 && ! defined __CYGWIN__
|
||||
|
||||
/* Get declarations of the native Windows API functions. */
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
|
||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
# include "msvc-inval.h"
|
||||
# endif
|
||||
|
||||
/* Get _get_osfhandle. */
|
||||
# if GNULIB_MSVC_NOTHROW
|
||||
# include "msvc-nothrow.h"
|
||||
# else
|
||||
# endif
|
||||
|
||||
# if HAVE_MSVC_INVALID_PARAMETER_HANDLER
|
||||
static int
|
||||
dup2_nothrow (int fd, int desired_fd)
|
||||
|
|
214
third_party/make/lib/getprogname.c
vendored
214
third_party/make/lib/getprogname.c
vendored
|
@ -1,4 +1,3 @@
|
|||
/* clang-format off */
|
||||
/* Program name management.
|
||||
Copyright (C) 2016-2020 Free Software Foundation, Inc.
|
||||
|
||||
|
@ -15,228 +14,17 @@
|
|||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* clang-format off */
|
||||
#include "third_party/make/src/config.h"
|
||||
|
||||
/* Specification. */
|
||||
#include "third_party/make/lib/getprogname.h"
|
||||
|
||||
|
||||
#ifdef _AIX
|
||||
#endif
|
||||
|
||||
#ifdef __MVS__
|
||||
# ifndef _OPEN_SYS
|
||||
# define _OPEN_SYS
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __hpux
|
||||
#endif
|
||||
|
||||
#ifdef __sgi
|
||||
#endif
|
||||
|
||||
#include "third_party/make/lib/dirname.h"
|
||||
|
||||
#ifndef HAVE_GETPROGNAME /* not Mac OS X, FreeBSD, NetBSD, OpenBSD >= 5.4, Cygwin */
|
||||
char const *
|
||||
getprogname (void)
|
||||
{
|
||||
# if HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME /* glibc, BeOS */
|
||||
/* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
|
||||
return program_invocation_short_name;
|
||||
# elif HAVE_DECL_PROGRAM_INVOCATION_NAME /* glibc, BeOS */
|
||||
/* https://www.gnu.org/software/libc/manual/html_node/Error-Messages.html */
|
||||
return last_component (program_invocation_name);
|
||||
# elif HAVE_GETEXECNAME /* Solaris */
|
||||
/* https://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrb1/index.html */
|
||||
const char *p = getexecname ();
|
||||
if (!p)
|
||||
p = "?";
|
||||
return last_component (p);
|
||||
# elif HAVE_DECL___ARGV /* mingw, MSVC */
|
||||
/* https://docs.microsoft.com/en-us/cpp/c-runtime-library/argc-argv-wargv */
|
||||
const char *p = __argv && __argv[0] ? __argv[0] : "?";
|
||||
return last_component (p);
|
||||
# elif HAVE_VAR___PROGNAME /* OpenBSD, Android, QNX */
|
||||
/* https://man.openbsd.org/style.9 */
|
||||
/* http://www.qnx.de/developers/docs/6.5.0/index.jsp?topic=%2Fcom.qnx.doc.neutrino_lib_ref%2Fp%2F__progname.html */
|
||||
/* Be careful to declare this only when we absolutely need it
|
||||
(OpenBSD 5.1), rather than when it's available. Otherwise,
|
||||
its mere declaration makes program_invocation_short_name
|
||||
malfunction (have zero length) with Fedora 25's glibc. */
|
||||
extern char *__progname;
|
||||
const char *p = __progname;
|
||||
# if defined __ANDROID__
|
||||
return last_component (p);
|
||||
# else
|
||||
return p && p[0] ? p : "?";
|
||||
# endif
|
||||
# elif _AIX /* AIX */
|
||||
/* Idea by Bastien ROUCARIÈS,
|
||||
https://lists.gnu.org/r/bug-gnulib/2010-12/msg00095.html
|
||||
Reference: https://www.ibm.com/support/knowledgecenter/en/ssw_aix_61/com.ibm.aix.basetrf1/getprocs.htm
|
||||
*/
|
||||
static char *p;
|
||||
static int first = 1;
|
||||
if (first)
|
||||
{
|
||||
first = 0;
|
||||
pid_t pid = getpid ();
|
||||
struct procentry64 procs;
|
||||
p = (0 < getprocs64 (&procs, sizeof procs, NULL, 0, &pid, 1)
|
||||
? strdup (procs.pi_comm)
|
||||
: NULL);
|
||||
if (!p)
|
||||
p = "?";
|
||||
}
|
||||
return p;
|
||||
# elif defined __hpux
|
||||
static char *p;
|
||||
static int first = 1;
|
||||
if (first)
|
||||
{
|
||||
first = 0;
|
||||
pid_t pid = getpid ();
|
||||
struct pst_status status;
|
||||
if (pstat_getproc (&status, sizeof status, 0, pid) > 0)
|
||||
{
|
||||
char *ucomm = status.pst_ucomm;
|
||||
char *cmd = status.pst_cmd;
|
||||
if (strlen (ucomm) < PST_UCOMMLEN - 1)
|
||||
p = ucomm;
|
||||
else
|
||||
{
|
||||
/* ucomm is truncated to length PST_UCOMMLEN - 1.
|
||||
Look at cmd instead. */
|
||||
char *space = strchr (cmd, ' ');
|
||||
if (space != NULL)
|
||||
*space = '\0';
|
||||
p = strrchr (cmd, '/');
|
||||
if (p != NULL)
|
||||
p++;
|
||||
else
|
||||
p = cmd;
|
||||
if (strlen (p) > PST_UCOMMLEN - 1
|
||||
&& memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
|
||||
/* p is less truncated than ucomm. */
|
||||
;
|
||||
else
|
||||
p = ucomm;
|
||||
}
|
||||
p = strdup (p);
|
||||
}
|
||||
else
|
||||
{
|
||||
# if !defined __LP64__
|
||||
/* Support for 32-bit programs running in 64-bit HP-UX.
|
||||
The documented way to do this is to use the same source code
|
||||
as above, but in a compilation unit where '#define _PSTAT64 1'
|
||||
is in effect. I prefer a single compilation unit; the struct
|
||||
size and the offsets are not going to change. */
|
||||
char status64[1216];
|
||||
if (__pstat_getproc64 (status64, sizeof status64, 0, pid) > 0)
|
||||
{
|
||||
char *ucomm = status64 + 288;
|
||||
char *cmd = status64 + 168;
|
||||
if (strlen (ucomm) < PST_UCOMMLEN - 1)
|
||||
p = ucomm;
|
||||
else
|
||||
{
|
||||
/* ucomm is truncated to length PST_UCOMMLEN - 1.
|
||||
Look at cmd instead. */
|
||||
char *space = strchr (cmd, ' ');
|
||||
if (space != NULL)
|
||||
*space = '\0';
|
||||
p = strrchr (cmd, '/');
|
||||
if (p != NULL)
|
||||
p++;
|
||||
else
|
||||
p = cmd;
|
||||
if (strlen (p) > PST_UCOMMLEN - 1
|
||||
&& memcmp (p, ucomm, PST_UCOMMLEN - 1) == 0)
|
||||
/* p is less truncated than ucomm. */
|
||||
;
|
||||
else
|
||||
p = ucomm;
|
||||
}
|
||||
p = strdup (p);
|
||||
}
|
||||
else
|
||||
# endif
|
||||
p = NULL;
|
||||
}
|
||||
if (!p)
|
||||
p = "?";
|
||||
}
|
||||
return p;
|
||||
# elif __MVS__ /* z/OS */
|
||||
/* https://www.ibm.com/support/knowledgecenter/SSLTBW_2.1.0/com.ibm.zos.v2r1.bpxbd00/rtwgetp.htm */
|
||||
static char *p = "?";
|
||||
static int first = 1;
|
||||
if (first)
|
||||
{
|
||||
pid_t pid = getpid ();
|
||||
int token;
|
||||
W_PSPROC buf;
|
||||
first = 0;
|
||||
memset (&buf, 0, sizeof(buf));
|
||||
buf.ps_cmdptr = (char *) malloc (buf.ps_cmdlen = PS_CMDBLEN_LONG);
|
||||
buf.ps_conttyptr = (char *) malloc (buf.ps_conttylen = PS_CONTTYBLEN);
|
||||
buf.ps_pathptr = (char *) malloc (buf.ps_pathlen = PS_PATHBLEN);
|
||||
if (buf.ps_cmdptr && buf.ps_conttyptr && buf.ps_pathptr)
|
||||
{
|
||||
for (token = 0; token >= 0;
|
||||
token = w_getpsent (token, &buf, sizeof(buf)))
|
||||
{
|
||||
if (token > 0 && buf.ps_pid == pid)
|
||||
{
|
||||
char *s = strdup (last_component (buf.ps_pathptr));
|
||||
if (s)
|
||||
p = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free (buf.ps_cmdptr);
|
||||
free (buf.ps_conttyptr);
|
||||
free (buf.ps_pathptr);
|
||||
}
|
||||
return p;
|
||||
# elif defined __sgi /* IRIX */
|
||||
char filename[50];
|
||||
int fd;
|
||||
|
||||
sprintf (filename, "/proc/pinfo/%d", (int) getpid ());
|
||||
fd = open (filename, O_RDONLY);
|
||||
if (0 <= fd)
|
||||
{
|
||||
prpsinfo_t buf;
|
||||
int ioctl_ok = 0 <= ioctl (fd, PIOCPSINFO, &buf);
|
||||
close (fd);
|
||||
if (ioctl_ok)
|
||||
{
|
||||
char *name = buf.pr_fname;
|
||||
size_t namesize = sizeof buf.pr_fname;
|
||||
/* It may not be NUL-terminated. */
|
||||
char *namenul = memchr (name, '\0', namesize);
|
||||
size_t namelen = namenul ? namenul - name : namesize;
|
||||
char *namecopy = malloc (namelen + 1);
|
||||
if (namecopy)
|
||||
{
|
||||
namecopy[namelen] = '\0';
|
||||
return memcpy (namecopy, name, namelen);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
# else
|
||||
# error "getprogname module not ported to this OS"
|
||||
# endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hey Emacs!
|
||||
* Local Variables:
|
||||
|
|
1415
third_party/make/lib/glob.c
vendored
1415
third_party/make/lib/glob.c
vendored
File diff suppressed because it is too large
Load diff
54
third_party/make/lib/malloc.c
vendored
54
third_party/make/lib/malloc.c
vendored
|
@ -1,54 +0,0 @@
|
|||
/* clang-format off */
|
||||
/* malloc() function that is glibc compatible.
|
||||
|
||||
Copyright (C) 1997-1998, 2006-2007, 2009-2020 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||
|
||||
/* written by Jim Meyering and Bruno Haible */
|
||||
|
||||
#define _GL_USE_STDLIB_ALLOC 1
|
||||
/* Only the AC_FUNC_MALLOC macro defines 'malloc' already in config.h. */
|
||||
#ifdef malloc
|
||||
# define NEED_MALLOC_GNU 1
|
||||
# undef malloc
|
||||
/* Whereas the gnulib module 'malloc-gnu' defines HAVE_MALLOC_GNU. */
|
||||
#elif GNULIB_MALLOC_GNU && !HAVE_MALLOC_GNU
|
||||
# define NEED_MALLOC_GNU 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Allocate an N-byte block of memory from the heap.
|
||||
If N is zero, allocate a 1-byte block. */
|
||||
|
||||
void *
|
||||
rpl_malloc (size_t n)
|
||||
{
|
||||
void *result;
|
||||
|
||||
#if NEED_MALLOC_GNU
|
||||
if (n == 0)
|
||||
n = 1;
|
||||
#endif
|
||||
|
||||
result = malloc (n);
|
||||
|
||||
#if !HAVE_MALLOC_POSIX
|
||||
if (result == NULL)
|
||||
errno = ENOMEM;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
|
@ -477,7 +477,6 @@ int SpawnSubprocesses(int argc, char *argv[]) {
|
|||
LOGIFNEG1(sigaction(SIGQUIT, &savequit, NULL));
|
||||
LOGIFNEG1(sigprocmask(SIG_SETMASK, &savemask, NULL));
|
||||
free(pids);
|
||||
kprintf("nocommit%n");
|
||||
return exitcode;
|
||||
}
|
||||
|
||||
|
|
|
@ -1240,7 +1240,10 @@ static void WaitAll(void) {
|
|||
if ((pid = wait4(-1, &ws, 0, &ru)) != -1) {
|
||||
HandleWorkerExit(pid, ws, &ru);
|
||||
} else {
|
||||
if (errno == ECHILD) break;
|
||||
if (errno == ECHILD) {
|
||||
errno = 0;
|
||||
break;
|
||||
}
|
||||
if (errno == EINTR) {
|
||||
if (killed) {
|
||||
killed = false;
|
||||
|
@ -1248,6 +1251,7 @@ static void WaitAll(void) {
|
|||
WARNF("(srvr) redbean shall terminate harder");
|
||||
LOGIFNEG1(kill(0, SIGTERM));
|
||||
}
|
||||
errno = 0;
|
||||
continue;
|
||||
}
|
||||
DIEF("(srvr) wait error: %m");
|
||||
|
@ -1267,8 +1271,14 @@ static void ReapZombies(void) {
|
|||
break;
|
||||
}
|
||||
} else {
|
||||
if (errno == ECHILD) break;
|
||||
if (errno == EINTR) continue;
|
||||
if (errno == ECHILD) {
|
||||
errno = 0;
|
||||
break;
|
||||
}
|
||||
if (errno == EINTR) {
|
||||
errno = 0;
|
||||
continue;
|
||||
}
|
||||
DIEF("(srvr) wait error: %m");
|
||||
}
|
||||
} while (!terminated);
|
||||
|
@ -1298,6 +1308,7 @@ static ssize_t WritevAll(int fd, struct iovec *iov, int iovlen) {
|
|||
}
|
||||
} while (wrote);
|
||||
} else if (errno == EINTR) {
|
||||
errno = 0;
|
||||
LockInc(&shared->c.writeinterruputs);
|
||||
if (killed || (meltdown && nowl() - startread > 2)) {
|
||||
return total ? total : -1;
|
||||
|
@ -1319,8 +1330,10 @@ static int TlsFlush(struct TlsBio *bio, const unsigned char *buf, size_t len) {
|
|||
if (WritevAll(bio->fd, v, 2) != -1) {
|
||||
if (bio->c > 0) bio->c = 0;
|
||||
} else if (errno == EINTR) {
|
||||
errno = 0;
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
} else if (errno == EAGAIN) {
|
||||
errno = 0;
|
||||
return MBEDTLS_ERR_SSL_TIMEOUT;
|
||||
} else if (errno == EPIPE || errno == ECONNRESET || errno == ENETRESET) {
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
|
@ -1363,8 +1376,10 @@ static int TlsRecvImpl(void *ctx, unsigned char *p, size_t n, uint32_t o) {
|
|||
v[1].iov_len = sizeof(bio->t);
|
||||
while ((r = readv(bio->fd, v, 2)) == -1) {
|
||||
if (errno == EINTR) {
|
||||
errno = 0;
|
||||
return MBEDTLS_ERR_SSL_WANT_READ;
|
||||
} else if (errno == EAGAIN) {
|
||||
errno = 0;
|
||||
return MBEDTLS_ERR_SSL_TIMEOUT;
|
||||
} else if (errno == EPIPE || errno == ECONNRESET || errno == ENETRESET) {
|
||||
return MBEDTLS_ERR_NET_CONN_RESET;
|
||||
|
@ -1406,6 +1421,7 @@ static ssize_t SslRead(int fd, void *buf, size_t size) {
|
|||
} else if (rc == MBEDTLS_ERR_SSL_WANT_READ) {
|
||||
errno = EINTR;
|
||||
rc = -1;
|
||||
errno = 0;
|
||||
} else {
|
||||
WARNF("(ssl) %s SslRead error -0x%04x", DescribeClient(), -rc);
|
||||
errno = EIO;
|
||||
|
@ -2249,6 +2265,7 @@ static ssize_t Send(struct iovec *iov, int iovlen) {
|
|||
} else if (errno == EAGAIN) {
|
||||
LockInc(&shared->c.writetimeouts);
|
||||
WARNF("(rsp) %s write timeout", DescribeClient());
|
||||
errno = 0;
|
||||
} else {
|
||||
LockInc(&shared->c.writeerrors);
|
||||
WARNF("(rsp) %s write error: %m", DescribeClient());
|
||||
|
@ -2662,6 +2679,7 @@ static void LaunchBrowser(const char *path) {
|
|||
}
|
||||
while (wait4(pid, &ws, 0, 0) == -1) {
|
||||
CHECK_EQ(EINTR, errno);
|
||||
errno = 0;
|
||||
}
|
||||
sigaction(SIGINT, &saveint, 0);
|
||||
sigaction(SIGQUIT, &savequit, 0);
|
||||
|
@ -5941,6 +5959,7 @@ static ssize_t SendString(const char *s) {
|
|||
if ((rc = writer(client, &iov, 1)) != -1 || errno != EINTR) {
|
||||
return rc;
|
||||
}
|
||||
errno = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6132,6 +6151,7 @@ static char *OpenAsset(struct Asset *a) {
|
|||
return HandleMapFailed(a, fd);
|
||||
}
|
||||
} else if (errno == EINTR) {
|
||||
errno = 0;
|
||||
goto OpenAgain;
|
||||
} else {
|
||||
return HandleOpenFail(a);
|
||||
|
@ -6639,7 +6659,6 @@ static bool StreamResponse(char *p) {
|
|||
static bool HandleMessageAcutal(void) {
|
||||
int rc;
|
||||
char *p;
|
||||
g_syscount = 0;
|
||||
if ((rc = ParseHttpMessage(&msg, inbuf.p, amtread)) != -1) {
|
||||
if (!rc) return false;
|
||||
hdrsize = rc;
|
||||
|
@ -6769,6 +6788,7 @@ static void HandleMessages(void) {
|
|||
}
|
||||
} else if (errno == EINTR) {
|
||||
LockInc(&shared->c.readinterrupts);
|
||||
errno = 0;
|
||||
} else if (errno == EAGAIN) {
|
||||
LockInc(&shared->c.readtimeouts);
|
||||
if (amtread) SendTimeout();
|
||||
|
@ -6943,6 +6963,7 @@ static void HandleConnection(size_t i) {
|
|||
} else {
|
||||
DIEF("(srvr) %s accept error: %m", DescribeServer());
|
||||
}
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
static void HandlePoll(void) {
|
||||
|
@ -6965,6 +6986,7 @@ static void HandlePoll(void) {
|
|||
} else {
|
||||
DIEF("(srvr) poll error: %m");
|
||||
}
|
||||
errno = 0;
|
||||
}
|
||||
|
||||
static void RestoreApe(void) {
|
||||
|
|
Loading…
Reference in a new issue