From 053681cb97aa3204e4577b4f2773bd10f537cf9e Mon Sep 17 00:00:00 2001 From: Justine Tunney Date: Sat, 1 Jul 2023 00:17:33 -0700 Subject: [PATCH] Fix BSD regressions The recent change to crt.S that aggressively aligns the system-provided stack has been rolled back on non-Linux until we can find a better way, since it can cause a segfault early in execution on several platforms. This change fixes a regression in tcgetattr() and tcsetattr() on OpenBSD and NetBSD caused by 4778cd4d27131374053ea797e14021fea7bb3d55. This change has been tested across the runitd test fleet which is green. --- libc/calls/tcflow.c | 3 +-- libc/calls/tcgetattr.c | 5 +---- libc/calls/tcsetattr.c | 10 +-------- libc/crt/crt.S | 6 +++--- libc/sysv/consts.sh | 5 +++++ libc/sysv/consts/TCGETS.S | 2 ++ libc/sysv/consts/TCSETS.S | 2 ++ libc/sysv/consts/termios.h | 35 ++++++++++++++++---------------- test/libc/calls/printargs_test.c | 3 +-- 9 files changed, 34 insertions(+), 37 deletions(-) create mode 100644 libc/sysv/consts/TCGETS.S create mode 100644 libc/sysv/consts/TCSETS.S diff --git a/libc/calls/tcflow.c b/libc/calls/tcflow.c index 4df150e6b..258fb10d3 100644 --- a/libc/calls/tcflow.c +++ b/libc/calls/tcflow.c @@ -34,7 +34,6 @@ #define kNtPurgeRxabort 2 #define TCXONC 0x0000540A // linux -#define TIOCGETA 0x40487413 // bsd #define TIOCSTOP 0x2000746f // bsd #define TIOCSTART 0x2000746e // bsd #define TIOCIXON 0x20007481 // xnu @@ -52,7 +51,7 @@ static const char *DescribeFlow(char buf[12], int action) { static int sys_tcflow_bsd_write(int fd, int cc) { unsigned char c; struct termios_bsd term; - if (sys_ioctl(fd, TIOCGETA, &term) == -1) { + if (sys_ioctl(fd, TCGETS, &term) == -1) { return -1; } if ((c = term.c_cc[cc]) != _POSIX_VDISABLE && diff --git a/libc/calls/tcgetattr.c b/libc/calls/tcgetattr.c index c51eb6c95..54c3cdba6 100644 --- a/libc/calls/tcgetattr.c +++ b/libc/calls/tcgetattr.c @@ -28,9 +28,6 @@ #include "libc/str/str.h" #include "libc/sysv/errfuns.h" -#define TCGETS 0x00005401 // linux -#define TIOCGETA 0x40487413 // bsd - int tcgetattr_nt(int, struct termios *); static int tcgetattr_metal(int fd, struct termios *tio) { @@ -45,7 +42,7 @@ static int tcgetattr_metal(int fd, struct termios *tio) { static int tcgetattr_bsd(int fd, struct termios *tio) { int rc; union metatermios mt; - if ((rc = sys_ioctl(fd, TIOCGETA, &mt)) != -1) { + if ((rc = sys_ioctl(fd, TCGETS, &mt)) != -1) { if (IsXnu()) { COPY_TERMIOS(tio, &mt.xnu); } else { diff --git a/libc/calls/tcsetattr.c b/libc/calls/tcsetattr.c index 9899e1b1a..7040a5e77 100644 --- a/libc/calls/tcsetattr.c +++ b/libc/calls/tcsetattr.c @@ -31,13 +31,6 @@ #include "libc/sysv/consts/termios.h" #include "libc/sysv/errfuns.h" -#define TCSETS 0x5402 -#define TCSETSW 0x5403 -#define TCSETSF 0x5404 -#define TIOCSETA 0x80487414 -#define TIOCSETAW 0x80487415 -#define TIOCSETAF 0x80487416 - void __on_tcsetattr(int); int tcsetattr_nt(int, int, const struct termios *); @@ -80,8 +73,7 @@ static int tcsetattr_impl(int fd, int opt, const struct termios *tio) { if (IsLinux() || IsBsd()) { union metatermios mt; - return sys_ioctl(fd, (IsLinux() ? TCSETS : TIOCSETA) + opt, - __termios2host(&mt, tio)); + return sys_ioctl(fd, TCSETS + opt, __termios2host(&mt, tio)); } return enosys(); diff --git a/libc/crt/crt.S b/libc/crt/crt.S index 83a06c735..2a554ab4c 100644 --- a/libc/crt/crt.S +++ b/libc/crt/crt.S @@ -72,9 +72,9 @@ _start: // setup a stack frame // align stack to GetStackSize() so GetStackAddr() is fast .weak ape_stack_memsz - mov $ape_stack_memsz,%r8d - mov $ape_stack_align,%r9d - cmp $_HOSTMETAL,%cl + mov $ape_stack_memsz,%r9d + mov $ape_stack_align,%r8d + cmp $_HOSTLINUX,%cl cmove %r9d,%r8d neg %r8 and %r8,%rsp diff --git a/libc/sysv/consts.sh b/libc/sysv/consts.sh index 53189e503..963d90a25 100755 --- a/libc/sysv/consts.sh +++ b/libc/sysv/consts.sh @@ -1318,6 +1318,8 @@ syscon sched SCHED_RESET_ON_FORK 0x40000000 0x40000000 0 0 0 0 0 0 # = TIOCSETA → About 3,110 results (0.41 seconds) # # group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary +syscon termios TCGETS 0x5401 0x5401 0x40487413 0x40487413 0x402c7413 0x402c7413 0x402c7413 0x5401 # Gets console settings; tcgetattr(tty, argp) → ioctl(tty, TCGETS, struct termios *argp); polyfilled NT +syscon termios TCSETS 0x5402 0x5402 0x80487414 0x80487414 0x802c7414 0x802c7414 0x802c7414 0x5402 # Sets console settings; = ioctl(tty, TCSETS, const struct termios *argp); polyfilled NT syscon termios TIOCGWINSZ 0x5413 0x5413 1074295912 1074295912 1074295912 1074295912 1074295912 0x5413 # ioctl(tty, TIOCGWINSZ, struct winsize *argp); polyfilled NT syscon termios TIOCSWINSZ 0x5414 0x5414 0x80087467 0x80087467 0x80087467 0x80087467 0x80087467 0x5414 # ioctl(tty, TIOCSWINSZ, const struct winsize *argp) (faked NT) syscon termios TIOCINQ 0x541b 0x541b 0x4004667f 0x4004667f 0x4004667f 0x4004667f 0x4004667f 0x4004667f # [Linuxism] same as FIONREAD @@ -1441,6 +1443,9 @@ syscon termios VLNEXT 15+1 15+1 14 14 14 14 14 15 # termios. syscon termios VEOL2 16+1 16+1 2 2 2 2 2 16 # termios.c_cc[VEOL2]=𝑥 syscon termios _POSIX_VDISABLE 0 0 255 255 255 255 255 0 # termios.c_cc tombstone value +# tcflush() magic numbers +# +# group name GNU/Systemd GNU/Systemd (Aarch64) XNU's Not UNIX! MacOS (Arm64) FreeBSD OpenBSD NetBSD The New Technology Commentary syscon termios TCIFLUSH 0 0 1 1 1 1 1 0 # see tcflush; FREAD on BSD; faked nt syscon termios TCOFLUSH 1 1 2 2 2 2 2 1 # see tcflush; FWRITE on BSD; faked nt syscon termios TCIOFLUSH 2 2 3 3 3 3 3 2 # see tcflush; FREAD|FWRITE on BSD; faked nt diff --git a/libc/sysv/consts/TCGETS.S b/libc/sysv/consts/TCGETS.S new file mode 100644 index 000000000..8a7bf0cdb --- /dev/null +++ b/libc/sysv/consts/TCGETS.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon termios,TCGETS,0x5401,0x5401,0x40487413,0x40487413,0x402c7413,0x402c7413,0x402c7413,0x5401 diff --git a/libc/sysv/consts/TCSETS.S b/libc/sysv/consts/TCSETS.S new file mode 100644 index 000000000..2bad14688 --- /dev/null +++ b/libc/sysv/consts/TCSETS.S @@ -0,0 +1,2 @@ +#include "libc/sysv/consts/syscon.internal.h" +.syscon termios,TCSETS,0x5402,0x5402,0x80487414,0x80487414,0x802c7414,0x802c7414,0x802c7414,0x5402 diff --git a/libc/sysv/consts/termios.h b/libc/sysv/consts/termios.h index 8f5c0ee38..cb7ad7a10 100644 --- a/libc/sysv/consts/termios.h +++ b/libc/sysv/consts/termios.h @@ -73,12 +73,6 @@ extern const uint32_t TAB1; extern const uint32_t TAB2; extern const uint32_t TAB3; extern const uint32_t TABDLY; -extern const int TCIFLUSH; -extern const int TCIOFLUSH; -extern const int TCOFLUSH; -extern const int TCSADRAIN; -extern const int TCSAFLUSH; -extern const int TCSANOW; extern const uint64_t TIOCCONS; extern const uint64_t TIOCGETD; extern const uint64_t TIOCGWINSZ; @@ -116,11 +110,6 @@ extern const uint32_t XCASE; extern const uint32_t XTABS; extern const uint32_t CRTSCTS; -#define TCOOFF 0 -#define TCOON 1 -#define TCIOFF 2 -#define TCION 3 - #define BRKINT 0x02 #define ICRNL 0x0100 #define IGNBRK 0x01 @@ -202,12 +191,6 @@ extern const uint32_t CRTSCTS; #define PARENB PARENB #define PARODD PARODD #define PENDIN PENDIN -#define TCIFLUSH TCIFLUSH -#define TCIOFLUSH TCIOFLUSH -#define TCOFLUSH TCOFLUSH -#define TCSADRAIN 1 -#define TCSAFLUSH 2 -#define TCSANOW 0 #define TIOCCONS TIOCCONS #define TIOCGETD TIOCGETD #define TIOCGWINSZ TIOCGWINSZ @@ -240,8 +223,26 @@ extern const uint32_t CRTSCTS; #define VWERASE VWERASE #define XCASE XCASE +/* tcsetattr() */ +#define TCSANOW 0 +#define TCSAFLUSH 2 +#define TCSADRAIN 1 +extern const unsigned long TCGETS; /* use tcgetattr() */ +extern const unsigned long TCSETS; /* use tcsetattr() */ +/* tcflush() */ +extern const int TCIFLUSH; +extern const int TCOFLUSH; +extern const int TCIOFLUSH; +#define TCIFLUSH TCIFLUSH +#define TCOFLUSH TCOFLUSH +#define TCIOFLUSH TCIOFLUSH +/* tcflow() */ +#define TCOOFF 0 +#define TCOON 1 +#define TCIOFF 2 +#define TCION 3 COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/test/libc/calls/printargs_test.c b/test/libc/calls/printargs_test.c index 117d838be..d2d3029da 100644 --- a/test/libc/calls/printargs_test.c +++ b/test/libc/calls/printargs_test.c @@ -17,8 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" -#include "libc/runtime/internal.h" -#include "libc/sysv/consts/o.h" +#include "libc/runtime/runtime.h" #include "libc/testlib/testlib.h" #include "libc/x/x.h"