Commit: a5a679470ba738a710e43b04dfc5de04f6361c1d
Parent: 9cfa730cbaf2d69ddb25dd22c2230b11fd36c151
Author: Randy Palamar
Date: Wed, 4 Dec 2024 18:18:39 -0700
drop unnecessary fcntl call in fork_child
Since we are opening the file descriptor ourselves we can just set
the flags we want to begin with.
Diffstat:
2 files changed, 43 insertions(+), 47 deletions(-)
diff --git a/os_unix.c b/os_unix.c
@@ -1,10 +1,9 @@
/* See LICENSE for copyright details */
-#include <fcntl.h>
-#include <pty.h>
#include <pwd.h>
#include <sys/select.h>
#include <unistd.h>
+__attribute__((noreturn))
static void
execsh(char *defcmd)
{
@@ -28,47 +27,5 @@ execsh(char *defcmd)
execvp(sh, argv);
syscall1(SYS_exit_group, 1);
-}
-
-static linux_platform_process
-os_fork_child(char *cmd)
-{
- i32 n = 0;
- i64 m = syscall3(SYS_open, (iptr)"/dev/ptmx", O_RDWR|O_NOCTTY, 0);
- if (m > -4096UL) os_fatal(s8("os_fork_child: failed to open master terminal\n"));
- /* NOTE: first unlock the tty, then get a valid pty number */
- if (syscall3(SYS_ioctl, m, TIOCSPTLCK, (iptr)&n) || syscall3(SYS_ioctl, m, TIOCGPTN, (iptr)&n))
- os_fatal(s8("os_fork_child: failed to get a pty number\n"));
-
- u8 buffer[20] = {"/dev/pts/"};
- Stream sbuf = {.buf = buffer, .cap = 20, .widx = sizeof("/dev/pts/") - 1};
- stream_push_i64(&sbuf, n);
- stream_push_byte(&sbuf, 0);
-
- i64 s = syscall3(SYS_open, (iptr)sbuf.buf, O_RDWR|O_NOCTTY, 0);
- if (s > -4096UL) os_fatal(s8("os_fork_child: failed to open slave terminal\n"));
-
- i64 pid = syscall1(SYS_fork, 0);
- if (pid > -4096UL) os_fatal(s8("os_fork_child: failed to fork a child\n"));
-
- if (pid == 0) {
- syscall1(SYS_close, m);
- syscall1(SYS_setsid, 0);
- syscall2(SYS_dup2, s, 0);
- syscall2(SYS_dup2, s, 1);
- syscall2(SYS_dup2, s, 2);
- syscall3(SYS_ioctl, s, TIOCSCTTY, 0);
- if (s > 2) syscall1(SYS_close, s);
- execsh(cmd);
- }
- syscall1(SYS_close, s);
-
- /* TODO: why is this needed? are we blocking on write? */
- i32 flags = fcntl(m, F_GETFL);
- if (flags == -1)
- os_fatal(s8("os_fork_child: fcntl: F_GETFL\n"));
- if (fcntl(m, F_SETFL, flags | O_NONBLOCK) == -1)
- os_fatal(s8("os_fork_child: fcntl: F_SETFL\n"));
-
- return (linux_platform_process){.process_id = pid, .handle = m};
+ __builtin_unreachable();
}
diff --git a/platform_linux_common.c b/platform_linux_common.c
@@ -37,8 +37,8 @@
#define TIOCSCTTY 0x540E
#define TIOCSWINSZ 0x5414
-#define TIOCSPTLCK 0x145431 /* (un)lock pty */
-#define TIOCGPTN 0x245430 /* get pty number */
+#define TIOCSPTLCK 0x40045431 /* (un)lock pty */
+#define TIOCGPTN 0x80045430 /* get pty number */
#ifndef VERSION
#define VERSION "unknown"
@@ -289,6 +289,45 @@ os_child_exited(iptr pid)
return r == pid && W_IF_EXITED(status);
}
+static void execsh(char *);
+static linux_platform_process
+os_fork_child(char *cmd)
+{
+ i32 n = 0;
+
+ /* NOTE: we open in non-blocking mode so that we can try and fully drain the pipe
+ * before processing. Otherwise a single read will be limited to the page size */
+ i64 m = syscall3(SYS_open, (iptr)"/dev/ptmx", O_RDWR|O_NOCTTY|O_NONBLOCK|O_CLOEXEC, 0);
+ if (m > -4096UL) os_fatal(s8("os_fork_child: failed to open master terminal\n"));
+ /* NOTE: first unlock the tty, then get a valid pty number */
+ if (syscall3(SYS_ioctl, m, TIOCSPTLCK, (iptr)&n) || syscall3(SYS_ioctl, m, TIOCGPTN, (iptr)&n))
+ os_fatal(s8("os_fork_child: failed to get a pty number\n"));
+
+ u8 buffer[20] = {"/dev/pts/"};
+ Stream sbuf = {.buf = buffer, .cap = 20, .widx = sizeof("/dev/pts/") - 1};
+ stream_push_i64(&sbuf, n);
+ stream_push_byte(&sbuf, 0);
+
+ i64 s = syscall3(SYS_open, (iptr)sbuf.buf, O_RDWR|O_NOCTTY, 0);
+ if (s > -4096UL) os_fatal(s8("os_fork_child: failed to open slave terminal\n"));
+
+ i64 pid = syscall1(SYS_fork, 0);
+ if (pid > -4096UL) os_fatal(s8("os_fork_child: failed to fork a child\n"));
+
+ if (pid == 0) {
+ syscall1(SYS_setsid, 0);
+ syscall2(SYS_dup2, s, 0);
+ syscall2(SYS_dup2, s, 1);
+ syscall2(SYS_dup2, s, 2);
+ syscall3(SYS_ioctl, s, TIOCSCTTY, 0);
+ if (s > 2) syscall1(SYS_close, s);
+ execsh(cmd);
+ }
+ syscall1(SYS_close, s);
+
+ return (linux_platform_process){.process_id = pid, .handle = m};
+}
+
static PLATFORM_SET_TERMINAL_SIZE_FN(os_set_terminal_size)
{
u16 win_size[4];