From 5b60e5a37dc394083bd8fac1f7aaf50723bc08f0 Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Fri, 3 Sep 2021 22:19:41 -0700 Subject: [PATCH] Fix termios struct on Linux The termios::c_cc field turned out to be incorrectly defined on Linux due to some confusion between the glibc and kernel definitions. We'll be using the kernel definition, since it has the strongest consensus. Fields have been have been added to struct stat for BSD compatibility such as st_birthtim, plus the GLIBC compatibility of isystem/sys/stat has been improved. --- examples/stat.c | 15 ++-- libc/calls/calls.mk | 2 + libc/calls/fileexists.c | 5 +- libc/calls/fstat-nt.c | 2 + libc/calls/fstat-sysv.c | 25 ++++-- libc/calls/fstat.c | 1 - libc/calls/fstatat-sysv.c | 27 ++++-- libc/calls/fstatat.c | 4 - libc/calls/internal.h | 4 +- libc/calls/ioctl_tcgets.c | 32 +++++-- libc/calls/ioctl_tcsets.c | 26 +++++- libc/calls/ischardev.c | 4 +- libc/calls/isdirectory.c | 4 +- libc/calls/isregularfile.c | 4 +- libc/calls/readansi.c | 2 + libc/calls/stat2cosmo.c | 97 +++++++++++++++++++++ libc/calls/stat2linux.c | 95 -------------------- libc/calls/struct/metastat.internal.h | 26 +++++- libc/calls/struct/stat.h | 36 ++++---- libc/calls/struct/stat.macros.h | 24 +++++ libc/calls/struct/termios.h | 4 +- libc/calls/termios.internal.h | 44 +++++----- libc/calls/termios2host.c | 35 -------- libc/calls/termios2linux.c | 33 ------- libc/isystem/stat.h | 7 -- libc/isystem/sys/stat.h | 5 ++ libc/sysv/consts.sh | 36 ++++---- libc/sysv/consts/NCCS.S | 2 +- libc/sysv/consts/VDISCARD.S | 2 +- libc/sysv/consts/VEOF.S | 2 +- libc/sysv/consts/VEOL.S | 2 +- libc/sysv/consts/VEOL2.S | 2 +- libc/sysv/consts/VERASE.S | 2 +- libc/sysv/consts/VINTR.S | 2 +- libc/sysv/consts/VKILL.S | 2 +- libc/sysv/consts/VLNEXT.S | 2 +- libc/sysv/consts/VMIN.S | 2 +- libc/sysv/consts/VQUIT.S | 2 +- libc/sysv/consts/VREPRINT.S | 2 +- libc/sysv/consts/VSTART.S | 2 +- libc/sysv/consts/VSTOP.S | 2 +- libc/sysv/consts/VSUSP.S | 2 +- libc/sysv/consts/VSWTC.S | 2 +- libc/sysv/consts/VTIME.S | 2 +- libc/sysv/consts/VWERASE.S | 2 +- libc/sysv/consts/termios.h | 3 +- libc/zipos/stat-impl.c | 1 + third_party/chibicc/preprocess.c | 2 +- third_party/lz4cli/util.h | 2 +- third_party/python/Modules/_sqlite/module.c | 2 + third_party/python/Modules/posixmodule.c | 1 + third_party/python/pyconfig.h | 8 +- 52 files changed, 358 insertions(+), 296 deletions(-) create mode 100644 libc/calls/stat2cosmo.c delete mode 100644 libc/calls/stat2linux.c create mode 100644 libc/calls/struct/stat.macros.h delete mode 100644 libc/calls/termios2host.c delete mode 100644 libc/calls/termios2linux.c delete mode 100644 libc/isystem/stat.h diff --git a/examples/stat.c b/examples/stat.c index 4e7f045f8..895251d3f 100644 --- a/examples/stat.c +++ b/examples/stat.c @@ -12,6 +12,7 @@ #include "libc/errno.h" #include "libc/fmt/fmt.h" #include "libc/log/check.h" +#include "libc/log/log.h" #include "libc/runtime/gc.h" #include "libc/stdio/stdio.h" #include "libc/x/x.h" @@ -35,18 +36,22 @@ void PrintFileMetadata(const char *pathname, struct stat *st) { "%-32s%d\n" "%-32s%d\n" "%-32s%d\n" + "%-32s%d\n" "%-32s%ld\n" + "%-32s%ld\n" + "%-32s%s\n" "%-32s%s\n" "%-32s%s\n" "%-32s%s\n", "bytes in file", st->st_size, "physical bytes", st->st_blocks * 512, "device id w/ file", st->st_dev, "inode", st->st_ino, "hard link count", st->st_nlink, "mode / permissions", st->st_mode, - "owner id", st->st_uid, "group id", st->st_gid, - "device id (if special)", st->st_rdev, "block size", st->st_blksize, - "access time", _gc(xiso8601(&st->st_atim)), "modified time", - _gc(xiso8601(&st->st_mtim)), "c[omplicated]time", - _gc(xiso8601(&st->st_ctim))); + "owner id", st->st_uid, "group id", st->st_gid, "flags", st->st_flags, + "gen", st->st_gen, "device id (if special)", st->st_rdev, "block size", + st->st_blksize, "access time", _gc(xiso8601(&st->st_atim)), + "modified time", _gc(xiso8601(&st->st_mtim)), "c[omplicated]time", + _gc(xiso8601(&st->st_ctim)), "birthtime", + _gc(xiso8601(&st->st_birthtim))); } int main(int argc, char *argv[]) { diff --git a/libc/calls/calls.mk b/libc/calls/calls.mk index e4da3957e..f95d5df86 100644 --- a/libc/calls/calls.mk +++ b/libc/calls/calls.mk @@ -67,6 +67,8 @@ o/$(MODE)/libc/calls/raise.o: \ OVERRIDE_COPTS += \ $(NO_MAGIC) +o/$(MODE)/libc/calls/termios2linux.o \ +o/$(MODE)/libc/calls/termios2host.o \ o/$(MODE)/libc/calls/sigenter-freebsd.o \ o/$(MODE)/libc/calls/sigenter-netbsd.o \ o/$(MODE)/libc/calls/sigenter-openbsd.o \ diff --git a/libc/calls/fileexists.c b/libc/calls/fileexists.c index 02e3c165c..b2b3b0899 100644 --- a/libc/calls/fileexists.c +++ b/libc/calls/fileexists.c @@ -19,6 +19,7 @@ #include "libc/bits/weaken.h" #include "libc/calls/calls.h" #include "libc/calls/internal.h" +#include "libc/calls/struct/metastat.internal.h" #include "libc/calls/struct/stat.h" #include "libc/dce.h" #include "libc/errno.h" @@ -43,13 +44,13 @@ */ bool fileexists(const char *path) { int e; - struct stat st; + union metastat st; struct ZiposUri zipname; uint16_t path16[PATH_MAX]; if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) { e = errno; - if (weaken(__zipos_stat)(&zipname, &st) != -1) { + if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) { return true; } else { errno = e; diff --git a/libc/calls/fstat-nt.c b/libc/calls/fstat-nt.c index 18b74bff8..13c8303e9 100644 --- a/libc/calls/fstat-nt.c +++ b/libc/calls/fstat-nt.c @@ -87,6 +87,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) { case kNtFileTypeDisk: if (GetFileInformationByHandle(handle, &wst)) { st->st_mode = 0555; + st->st_flags = wst.dwFileAttributes; if (!(wst.dwFileAttributes & kNtFileAttributeReadonly)) { st->st_mode |= 0200; } @@ -100,6 +101,7 @@ textwindows int sys_fstat_nt(int64_t handle, struct stat *st) { st->st_atim = FileTimeToTimeSpec(wst.ftLastAccessFileTime); st->st_mtim = FileTimeToTimeSpec(wst.ftLastWriteFileTime); st->st_ctim = FileTimeToTimeSpec(wst.ftCreationFileTime); + st->st_birthtim = st->st_ctim; st->st_size = (uint64_t)wst.nFileSizeHigh << 32 | wst.nFileSizeLow; st->st_blksize = PAGESIZE; st->st_dev = wst.dwVolumeSerialNumber; diff --git a/libc/calls/fstat-sysv.c b/libc/calls/fstat-sysv.c index 341cb8051..e05714552 100644 --- a/libc/calls/fstat-sysv.c +++ b/libc/calls/fstat-sysv.c @@ -17,15 +17,30 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/dce.h" +#include "libc/intrin/asan.internal.h" +#include "libc/sysv/errfuns.h" /** * Supports fstat(), etc. implementations. * @asyncsignalsafe */ -textstartup int32_t sys_fstat(int32_t fd, struct stat *st) { - int res; - if ((res = __sys_fstat(fd, st)) != -1) { - __stat2linux(st); +int32_t sys_fstat(int32_t fd, struct stat *st) { + void *p; + union metastat ms; + if (IsLinux()) { + _Static_assert(sizeof(*st) == sizeof(ms.linux), "assumption broken"); + if (IsAsan() && !__asan_is_valid(st, sizeof(*st))) return efault(); + p = st; + } else if (st) { + p = &ms; + } else { + p = 0; + } + if (__sys_fstat(fd, p) != -1) { + __stat2cosmo(st, &ms); + return 0; + } else { + return -1; } - return res; } diff --git a/libc/calls/fstat.c b/libc/calls/fstat.c index a2d6fe629..e41f50834 100644 --- a/libc/calls/fstat.c +++ b/libc/calls/fstat.c @@ -29,7 +29,6 @@ * @asyncsignalsafe */ int fstat(int fd, struct stat *st) { - if (IsAsan() && !__asan_is_valid(st, sizeof(*st))) return efault(); if (__isfdkind(fd, kFdZip)) { return weaken(__zipos_fstat)( (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, st); diff --git a/libc/calls/fstatat-sysv.c b/libc/calls/fstatat-sysv.c index 4ce4c878e..dceac5c93 100644 --- a/libc/calls/fstatat-sysv.c +++ b/libc/calls/fstatat-sysv.c @@ -17,16 +17,33 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/internal.h" +#include "libc/calls/struct/metastat.internal.h" +#include "libc/dce.h" +#include "libc/intrin/asan.internal.h" +#include "libc/sysv/errfuns.h" /** * Supports stat(), lstat(), fstatat(), etc. implementations. * @asyncsignalsafe */ -int32_t sys_fstatat(int32_t dirfd, const char *pathname, struct stat *st, +int32_t sys_fstatat(int32_t dirfd, const char *path, struct stat *st, int32_t flags) { - int32_t rc; - if ((rc = __sys_fstatat(dirfd, pathname, st, flags)) != -1) { - __stat2linux(st); + void *p; + union metastat ms; + if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); + if (IsLinux()) { + _Static_assert(sizeof(*st) == sizeof(ms.linux), "assumption broken"); + if (IsAsan() && !__asan_is_valid(st, sizeof(*st))) return efault(); + p = st; + } else if (st) { + p = &ms; + } else { + p = 0; + } + if (__sys_fstatat(dirfd, path, p, flags) != -1) { + __stat2cosmo(st, &ms); + return 0; + } else { + return -1; } - return rc; } diff --git a/libc/calls/fstatat.c b/libc/calls/fstatat.c index 76d2a89c4..db489f107 100644 --- a/libc/calls/fstatat.c +++ b/libc/calls/fstatat.c @@ -41,10 +41,6 @@ */ int fstatat(int dirfd, const char *path, struct stat *st, int flags) { struct ZiposUri zipname; - if (IsAsan() && (!__asan_is_valid(path, 1) || - (st && !__asan_is_valid(st, sizeof(*st))))) { - return efault(); - } if (__isfdkind(dirfd, kFdZip)) return einval(); /* TODO(jart): implement me */ if (weaken(__zipos_stat) && weaken(__zipos_parseuri)(path, &zipname) != -1) { return weaken(__zipos_stat)(&zipname, st); diff --git a/libc/calls/internal.h b/libc/calls/internal.h index 074b0c320..f3f9927ff 100644 --- a/libc/calls/internal.h +++ b/libc/calls/internal.h @@ -4,10 +4,12 @@ #include "libc/calls/internal.h" #include "libc/calls/struct/iovec.h" #include "libc/calls/struct/itimerval.h" +#include "libc/calls/struct/metastat.internal.h" #include "libc/calls/struct/rusage.h" #include "libc/calls/struct/sigaction-xnu.internal.h" #include "libc/calls/struct/siginfo.h" #include "libc/calls/struct/sigval.h" +#include "libc/calls/struct/stat.h" #include "libc/calls/struct/timespec.h" #include "libc/calls/struct/timeval.h" #include "libc/dce.h" @@ -222,7 +224,7 @@ u32 __prot2nt(i32, i32) privileged; void __restore_rt() hidden; int sys_utimensat_xnu(int, const char *, const struct timespec *, int) hidden; int sys_nanosleep_xnu(const struct timespec *, struct timespec *) hidden; -void __stat2linux(void *) hidden; +void __stat2cosmo(struct stat *restrict, const union metastat *) hidden; void __restore_rt_netbsd(void) hidden; void __sigenter_xnu(void *, i32, i32, struct __darwin_siginfo *, struct __darwin_ucontext *) hidden; diff --git a/libc/calls/ioctl_tcgets.c b/libc/calls/ioctl_tcgets.c index 6ce158c91..aee73fd8c 100644 --- a/libc/calls/ioctl_tcgets.c +++ b/libc/calls/ioctl_tcgets.c @@ -20,6 +20,7 @@ #include "libc/calls/ioctl.h" #include "libc/calls/struct/metatermios.internal.h" #include "libc/calls/termios.internal.h" +#include "libc/calls/ttydefaults.h" #include "libc/dce.h" #include "libc/intrin/asan.internal.h" #include "libc/sysv/consts/termios.h" @@ -27,13 +28,33 @@ int ioctl_tcgets_nt(int, struct termios *) hidden; +static int ioctl_tcgets_metal(int fd, struct termios *tio) { + memset(tio, 0, sizeof(*tio)); + tio->c_iflag = TTYDEF_IFLAG; + tio->c_oflag = TTYDEF_OFLAG; + tio->c_lflag = TTYDEF_LFLAG; + tio->c_cflag = TTYDEF_CFLAG; + return 0; +} + static int ioctl_tcgets_sysv(int fd, struct termios *tio) { int rc; - union metatermios t; - if ((rc = sys_ioctl(fd, TCGETS, &t)) != -1) { - __termios2linux(tio, &t); + union metatermios mt; + if (IsLinux()) { + if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault(); + return sys_ioctl(fd, TCGETS, tio); + } else { + if ((rc = sys_ioctl(fd, TCGETS, &mt)) != -1) { + if (IsXnu()) { + COPY_TERMIOS(tio, &mt.xnu); + } else if (IsFreebsd() || IsOpenbsd() || IsNetbsd()) { + COPY_TERMIOS(tio, &mt.bsd); + } else { + unreachable; + } + } + return rc; } - return rc; } /** @@ -51,9 +72,10 @@ int ioctl_tcgets(int fd, ...) { va_end(va); if (fd >= 0) { if (!tio) return efault(); - if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault(); if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { return enotty(); + } else if (IsMetal()) { + return ioctl_tcgets_metal(fd, tio); } else if (!IsWindows()) { return ioctl_tcgets_sysv(fd, tio); } else { diff --git a/libc/calls/ioctl_tcsets.c b/libc/calls/ioctl_tcsets.c index 7e37095ba..8986bfebd 100644 --- a/libc/calls/ioctl_tcsets.c +++ b/libc/calls/ioctl_tcsets.c @@ -27,10 +27,29 @@ int ioctl_tcsets_nt(int, uint64_t, const struct termios *); +static int ioctl_tcsets_metal(int fd, uint64_t request, + const struct termios *tio) { + return 0; +} + +static inline void *__termios2host(union metatermios *mt, + const struct termios *lt) { + if (!IsXnu() && !IsFreebsd() && !IsOpenbsd() && !IsNetbsd()) { + return lt; + } else if (IsXnu()) { + COPY_TERMIOS(&mt->xnu, lt); + return &mt->xnu; + } else { + COPY_TERMIOS(&mt->bsd, lt); + return &mt->bsd; + } +} + static int ioctl_tcsets_sysv(int fd, uint64_t request, const struct termios *tio) { - union metatermios t; - return sys_ioctl(fd, request, __termios2host(&t, tio)); + union metatermios mt; + if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault(); + return sys_ioctl(fd, request, __termios2host(&mt, tio)); } /** @@ -47,10 +66,11 @@ int ioctl_tcsets(int fd, uint64_t request, ...) { tio = va_arg(va, const struct termios *); va_end(va); if (!tio) return efault(); - if (IsAsan() && !__asan_is_valid(tio, sizeof(*tio))) return efault(); if (fd >= 0) { if (fd < g_fds.n && g_fds.p[fd].kind == kFdZip) { return enotty(); + } else if (IsMetal()) { + return ioctl_tcsets_metal(fd, request, tio); } else if (!IsWindows()) { return ioctl_tcsets_sysv(fd, request, tio); } else { diff --git a/libc/calls/ischardev.c b/libc/calls/ischardev.c index ebc4861cd..2777d0ad4 100644 --- a/libc/calls/ischardev.c +++ b/libc/calls/ischardev.c @@ -46,9 +46,9 @@ bool32 ischardev(int fd) { if (__isfdkind(fd, kFdZip)) { e = errno; if (weaken(__zipos_fstat)( - (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, &st.linux) != + (struct ZiposHandle *)(intptr_t)g_fds.p[fd].handle, &st.cosmo) != -1) { - return S_ISCHR(st.linux.st_mode); + return S_ISCHR(st.cosmo.st_mode); } else { errno = e; return false; diff --git a/libc/calls/isdirectory.c b/libc/calls/isdirectory.c index 103b17378..a0e863081 100644 --- a/libc/calls/isdirectory.c +++ b/libc/calls/isdirectory.c @@ -49,8 +49,8 @@ bool isdirectory(const char *path) { if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) { e = errno; - if (weaken(__zipos_stat)(&zipname, &st.linux) != -1) { - return S_ISDIR(st.linux.st_mode); + if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) { + return S_ISDIR(st.cosmo.st_mode); } else { errno = e; return false; diff --git a/libc/calls/isregularfile.c b/libc/calls/isregularfile.c index 8c31329b1..66d0022d4 100644 --- a/libc/calls/isregularfile.c +++ b/libc/calls/isregularfile.c @@ -46,8 +46,8 @@ bool isregularfile(const char *path) { if (IsAsan() && !__asan_is_valid(path, 1)) return efault(); if (weaken(__zipos_open) && weaken(__zipos_parseuri)(path, &zipname) != -1) { e = errno; - if (weaken(__zipos_stat)(&zipname, &st.linux) != -1) { - return S_ISREG(st.linux.st_mode); + if (weaken(__zipos_stat)(&zipname, &st.cosmo) != -1) { + return S_ISREG(st.cosmo.st_mode); } else { errno = e; return false; diff --git a/libc/calls/readansi.c b/libc/calls/readansi.c index aa4400bc0..27706e4a1 100644 --- a/libc/calls/readansi.c +++ b/libc/calls/readansi.c @@ -17,6 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/calls/internal.h" #include "libc/str/thompike.h" #include "libc/sysv/errfuns.h" @@ -108,6 +109,7 @@ ssize_t readansi(int fd, char *buf, size_t size) { case 'O': t = kSs; break; + case '\e': case 0x20 ... 0x2F: break; default: diff --git a/libc/calls/stat2cosmo.c b/libc/calls/stat2cosmo.c new file mode 100644 index 000000000..b6c76763b --- /dev/null +++ b/libc/calls/stat2cosmo.c @@ -0,0 +1,97 @@ +/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ +│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ +╞══════════════════════════════════════════════════════════════════════════════╡ +│ Copyright 2020 Justine Alexandra Roberts Tunney │ +│ │ +│ Permission to use, copy, modify, and/or distribute this software for │ +│ any purpose with or without fee is hereby granted, provided that the │ +│ above copyright notice and this permission notice appear in all copies. │ +│ │ +│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ +│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ +│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ +│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ +│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ +│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ +│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ +│ PERFORMANCE OF THIS SOFTWARE. │ +╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/calls/internal.h" +#include "libc/calls/struct/metastat.internal.h" +#include "libc/dce.h" + +void __stat2cosmo(struct stat *restrict st, const union metastat *ms) { + if (st) { + if (IsLinux()) { + st->st_birthtim = st->st_ctim; + } else if (IsXnu()) { + st->st_dev = ms->xnu.st_dev; + st->st_ino = ms->xnu.st_ino; + st->st_nlink = ms->xnu.st_nlink; + st->st_mode = ms->xnu.st_mode; + st->st_uid = ms->xnu.st_uid; + st->st_gid = ms->xnu.st_gid; + st->st_flags = ms->xnu.st_flags; + st->st_rdev = ms->xnu.st_rdev; + st->st_size = ms->xnu.st_size; + st->st_blksize = ms->xnu.st_blksize; + st->st_blocks = ms->xnu.st_blocks; + st->st_gen = ms->xnu.st_gen; + st->st_atim = ms->xnu.st_atim; + st->st_mtim = ms->xnu.st_mtim; + st->st_ctim = ms->xnu.st_ctim; + st->st_birthtim = ms->xnu.st_birthtim; + } else if (IsFreebsd()) { + st->st_dev = ms->freebsd.st_dev; + st->st_ino = ms->freebsd.st_ino; + st->st_nlink = ms->freebsd.st_nlink; + st->st_mode = ms->freebsd.st_mode; + st->st_uid = ms->freebsd.st_uid; + st->st_gid = ms->freebsd.st_gid; + st->st_flags = ms->freebsd.st_flags; + st->st_rdev = ms->freebsd.st_rdev; + st->st_size = ms->freebsd.st_size; + st->st_blksize = ms->freebsd.st_blksize; + st->st_blocks = ms->freebsd.st_blocks; + st->st_gen = ms->freebsd.st_gen; + st->st_atim = ms->freebsd.st_atim; + st->st_mtim = ms->freebsd.st_mtim; + st->st_ctim = ms->freebsd.st_ctim; + st->st_birthtim = ms->freebsd.st_birthtim; + } else if (IsOpenbsd()) { + st->st_dev = ms->openbsd.st_dev; + st->st_ino = ms->openbsd.st_ino; + st->st_nlink = ms->openbsd.st_nlink; + st->st_mode = ms->openbsd.st_mode; + st->st_uid = ms->openbsd.st_uid; + st->st_gid = ms->openbsd.st_gid; + st->st_flags = ms->openbsd.st_flags; + st->st_rdev = ms->openbsd.st_rdev; + st->st_size = ms->openbsd.st_size; + st->st_blksize = ms->openbsd.st_blksize; + st->st_blocks = ms->openbsd.st_blocks; + st->st_gen = ms->openbsd.st_gen; + st->st_atim = ms->openbsd.st_atim; + st->st_mtim = ms->openbsd.st_mtim; + st->st_ctim = ms->openbsd.st_ctim; + st->st_birthtim = ms->openbsd.st_ctim; + } else if (IsNetbsd()) { + st->st_dev = ms->netbsd.st_dev; + st->st_ino = ms->netbsd.st_ino; + st->st_nlink = ms->netbsd.st_nlink; + st->st_mode = ms->netbsd.st_mode; + st->st_uid = ms->netbsd.st_uid; + st->st_gid = ms->netbsd.st_gid; + st->st_flags = ms->netbsd.st_flags; + st->st_rdev = ms->netbsd.st_rdev; + st->st_size = ms->netbsd.st_size; + st->st_blksize = ms->netbsd.st_blksize; + st->st_blocks = ms->netbsd.st_blocks; + st->st_gen = ms->netbsd.st_gen; + st->st_atim = ms->netbsd.st_atim; + st->st_mtim = ms->netbsd.st_mtim; + st->st_ctim = ms->netbsd.st_ctim; + st->st_birthtim = ms->netbsd.st_birthtim; + } + } +} diff --git a/libc/calls/stat2linux.c b/libc/calls/stat2linux.c deleted file mode 100644 index 9970d8535..000000000 --- a/libc/calls/stat2linux.c +++ /dev/null @@ -1,95 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/internal.h" -#include "libc/calls/struct/metastat.internal.h" -#include "libc/dce.h" - -#ifndef SWITCHEROO -#define SWITCHEROO(S1, S2, A, B, C, D, E, F, G, H, I, J, K, L, M) \ - do { \ - autotype((S2).A) a = (typeof((S2).A))(S1).A; \ - autotype((S2).B) b = (typeof((S2).B))(S1).B; \ - autotype((S2).C) c = (typeof((S2).C))(S1).C; \ - autotype((S2).D) d = (typeof((S2).D))(S1).D; \ - autotype((S2).E) e = (typeof((S2).E))(S1).E; \ - autotype((S2).F) f = (typeof((S2).F))(S1).F; \ - autotype((S2).G) g = (typeof((S2).G))(S1).G; \ - autotype((S2).H) h = (typeof((S2).H))(S1).H; \ - autotype((S2).I) i = (typeof((S2).I))(S1).I; \ - autotype((S2).J) j = (typeof((S2).J))(S1).J; \ - autotype((S2).K) k = (typeof((S2).K))(S1).K; \ - autotype((S2).L) l = (typeof((S2).L))(S1).L; \ - autotype((S2).M) m = (typeof((S2).M))(S1).M; \ - (S2).A = a; \ - (S2).B = b; \ - (S2).C = c; \ - (S2).D = d; \ - (S2).E = e; \ - (S2).F = f; \ - (S2).G = g; \ - (S2).H = h; \ - (S2).I = i; \ - (S2).J = j; \ - (S2).K = k; \ - (S2).L = l; \ - (S2).M = m; \ - } while (0); -#endif - -static textstartup void __stat2linux_xnu(union metastat *ms) { - SWITCHEROO(ms->xnu, ms->linux, st_dev, st_ino, st_nlink, st_mode, st_uid, - st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atim, st_mtim, - st_ctim); -} - -static textstartup void __stat2linux_freebsd(union metastat *ms) { - SWITCHEROO(ms->freebsd, ms->linux, st_dev, st_ino, st_nlink, st_mode, st_uid, - st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atim, st_mtim, - st_ctim); -} - -static textstartup void __stat2linux_openbsd(union metastat *ms) { - SWITCHEROO(ms->openbsd, ms->linux, st_dev, st_ino, st_nlink, st_mode, st_uid, - st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atim, st_mtim, - st_ctim); -} - -static textstartup void __stat2linux_netbsd(union metastat *ms) { - SWITCHEROO(ms->netbsd, ms->linux, st_dev, st_ino, st_nlink, st_mode, st_uid, - st_gid, st_rdev, st_size, st_blksize, st_blocks, st_atim, st_mtim, - st_ctim); -} - -/** - * Transcodes “The Dismal Data Structure” from BSD→Linux ABI. - * @asyncsignalsafe - */ -textstartup void __stat2linux(void *ms) { - if (ms) { - if (IsXnu()) { - __stat2linux_xnu((union metastat *)ms); - } else if (IsFreebsd()) { - __stat2linux_freebsd((union metastat *)ms); - } else if (IsOpenbsd()) { - __stat2linux_openbsd((union metastat *)ms); - } else if (IsNetbsd()) { - __stat2linux_netbsd((union metastat *)ms); - } - } -} diff --git a/libc/calls/struct/metastat.internal.h b/libc/calls/struct/metastat.internal.h index 70291c7ce..4c3662071 100644 --- a/libc/calls/struct/metastat.internal.h +++ b/libc/calls/struct/metastat.internal.h @@ -1,7 +1,7 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_METASTAT_H_ #define COSMOPOLITAN_LIBC_CALLS_STRUCT_METASTAT_H_ -#ifndef __STRICT_ANSI__ #include "libc/calls/struct/stat.h" +#include "libc/calls/struct/timespec.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ @@ -13,6 +13,24 @@ COSMOPOLITAN_C_START_ : IsNetbsd() ? x.netbsd.field \ : 0) +struct stat_linux { + uint64_t st_dev; + uint64_t st_ino; + uint64_t st_nlink; + uint32_t st_mode; + uint32_t st_uid; + uint32_t st_gid; + uint32_t __pad0; + uint64_t st_rdev; + int64_t st_size; + int64_t st_blksize; + int64_t st_blocks; + struct timespec st_atim; + struct timespec st_mtim; + struct timespec st_ctim; + int64_t __unused[3]; +}; + struct stat_xnu { int32_t st_dev; uint16_t st_mode, st_nlink; @@ -52,7 +70,7 @@ struct stat_openbsd { int64_t st_size, st_blocks; int32_t st_blksize; uint32_t st_flags, st_gen; - struct timespec __st_birthtim; + struct timespec st_birthtim; }; struct stat_netbsd { @@ -68,7 +86,8 @@ struct stat_netbsd { }; union metastat { - struct stat linux; + struct stat cosmo; + struct stat_linux linux; struct stat_xnu xnu; struct stat_freebsd freebsd; struct stat_openbsd openbsd; @@ -77,5 +96,4 @@ union metastat { COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* !ANSI */ #endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_METASTAT_H_ */ diff --git a/libc/calls/struct/stat.h b/libc/calls/struct/stat.h index 7a4bb64c3..fc39ec4a5 100644 --- a/libc/calls/struct/stat.h +++ b/libc/calls/struct/stat.h @@ -3,25 +3,23 @@ #include "libc/calls/struct/timespec.h" #if !(__ASSEMBLER__ + __LINKER__ + 0) -struct stat { /* linux abi */ - int64_t st_dev; /* 0: id of device with file */ - int64_t st_ino; /* 8: inode number in disk b-tree */ - int64_t st_nlink; /* 16: hard link count */ - int32_t st_mode; /* 24: octal file mask thing */ - int32_t st_uid; /* 28: user id of owner */ - int32_t st_gid; /* group id of owning group */ - int32_t __pad; /* ignore this */ - int64_t st_rdev; /* id of device if a special file */ - int64_t st_size; /* bytes in file */ - int64_t st_blksize; /* preferred chunking for underlying filesystem */ - int64_t st_blocks; /* number of 512-byte pages allocated to file */ - struct timespec st_atim; /* access time (consider noatime) */ - struct timespec st_mtim; /* modified time */ - struct timespec st_ctim; /* complicated time */ - int64_t __future[3 + 10]; /* reserved for future use */ -#define st_atime st_atim.tv_sec -#define st_mtime st_mtim.tv_sec -#define st_ctime st_ctim.tv_sec +struct stat { /* cosmo abi */ + uint64_t st_dev; /* 0: id of device with file */ + uint64_t st_ino; /* 8: inode number in disk b-tree */ + uint64_t st_nlink; /* 16: hard link count */ + uint32_t st_mode; /* 24: octal file mask thing */ + uint32_t st_uid; /* 28: user id of owner */ + uint32_t st_gid; /* group id of owning group */ + uint32_t st_flags; /* flags (bsd-only) */ + uint64_t st_rdev; /* id of device if a special file */ + int64_t st_size; /* bytes in file */ + int64_t st_blksize; /* preferred chunking for underlying filesystem */ + int64_t st_blocks; /* number of 512-byte pages allocated to file */ + struct timespec st_atim; /* access time */ + struct timespec st_mtim; /* modified time */ + struct timespec st_ctim; /* complicated time */ + struct timespec st_birthtim; + uint64_t st_gen; }; #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/calls/struct/stat.macros.h b/libc/calls/struct/stat.macros.h new file mode 100644 index 000000000..e3712fe3e --- /dev/null +++ b/libc/calls/struct/stat.macros.h @@ -0,0 +1,24 @@ +#ifndef COSMOPOLITAN_LIBC_CALLS_STRUCT_STAT_MACROS_H_ +#define COSMOPOLITAN_LIBC_CALLS_STRUCT_STAT_MACROS_H_ + +#define STAT_HAVE_NSEC 1 + +#define st_atime st_atim.tv_sec +#define st_mtime st_mtim.tv_sec +#define st_ctime st_ctim.tv_sec + +#define st_atime_nsec st_atim.tv_nsec +#define st_mtime_nsec st_mtim.tv_nsec +#define st_ctime_nsec st_ctim.tv_nsec + +#define st_atimensec st_atim.tv_nsec +#define st_mtimensec st_mtim.tv_nsec +#define st_ctimensec st_ctim.tv_nsec +#define st_birthtime st_birthtim.tv_sec +#define st_birthtimensec st_birthtim.tv_nsec + +#define st_file_attributes st_flags + +#define INIT_STRUCT_STAT_PADDING(st) (void)st + +#endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_STAT_MACROS_H_ */ diff --git a/libc/calls/struct/termios.h b/libc/calls/struct/termios.h index 1ef829227..74e9fbc18 100644 --- a/libc/calls/struct/termios.h +++ b/libc/calls/struct/termios.h @@ -8,11 +8,13 @@ struct termios { /* GNU/Systemd ABI */ uint32_t c_oflag; /* output modes */ uint32_t c_cflag; /* control modes */ uint32_t c_lflag; /* local modes */ - uint8_t c_cc[32]; /* code mappings */ + uint8_t c_cc[20]; /* code mappings */ uint32_t c_ispeed; /* input speed */ uint32_t c_ospeed; /* output speed */ }; +#define c_line c_cc[0] /* line discipline */ + COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_CALLS_STRUCT_TERMIOS_H_ */ diff --git a/libc/calls/termios.internal.h b/libc/calls/termios.internal.h index 0a44c6db0..1e4b46ac5 100644 --- a/libc/calls/termios.internal.h +++ b/libc/calls/termios.internal.h @@ -1,30 +1,30 @@ #ifndef COSMOPOLITAN_LIBC_CALLS_TERMIOS_INTERNAL_H_ #define COSMOPOLITAN_LIBC_CALLS_TERMIOS_INTERNAL_H_ -#ifndef __STRICT_ANSI__ -#include "libc/bits/safemacros.internal.h" #include "libc/calls/struct/metatermios.internal.h" #include "libc/calls/struct/termios.h" -#include "libc/str/str.h" -#if !(__ASSEMBLER__ + __LINKER__ + 0) -COSMOPOLITAN_C_START_ -#define COPY_TERMIOS(TO, FROM) \ - do { \ - memset((TO), 0, sizeof(*(TO))); \ - (TO)->c_iflag = (FROM)->c_iflag; \ - (TO)->c_oflag = (FROM)->c_oflag; \ - (TO)->c_cflag = (FROM)->c_cflag; \ - (TO)->c_lflag = (FROM)->c_lflag; \ - memcpy((TO)->c_cc, (FROM)->c_cc, \ - min(sizeof((TO)->c_cc), sizeof((FROM)->c_cc))); \ - (TO)->c_ispeed = (FROM)->c_ispeed; \ - (TO)->c_ospeed = (FROM)->c_ospeed; \ +#define COPY_TERMIOS(TO, FROM) \ + do { \ + uint32_t Cc3; \ + uint64_t Cc1, Cc2; \ + autotype((TO)->c_iflag) c_iflag = (FROM)->c_iflag; \ + autotype((TO)->c_oflag) c_oflag = (FROM)->c_oflag; \ + autotype((TO)->c_cflag) c_cflag = (FROM)->c_cflag; \ + autotype((TO)->c_lflag) c_lflag = (FROM)->c_lflag; \ + __builtin_memcpy(&Cc1, (FROM)->c_cc + 000, 8); \ + __builtin_memcpy(&Cc2, (FROM)->c_cc + 010, 8); \ + __builtin_memcpy(&Cc3, (FROM)->c_cc + 020, 4); \ + autotype((TO)->c_ispeed) c_ispeed = (FROM)->c_ispeed; \ + autotype((TO)->c_ospeed) c_ospeed = (FROM)->c_ospeed; \ + (TO)->c_iflag = c_iflag; \ + (TO)->c_oflag = c_oflag; \ + (TO)->c_cflag = c_cflag; \ + (TO)->c_lflag = c_lflag; \ + __builtin_memcpy((TO)->c_cc + 000, &Cc1, 8); \ + __builtin_memcpy((TO)->c_cc + 010, &Cc2, 8); \ + __builtin_memcpy((TO)->c_cc + 020, &Cc3, 4); \ + (TO)->c_ispeed = c_ispeed; \ + (TO)->c_ospeed = c_ospeed; \ } while (0) -void *__termios2host(union metatermios *, const struct termios *) hidden; -void __termios2linux(struct termios *, const union metatermios *) hidden; - -COSMOPOLITAN_C_END_ -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ -#endif /* !ANSI */ #endif /* COSMOPOLITAN_LIBC_CALLS_TERMIOS_INTERNAL_H_ */ diff --git a/libc/calls/termios2host.c b/libc/calls/termios2host.c deleted file mode 100644 index a08507757..000000000 --- a/libc/calls/termios2host.c +++ /dev/null @@ -1,35 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/ioctl.h" -#include "libc/calls/struct/metatermios.internal.h" -#include "libc/calls/termios.h" -#include "libc/calls/termios.internal.h" -#include "libc/dce.h" - -void *__termios2host(union metatermios *t, const struct termios *lt) { - if (!IsXnu() && !IsFreebsd() && !IsOpenbsd() && !IsNetbsd()) { - return lt; - } else if (IsXnu()) { - COPY_TERMIOS(&t->xnu, lt); - return &t->xnu; - } else { - COPY_TERMIOS(&t->bsd, lt); - return &t->bsd; - } -} diff --git a/libc/calls/termios2linux.c b/libc/calls/termios2linux.c deleted file mode 100644 index ab775d69c..000000000 --- a/libc/calls/termios2linux.c +++ /dev/null @@ -1,33 +0,0 @@ -/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│ -│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│ -╞══════════════════════════════════════════════════════════════════════════════╡ -│ Copyright 2020 Justine Alexandra Roberts Tunney │ -│ │ -│ Permission to use, copy, modify, and/or distribute this software for │ -│ any purpose with or without fee is hereby granted, provided that the │ -│ above copyright notice and this permission notice appear in all copies. │ -│ │ -│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ -│ PERFORMANCE OF THIS SOFTWARE. │ -╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/calls/ioctl.h" -#include "libc/calls/struct/metatermios.internal.h" -#include "libc/calls/termios.h" -#include "libc/calls/termios.internal.h" -#include "libc/dce.h" - -void __termios2linux(struct termios *lt, const union metatermios *t) { - if (IsXnu()) { - COPY_TERMIOS(lt, &t->xnu); - } else if (IsFreebsd() || IsOpenbsd() || IsNetbsd()) { - COPY_TERMIOS(lt, &t->bsd); - } else { - memcpy(lt, &t->linux, sizeof(*lt)); - } -} diff --git a/libc/isystem/stat.h b/libc/isystem/stat.h deleted file mode 100644 index 586a99816..000000000 --- a/libc/isystem/stat.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef COSMOPOLITAN_LIBC_ISYSTEM_STAT_H_ -#define COSMOPOLITAN_LIBC_ISYSTEM_STAT_H_ -#include "libc/calls/calls.h" -#include "libc/calls/struct/stat.h" -#include "libc/calls/weirdtypes.h" -#include "libc/sysv/consts/s.h" -#endif /* COSMOPOLITAN_LIBC_ISYSTEM_STAT_H_ */ diff --git a/libc/isystem/sys/stat.h b/libc/isystem/sys/stat.h index cfc2635d6..d443c62f0 100644 --- a/libc/isystem/sys/stat.h +++ b/libc/isystem/sys/stat.h @@ -1,5 +1,10 @@ #ifndef LIBC_ISYSTEM_SYS_STAT_H_ #define LIBC_ISYSTEM_SYS_STAT_H_ #include "libc/calls/calls.h" +#include "libc/calls/struct/stat.h" +#include "libc/calls/struct/stat.macros.h" +#include "libc/calls/weirdtypes.h" #include "libc/sysv/consts/s.h" +#include "libc/sysv/consts/utime.h" +#include "libc/time/time.h" #endif diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 4cdaca8d1..89f7f33b4 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -1516,24 +1516,24 @@ syscon termios CS6 0b0000000000010000 0b0000000100000000 0b0000000100000000 syscon termios CS7 0b0000000000100000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000001000000000 0b0000000000100000 # termios.c_cflag flag for 7-bit characters syscon termios CS8 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # termios.c_cflag flag for 8-bit characters syscon termios CSIZE 0b0000000000110000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000001100000000 0b0000000000110000 # mask for CS𝑥 flags -syscon termios NCCS 32 32 32 32 20 32 # ARRAYLEN(termios.c_cc); faked xnu/freebsd/openbsd (originally 20) and faked nt -syscon termios VINTR 0 8 8 8 8 0 # termios.c_cc[VINTR]=𝑥 -syscon termios VQUIT 1 9 9 9 9 1 # termios.c_cc[VQUIT]=𝑥 -syscon termios VERASE 2 3 3 3 3 2 # termios.c_cc[VERASE]=𝑥 -syscon termios VKILL 3 5 5 5 5 3 # termios.c_cc[VKILL]=𝑥 -syscon termios VEOF 4 0 0 0 0 4 # termios.c_cc[VEOF]=𝑥 -syscon termios VTIME 5 17 17 17 17 5 # termios.c_cc[VTIME]=𝑥 sets non-canonical read timeout to 𝑥×𝟷𝟶𝟶ms which is needed when entering escape sequences manually with the escape key -syscon termios VMIN 6 16 16 16 16 6 # termios.c_cc[VMIN]=𝑥 in non-canonical mode can be set to 0 for non-blocking reads, 1 for single character raw mode reads, or higher to buffer -syscon termios VSWTC 7 0 0 0 0 7 # termios.c_cc[VSWTC]=𝑥 -syscon termios VSTART 8 12 12 12 12 8 # termios.c_cc[VSTART]=𝑥 -syscon termios VSTOP 9 13 13 13 13 9 # termios.c_cc[VSTOP]=𝑥 -syscon termios VSUSP 10 10 10 10 10 10 # termios.c_cc[VSUSP]=𝑥 defines suspend, i.e. Ctrl-Z (a.k.a. →, ^Z, SUB, 26, 032, 0x1A, ord('Z')^0b01000000); unix consensus -syscon termios VEOL 11 1 1 1 1 11 # termios.c_cc[VEOL]=𝑥 -syscon termios VEOL2 16 2 2 2 2 16 # termios.c_cc[VEOL2]=𝑥 -syscon termios VREPRINT 12 6 6 6 6 12 # termios.c_cc[VREPRINT]=𝑥 -syscon termios VDISCARD 13 15 15 15 15 13 # termios.c_cc[VDISCARD]=𝑥 -syscon termios VWERASE 14 4 4 4 4 14 # termios.c_cc[VWERASE]=𝑥 -syscon termios VLNEXT 15 14 14 14 14 15 # termios.c_cc[VLNEXT]=𝑥 +syscon termios NCCS 20 20 20 20 20 20 # ARRAYLEN(termios.c_cc); we schlep c_line into c_cc on linux +syscon termios VINTR 0+1 8 8 8 8 0 # termios.c_cc[VINTR]=𝑥 +syscon termios VQUIT 1+1 9 9 9 9 1 # termios.c_cc[VQUIT]=𝑥 +syscon termios VERASE 2+1 3 3 3 3 2 # termios.c_cc[VERASE]=𝑥 +syscon termios VKILL 3+1 5 5 5 5 3 # termios.c_cc[VKILL]=𝑥 +syscon termios VEOF 4+1 0 0 0 0 4 # termios.c_cc[VEOF]=𝑥 +syscon termios VTIME 5+1 17 17 17 17 5 # termios.c_cc[VTIME]=𝑥 sets non-canonical read timeout to 𝑥×𝟷𝟶𝟶ms which is needed when entering escape sequences manually with the escape key +syscon termios VMIN 6+1 16 16 16 16 6 # termios.c_cc[VMIN]=𝑥 in non-canonical mode can be set to 0 for non-blocking reads, 1 for single character raw mode reads, or higher to buffer +syscon termios VSWTC 7+1 0 0 0 0 7 # termios.c_cc[VSWTC]=𝑥 +syscon termios VSTART 8+1 12 12 12 12 8 # termios.c_cc[VSTART]=𝑥 +syscon termios VSTOP 9+1 13 13 13 13 9 # termios.c_cc[VSTOP]=𝑥 +syscon termios VSUSP 10+1 10 10 10 10 10 # termios.c_cc[VSUSP]=𝑥 defines suspend, i.e. Ctrl-Z (a.k.a. →, ^Z, SUB, 26, 032, 0x1A, ord('Z')^0b01000000); unix consensus +syscon termios VEOL 11+1 1 1 1 1 11 # termios.c_cc[VEOL]=𝑥 +syscon termios VREPRINT 12+1 6 6 6 6 12 # termios.c_cc[VREPRINT]=𝑥 +syscon termios VDISCARD 13+1 15 15 15 15 13 # termios.c_cc[VDISCARD]=𝑥 +syscon termios VWERASE 14+1 4 4 4 4 14 # termios.c_cc[VWERASE]=𝑥 +syscon termios VLNEXT 15+1 14 14 14 14 15 # termios.c_cc[VLNEXT]=𝑥 +syscon termios VEOL2 16+1 2 2 2 2 16 # termios.c_cc[VEOL2]=𝑥 syscon termios TIOCSERGETLSR 0x5459 0 0 0 0 0 # syscon termios TIOCSERGETMULTI 0x545a 0 0 0 0 0 # syscon termios TIOCSERSETMULTI 0x545b 0 0 0 0 0 # diff --git a/libc/sysv/consts/NCCS.S b/libc/sysv/consts/NCCS.S index 95c3953b0..93b1a046d 100644 --- a/libc/sysv/consts/NCCS.S +++ b/libc/sysv/consts/NCCS.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,NCCS,32,32,32,32,20,32 +.syscon termios,NCCS,20,20,20,20,20,20 diff --git a/libc/sysv/consts/VDISCARD.S b/libc/sysv/consts/VDISCARD.S index 44f2f56bf..56352d9e5 100644 --- a/libc/sysv/consts/VDISCARD.S +++ b/libc/sysv/consts/VDISCARD.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VDISCARD,13,15,15,15,15,13 +.syscon termios,VDISCARD,13+1,15,15,15,15,13 diff --git a/libc/sysv/consts/VEOF.S b/libc/sysv/consts/VEOF.S index 8297a43f4..2ca8fb1ce 100644 --- a/libc/sysv/consts/VEOF.S +++ b/libc/sysv/consts/VEOF.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VEOF,4,0,0,0,0,4 +.syscon termios,VEOF,4+1,0,0,0,0,4 diff --git a/libc/sysv/consts/VEOL.S b/libc/sysv/consts/VEOL.S index 40bd5b4a0..a09dfdc34 100644 --- a/libc/sysv/consts/VEOL.S +++ b/libc/sysv/consts/VEOL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VEOL,11,1,1,1,1,11 +.syscon termios,VEOL,11+1,1,1,1,1,11 diff --git a/libc/sysv/consts/VEOL2.S b/libc/sysv/consts/VEOL2.S index 8b06ff46a..c5376e531 100644 --- a/libc/sysv/consts/VEOL2.S +++ b/libc/sysv/consts/VEOL2.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VEOL2,16,2,2,2,2,16 +.syscon termios,VEOL2,16+1,2,2,2,2,16 diff --git a/libc/sysv/consts/VERASE.S b/libc/sysv/consts/VERASE.S index 74670898d..730e0dee9 100644 --- a/libc/sysv/consts/VERASE.S +++ b/libc/sysv/consts/VERASE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VERASE,2,3,3,3,3,2 +.syscon termios,VERASE,2+1,3,3,3,3,2 diff --git a/libc/sysv/consts/VINTR.S b/libc/sysv/consts/VINTR.S index 19c83ce59..c3952aebe 100644 --- a/libc/sysv/consts/VINTR.S +++ b/libc/sysv/consts/VINTR.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VINTR,0,8,8,8,8,0 +.syscon termios,VINTR,0+1,8,8,8,8,0 diff --git a/libc/sysv/consts/VKILL.S b/libc/sysv/consts/VKILL.S index cd88b887c..fe3ea7387 100644 --- a/libc/sysv/consts/VKILL.S +++ b/libc/sysv/consts/VKILL.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VKILL,3,5,5,5,5,3 +.syscon termios,VKILL,3+1,5,5,5,5,3 diff --git a/libc/sysv/consts/VLNEXT.S b/libc/sysv/consts/VLNEXT.S index c913f7bca..661ffe501 100644 --- a/libc/sysv/consts/VLNEXT.S +++ b/libc/sysv/consts/VLNEXT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VLNEXT,15,14,14,14,14,15 +.syscon termios,VLNEXT,15+1,14,14,14,14,15 diff --git a/libc/sysv/consts/VMIN.S b/libc/sysv/consts/VMIN.S index 4b52054df..254175e8b 100644 --- a/libc/sysv/consts/VMIN.S +++ b/libc/sysv/consts/VMIN.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VMIN,6,16,16,16,16,6 +.syscon termios,VMIN,6+1,16,16,16,16,6 diff --git a/libc/sysv/consts/VQUIT.S b/libc/sysv/consts/VQUIT.S index fe1176043..6e603d679 100644 --- a/libc/sysv/consts/VQUIT.S +++ b/libc/sysv/consts/VQUIT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VQUIT,1,9,9,9,9,1 +.syscon termios,VQUIT,1+1,9,9,9,9,1 diff --git a/libc/sysv/consts/VREPRINT.S b/libc/sysv/consts/VREPRINT.S index 7277eb621..ebc183242 100644 --- a/libc/sysv/consts/VREPRINT.S +++ b/libc/sysv/consts/VREPRINT.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VREPRINT,12,6,6,6,6,12 +.syscon termios,VREPRINT,12+1,6,6,6,6,12 diff --git a/libc/sysv/consts/VSTART.S b/libc/sysv/consts/VSTART.S index 4f31b516f..489a38370 100644 --- a/libc/sysv/consts/VSTART.S +++ b/libc/sysv/consts/VSTART.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VSTART,8,12,12,12,12,8 +.syscon termios,VSTART,8+1,12,12,12,12,8 diff --git a/libc/sysv/consts/VSTOP.S b/libc/sysv/consts/VSTOP.S index fdc369eee..55da19308 100644 --- a/libc/sysv/consts/VSTOP.S +++ b/libc/sysv/consts/VSTOP.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VSTOP,9,13,13,13,13,9 +.syscon termios,VSTOP,9+1,13,13,13,13,9 diff --git a/libc/sysv/consts/VSUSP.S b/libc/sysv/consts/VSUSP.S index 949b99864..735b6396e 100644 --- a/libc/sysv/consts/VSUSP.S +++ b/libc/sysv/consts/VSUSP.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VSUSP,10,10,10,10,10,10 +.syscon termios,VSUSP,10+1,10,10,10,10,10 diff --git a/libc/sysv/consts/VSWTC.S b/libc/sysv/consts/VSWTC.S index 1cc638c5e..c422d8f16 100644 --- a/libc/sysv/consts/VSWTC.S +++ b/libc/sysv/consts/VSWTC.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VSWTC,7,0,0,0,0,7 +.syscon termios,VSWTC,7+1,0,0,0,0,7 diff --git a/libc/sysv/consts/VTIME.S b/libc/sysv/consts/VTIME.S index 03ceb1590..7a31658c5 100644 --- a/libc/sysv/consts/VTIME.S +++ b/libc/sysv/consts/VTIME.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VTIME,5,17,17,17,17,5 +.syscon termios,VTIME,5+1,17,17,17,17,5 diff --git a/libc/sysv/consts/VWERASE.S b/libc/sysv/consts/VWERASE.S index e131e9f8f..b84b37091 100644 --- a/libc/sysv/consts/VWERASE.S +++ b/libc/sysv/consts/VWERASE.S @@ -1,2 +1,2 @@ #include "libc/sysv/consts/syscon.internal.h" -.syscon termios,VWERASE,14,4,4,4,4,14 +.syscon termios,VWERASE,14+1,4,4,4,4,14 diff --git a/libc/sysv/consts/termios.h b/libc/sysv/consts/termios.h index c1913d859..ed3edd650 100644 --- a/libc/sysv/consts/termios.h +++ b/libc/sysv/consts/termios.h @@ -59,7 +59,6 @@ extern const long IUTF8; extern const long IXANY; extern const long IXOFF; extern const long IXON; -extern const long NCCS; extern const long NETGRAPHDISC; extern const long NL1; extern const long NL2; @@ -257,7 +256,7 @@ COSMOPOLITAN_C_END_ #define IUTF8 SYMBOLIC(IUTF8) #define IXOFF SYMBOLIC(IXOFF) #define IXON SYMBOLIC(IXON) -#define NCCS LITERALLY(32) +#define NCCS LITERALLY(20) #define NETGRAPHDISC SYMBOLIC(NETGRAPHDISC) #define NMEADISC SYMBOLIC(NMEADISC) #define NOFLSH SYMBOLIC(NOFLSH) diff --git a/libc/zipos/stat-impl.c b/libc/zipos/stat-impl.c index 4d8a28451..c1e00e18d 100644 --- a/libc/zipos/stat-impl.c +++ b/libc/zipos/stat-impl.c @@ -39,6 +39,7 @@ int __zipos_stat_impl(struct Zipos *zipos, size_t cf, struct stat *st) { roundup(GetZipLfileCompressedSize(zipos->map + lf), 512) / 512; GetZipCfileTimestamps(zipos->map + cf, &st->st_mtim, &st->st_atim, &st->st_ctim, 0); + st->st_birthtim = st->st_ctim; return 0; } else { return einval(); diff --git a/third_party/chibicc/preprocess.c b/third_party/chibicc/preprocess.c index 7742b3d2c..b70605b7d 100644 --- a/third_party/chibicc/preprocess.c +++ b/third_party/chibicc/preprocess.c @@ -890,7 +890,7 @@ static Token *timestamp_macro(Token *tmpl) { if (stat(tmpl->file->name, &st) != 0) return new_str_token("??? ??? ?? ??:??:?? ????", tmpl); char buf[64]; - ctime_r(&st.st_mtime, buf); + ctime_r(&st.st_mtim.tv_sec, buf); buf[24] = '\0'; return new_str_token(buf, tmpl); } diff --git a/third_party/lz4cli/util.h b/third_party/lz4cli/util.h index b34fda8b3..e94380c2f 100644 --- a/third_party/lz4cli/util.h +++ b/third_party/lz4cli/util.h @@ -280,7 +280,7 @@ UTIL_STATIC int UTIL_setFileStat(const char *filename, struct stat *statbuf) return -1; timebuf.actime = time(NULL); - timebuf.modtime = statbuf->st_mtime; + timebuf.modtime = statbuf->st_mtim.tv_sec; res += utime(filename, &timebuf); /* set access and modification times */ #if !defined(_WIN32) diff --git a/third_party/python/Modules/_sqlite/module.c b/third_party/python/Modules/_sqlite/module.c index 9b1cc0d6d..a705160bb 100644 --- a/third_party/python/Modules/_sqlite/module.c +++ b/third_party/python/Modules/_sqlite/module.c @@ -333,6 +333,8 @@ PyMODINIT_FUNC PyInit__sqlite3(void) PyObject *tmp_obj; int i; + sqlite3_initialize(); + module = PyModule_Create(&_sqlite3module); if (!module || diff --git a/third_party/python/Modules/posixmodule.c b/third_party/python/Modules/posixmodule.c index 8c259bf5c..fe3218d51 100644 --- a/third_party/python/Modules/posixmodule.c +++ b/third_party/python/Modules/posixmodule.c @@ -11,6 +11,7 @@ #include "libc/calls/internal.h" #include "libc/calls/makedev.h" #include "libc/calls/struct/dirent.h" +#include "libc/calls/struct/stat.macros.h" #include "libc/calls/struct/winsize.h" #include "libc/calls/termios.h" #include "libc/calls/weirdtypes.h" diff --git a/third_party/python/pyconfig.h b/third_party/python/pyconfig.h index 8d35ed622..d8279fc8c 100644 --- a/third_party/python/pyconfig.h +++ b/third_party/python/pyconfig.h @@ -805,7 +805,7 @@ #define HAVE_STRUCT_PASSWD_PW_PASSWD 1 /* Define to 1 if `st_birthtime' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_BIRTHTIME */ +#define HAVE_STRUCT_STAT_ST_BIRTHTIME 1 /* Define to 1 if `st_blksize' is a member of `struct stat'. */ #define HAVE_STRUCT_STAT_ST_BLKSIZE 1 @@ -814,14 +814,16 @@ #define HAVE_STRUCT_STAT_ST_BLOCKS 1 /* Define to 1 if `st_flags' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_FLAGS */ +#define HAVE_STRUCT_STAT_ST_FLAGS 1 /* Define to 1 if `st_gen' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_GEN */ +#define HAVE_STRUCT_STAT_ST_GEN 1 /* Define to 1 if `st_rdev' is a member of `struct stat'. */ #define HAVE_STRUCT_STAT_ST_RDEV 1 +#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1 + /* Define to 1 if `tm_zone' is a member of `struct tm'. */ #define HAVE_STRUCT_TM_TM_ZONE 1