From e97fa8b03803dfb5d2046d9b2ebecbee85a0e1f9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 12 Feb 2024 18:24:07 -0700 Subject: [PATCH] std.os.termios: add type safety to cflag field This creates `tc_cflag_t` even though such a type is not defined by libc. I also collected the missing flag bits from all the operating systems. --- lib/std/c.zig | 152 ++++++++++++++++++++++++++++++++++++++++-- lib/std/c/darwin.zig | 20 ------ lib/std/c/netbsd.zig | 21 ------ lib/std/c/openbsd.zig | 21 ------ lib/std/os.zig | 2 + lib/std/os/linux.zig | 43 ++++++++---- 6 files changed, 178 insertions(+), 81 deletions(-) diff --git a/lib/std/c.zig b/lib/std/c.zig index 4333a191e6..13d2605de0 100644 --- a/lib/std/c.zig +++ b/lib/std/c.zig @@ -795,7 +795,7 @@ pub const termios = switch (native_os) { .macos, .ios, .tvos, .watchos => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, - cflag: tcflag_t, + cflag: tc_cflag_t, lflag: tcflag_t, cc: [NCCS]cc_t, ispeed: speed_t align(8), @@ -804,7 +804,7 @@ pub const termios = switch (native_os) { .freebsd, .kfreebsd, .netbsd, .dragonfly, .openbsd => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, - cflag: tcflag_t, + cflag: tc_cflag_t, lflag: tcflag_t, cc: [NCCS]cc_t, ispeed: speed_t, @@ -813,7 +813,7 @@ pub const termios = switch (native_os) { .haiku => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, - cflag: tcflag_t, + cflag: tc_cflag_t, lflag: tcflag_t, line: cc_t, ispeed: speed_t, @@ -823,14 +823,14 @@ pub const termios = switch (native_os) { .solaris, .illumos => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, - cflag: tcflag_t, + cflag: tc_cflag_t, lflag: tcflag_t, cc: [NCCS]cc_t, }, .emscripten, .wasi => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, - cflag: tcflag_t, + cflag: tc_cflag_t, lflag: tcflag_t, line: std.c.cc_t, cc: [NCCS]cc_t, @@ -1041,6 +1041,148 @@ pub const tc_oflag_t = switch (native_os) { else => @compileError("target libc does not have tc_oflag_t"), }; +pub const CSIZE = switch (native_os) { + .linux => std.os.linux.CSIZE, + .haiku => enum(u1) { CS7, CS8 }, + else => enum(u2) { CS5, CS6, CS7, CS8 }, +}; + +pub const tc_cflag_t = switch (native_os) { + .linux => std.os.linux.tc_cflag_t, + .macos, .ios, .tvos, .watchos => packed struct(u32) { + CIGNORE: bool = false, + _1: u5 = 0, + CSTOPB: bool = false, + _7: u1 = 0, + CSIZE: CSIZE = .CS5, + _10: u1 = 0, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + CCTS_OFLOW: bool = false, + CRTS_IFLOW: bool = false, + CDTR_IFLOW: bool = false, + CDSR_OFLOW: bool = false, + CCAR_OFLOW: bool = false, + _: u11 = 0, + }, + .freebsd, .kfreebsd => packed struct(u32) { + CIGNORE: bool = false, + _1: u7 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + CCTS_OFLOW: bool = false, + CRTS_IFLOW: bool = false, + CDTR_IFLOW: bool = false, + CDSR_OFLOW: bool = false, + CCAR_OFLOW: bool = false, + CNO_RTSDTR: bool = false, + _: u10 = 0, + }, + .netbsd => packed struct(u32) { + CIGNORE: bool = false, + _1: u7 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + CRTSCTS: bool = false, + CDTRCTS: bool = false, + _18: u2 = 0, + MDMBUF: bool = false, + _: u11 = 0, + }, + .dragonfly => packed struct(u32) { + CIGNORE: bool = false, + _1: u7 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + CCTS_OFLOW: bool = false, + CRTS_IFLOW: bool = false, + CDTR_IFLOW: bool = false, + CDSR_OFLOW: bool = false, + CCAR_OFLOW: bool = false, + _: u11 = 0, + }, + .openbsd => packed struct(u32) { + CIGNORE: bool = false, + _1: u7 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + CRTSCTS: bool = false, + _17: u3 = 0, + MDMBUF: bool = false, + _: u11 = 0, + }, + .haiku => packed struct(u32) { + _0: u5 = 0, + CSIZE: CSIZE = .CS7, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + XLOBLK: bool = false, + CTSFLOW: bool = false, + RTSFLOW: bool = false, + _: u17 = 0, + }, + .solaris, .illumos => packed struct(u32) { + _0: u4 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + RCV1EN: bool = false, + XMT1EN: bool = false, + LOBLK: bool = false, + XCLUDE: bool = false, + _16: u4 = 0, + PAREXT: bool = false, + CBAUDEXT: bool = false, + CIBAUDEXT: bool = false, + _23: u7 = 0, + CRTSXOFF: bool = false, + CRTSCTS: bool = false, + }, + .wasi, .emscripten => packed struct(u32) { + _0: u4 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + _: u20 = 0, + }, + else => @compileError("target libc does not have tc_cflag_t"), +}; + pub const tcflag_t = switch (native_os) { .linux => std.os.linux.tcflag_t, .macos, .ios, .tvos, .watchos => u64, diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 489cdc8bc0..27ad3d68e6 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -2692,26 +2692,6 @@ pub const SHUT = struct { pub const RDWR = 2; }; -pub const CIGNORE: tcflag_t = 0x00000001; // ignore control flags -pub const CSIZE: tcflag_t = 0x00000300; // character size mask -pub const CS5: tcflag_t = 0x00000000; // 5 bits (pseudo) -pub const CS6: tcflag_t = 0x00000100; // 6 bits -pub const CS7: tcflag_t = 0x00000200; // 7 bits -pub const CS8: tcflag_t = 0x00000300; // 8 bits -pub const CSTOPB: tcflag_t = 0x0000040; // send 2 stop bits -pub const CREAD: tcflag_t = 0x00000800; // enable receiver -pub const PARENB: tcflag_t = 0x00001000; // parity enable -pub const PARODD: tcflag_t = 0x00002000; // odd parity, else even -pub const HUPCL: tcflag_t = 0x00004000; // hang up on last close -pub const CLOCAL: tcflag_t = 0x00008000; // ignore modem status lines -pub const CCTS_OFLOW: tcflag_t = 0x00010000; // CTS flow control of output -pub const CRTSCTS: tcflag_t = (CCTS_OFLOW | CRTS_IFLOW); -pub const CRTS_IFLOW: tcflag_t = 0x00020000; // RTS flow control of input -pub const CDTR_IFLOW: tcflag_t = 0x00040000; // DTR flow control of input -pub const CDSR_OFLOW: tcflag_t = 0x00080000; // DSR flow control of output -pub const CCAR_OFLOW: tcflag_t = 0x00100000; // DCD flow control of output -pub const MDMBUF: tcflag_t = 0x00100000; // old name for CCAR_OFLOW - pub const ECHOKE: tcflag_t = 0x00000001; // visual erase for line kill pub const ECHOE: tcflag_t = 0x00000002; // visually erase chars pub const ECHOK: tcflag_t = 0x00000004; // echo NL after line kill diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig index 989c579d0e..b5c132df12 100644 --- a/lib/std/c/netbsd.zig +++ b/lib/std/c/netbsd.zig @@ -806,27 +806,6 @@ pub const T = struct { pub const IOCXMTFRAME = 0x80087444; }; - -// Control flags - hardware control of terminal -pub const CIGNORE: tcflag_t = 0x00000001; // ignore control flags -pub const CSIZE: tcflag_t = 0x00000300; // character size mask -pub const CS5: tcflag_t = 0x00000000; // 5 bits (pseudo) -pub const CS6: tcflag_t = 0x00000100; // 6 bits -pub const CS7: tcflag_t = 0x00000200; // 7 bits -pub const CS8: tcflag_t = 0x00000300; // 8 bits -pub const CSTOPB: tcflag_t = 0x00000400; // send 2 stop bits -pub const CREAD: tcflag_t = 0x00000800; // enable receiver -pub const PARENB: tcflag_t = 0x00001000; // parity enable -pub const PARODD: tcflag_t = 0x00002000; // odd parity, else even -pub const HUPCL: tcflag_t = 0x00004000; // hang up on last close -pub const CLOCAL: tcflag_t = 0x00008000; // ignore modem status lines -pub const CRTSCTS: tcflag_t = 0x00010000; // RTS/CTS full-duplex flow control -pub const CRTS_IFLOW: tcflag_t = CRTSCTS; // XXX compat -pub const CCTS_OFLOW: tcflag_t = CRTSCTS; // XXX compat -pub const CDTRCTS: tcflag_t = 0x00020000; // DTR/CTS full-duplex flow control -pub const MDMBUF: tcflag_t = 0x00100000; // DTR/DCD hardware flow control -pub const CHWFLOW: tcflag_t = (MDMBUF | CRTSCTS | CDTRCTS); // all types of hw flow control - // Commands passed to tcsetattr() for setting the termios structure. pub const TCSA = struct { pub const NOW = 0; // make change immediate diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig index 86130ed1a8..8d1df592d7 100644 --- a/lib/std/c/openbsd.zig +++ b/lib/std/c/openbsd.zig @@ -768,27 +768,6 @@ pub const AUTH = struct { pub const ALLOW: c_int = (OKAY | ROOTOKAY | SECURE); }; - - -// Control flags - hardware control of terminal -pub const CIGNORE: tcflag_t = 0x00000001; // ignore control flags -pub const CSIZE: tcflag_t = 0x00000300; // character size mask -pub const CS5: tcflag_t = 0x00000000; // 5 bits (pseudo) -pub const CS6: tcflag_t = 0x00000100; // 6 bits -pub const CS7: tcflag_t = 0x00000200; // 7 bits -pub const CS8: tcflag_t = 0x00000300; // 8 bits -pub const CSTOPB: tcflag_t = 0x00000400; // send 2 stop bits -pub const CREAD: tcflag_t = 0x00000800; // enable receiver -pub const PARENB: tcflag_t = 0x00001000; // parity enable -pub const PARODD: tcflag_t = 0x00002000; // odd parity, else even -pub const HUPCL: tcflag_t = 0x00004000; // hang up on last close -pub const CLOCAL: tcflag_t = 0x00008000; // ignore modem status lines -pub const CRTSCTS: tcflag_t = 0x00010000; // RTS/CTS full-duplex flow control -pub const CRTS_IFLOW: tcflag_t = CRTSCTS; // XXX compat -pub const CCTS_OFLOW: tcflag_t = CRTSCTS; // XXX compat -pub const MDMBUF: tcflag_t = 0x00100000; // DTR/DCD hardware flow control -pub const CHWFLOW: tcflag_t = (MDMBUF | CRTSCTS); // all types of hw flow control - // Commands passed to tcsetattr() for setting the termios structure. pub const TCSA = struct { pub const NOW = 0; // make change immediate diff --git a/lib/std/os.zig b/lib/std/os.zig index fcac0d1bb4..2db77ea980 100644 --- a/lib/std/os.zig +++ b/lib/std/os.zig @@ -184,11 +184,13 @@ pub const uid_t = system.uid_t; pub const user_desc = system.user_desc; pub const utsname = system.utsname; +pub const CSIZE = system.CSIZE; pub const NCCS = system.NCCS; pub const speed_t = system.speed_t; pub const tcflag_t = system.tcflag_t; pub const tc_iflag_t = system.tc_iflag_t; pub const tc_oflag_t = system.tc_oflag_t; +pub const tc_cflag_t = system.tc_cflag_t; pub const F_OK = system.F_OK; pub const R_OK = system.R_OK; diff --git a/lib/std/os/linux.zig b/lib/std/os/linux.zig index 40a77d54e8..42ab82b2ab 100644 --- a/lib/std/os/linux.zig +++ b/lib/std/os/linux.zig @@ -5120,6 +5120,33 @@ pub const tc_oflag_t = switch (native_arch) { }, }; +pub const CSIZE = enum(u2) { CS5, CS6, CS7, CS8 }; + +pub const tc_cflag_t = switch (native_arch) { + .powerpc, .powerpcle, .powerpc64, .powerpc64le => packed struct(u32) { + _0: u8 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + _: u16 = 0, + }, + else => packed struct(u32) { + _0: u4 = 0, + CSIZE: CSIZE = .CS5, + CSTOPB: bool = false, + CREAD: bool = false, + PARENB: bool = false, + PARODD: bool = false, + HUPCL: bool = false, + CLOCAL: bool = false, + _: u20 = 0, + }, +}; + pub const cc_t = switch (native_arch) { .mips, .mipsel, .mips64, .mips64el => enum(u8) { VINTR = 0, @@ -5182,18 +5209,6 @@ pub const cc_t = switch (native_arch) { pub const tcflag_t = u32; -pub const CSIZE: tcflag_t = 48; -pub const CS5: tcflag_t = 0; -pub const CS6: tcflag_t = 16; -pub const CS7: tcflag_t = 32; -pub const CS8: tcflag_t = 48; -pub const CSTOPB: tcflag_t = 64; -pub const CREAD: tcflag_t = 128; -pub const PARENB: tcflag_t = 256; -pub const PARODD: tcflag_t = 512; -pub const HUPCL: tcflag_t = 1024; -pub const CLOCAL: tcflag_t = 2048; - pub const ISIG: tcflag_t = 1; pub const ICANON: tcflag_t = 2; pub const ECHO: tcflag_t = 8; @@ -5215,7 +5230,7 @@ pub const termios = switch (native_arch) { .powerpc, .powerpcle, .powerpc64, .powerpc64le => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, - cflag: tcflag_t, + cflag: tc_cflag_t, lflag: tcflag_t, cc: [NCCS]cc_t, line: cc_t, @@ -5225,7 +5240,7 @@ pub const termios = switch (native_arch) { else => extern struct { iflag: tc_iflag_t, oflag: tc_oflag_t, - cflag: tcflag_t, + cflag: tc_cflag_t, lflag: tcflag_t, line: cc_t, cc: [NCCS]cc_t,