diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2024-09-15 12:20:58 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-15 12:20:58 -0700 |
commit | 057d27a9d6ef0bb2ee5130704c45b9e9197e7c36 (patch) | |
tree | c08b0d80b543cc18dd1dec97dde9885b8a50b375 /src/nvim/os/pty_process_unix.c | |
parent | 5792546777332361a9ac49107e46149c703de90e (diff) | |
download | rneovim-057d27a9d6ef0bb2ee5130704c45b9e9197e7c36.tar.gz rneovim-057d27a9d6ef0bb2ee5130704c45b9e9197e7c36.tar.bz2 rneovim-057d27a9d6ef0bb2ee5130704c45b9e9197e7c36.zip |
refactor: rename "process" => "proc" #30387
Problem:
- "process" is often used as a verb (`multiqueue_process_events`), which
is ambiguous for cases where it's used as a topic.
- The documented naming convention for processes is "proc".
- `:help dev-name-common`
- Shorter is better, when it doesn't harm readability or
discoverability.
Solution:
Rename "process" => "proc" in all C symbols and module names.
Diffstat (limited to 'src/nvim/os/pty_process_unix.c')
-rw-r--r-- | src/nvim/os/pty_process_unix.c | 417 |
1 files changed, 0 insertions, 417 deletions
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c deleted file mode 100644 index cfa4dcada7..0000000000 --- a/src/nvim/os/pty_process_unix.c +++ /dev/null @@ -1,417 +0,0 @@ -// Some of the code came from pangoterm and libuv - -#include <assert.h> -#include <errno.h> -#include <fcntl.h> -#include <signal.h> -#include <stdlib.h> -#include <string.h> -#include <sys/ioctl.h> -#include <sys/wait.h> -#include <uv.h> - -// forkpty is not in POSIX, so headers are platform-specific -#if defined(__FreeBSD__) || defined(__DragonFly__) -# include <libutil.h> -#elif defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) -# include <util.h> -#elif defined(__sun) -# include <fcntl.h> -# include <signal.h> -# include <sys/stream.h> -# include <sys/syscall.h> -# include <unistd.h> -#else -# include <pty.h> -#endif - -#ifdef __APPLE__ -# include <crt_externs.h> -#endif - -#include "auto/config.h" -#include "klib/klist.h" -#include "nvim/eval/typval.h" -#include "nvim/event/defs.h" -#include "nvim/event/loop.h" -#include "nvim/event/process.h" -#include "nvim/log.h" -#include "nvim/os/fs.h" -#include "nvim/os/os_defs.h" -#include "nvim/os/pty_process.h" -#include "nvim/os/pty_process_unix.h" -#include "nvim/types_defs.h" - -#ifdef INCLUDE_GENERATED_DECLARATIONS -# include "os/pty_process_unix.c.generated.h" -#endif - -#if defined(__sun) && !defined(HAVE_FORKPTY) - -// this header defines STR, just as nvim.h, but it is defined as ('S'<<8), -// to avoid #undef STR, #undef STR, #define STR ('S'<<8) just delay the -// inclusion of the header even though it gets include out of order. -# include <sys/stropts.h> - -static int openpty(int *amaster, int *aslave, char *name, struct termios *termp, - struct winsize *winp) -{ - int slave = -1; - int master = open("/dev/ptmx", O_RDWR); - if (master == -1) { - goto error; - } - - // grantpt will invoke a setuid program to change permissions - // and might fail if SIGCHLD handler is set, temporarily reset - // while running - void (*sig_saved)(int) = signal(SIGCHLD, SIG_DFL); - int res = grantpt(master); - signal(SIGCHLD, sig_saved); - - if (res == -1 || unlockpt(master) == -1) { - goto error; - } - - char *slave_name = ptsname(master); - if (slave_name == NULL) { - goto error; - } - - slave = open(slave_name, O_RDWR|O_NOCTTY); - if (slave == -1) { - goto error; - } - - // ptem emulates a terminal when used on a pseudo terminal driver, - // must be pushed before ldterm - ioctl(slave, I_PUSH, "ptem"); - // ldterm provides most of the termio terminal interface - ioctl(slave, I_PUSH, "ldterm"); - // ttcompat compatibility with older terminal ioctls - ioctl(slave, I_PUSH, "ttcompat"); - - if (termp) { - tcsetattr(slave, TCSAFLUSH, termp); - } - if (winp) { - ioctl(slave, TIOCSWINSZ, winp); - } - - *amaster = master; - *aslave = slave; - // ignoring name, not passed and size is unknown in the API - - return 0; - -error: - if (slave != -1) { - close(slave); - } - if (master != -1) { - close(master); - } - return -1; -} - -static int login_tty(int fd) -{ - setsid(); - if (ioctl(fd, TIOCSCTTY, NULL) == -1) { - return -1; - } - - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - dup2(fd, STDERR_FILENO); - if (fd > STDERR_FILENO) { - close(fd); - } - - return 0; -} - -static pid_t forkpty(int *amaster, char *name, struct termios *termp, struct winsize *winp) -{ - int master, slave; - if (openpty(&master, &slave, name, termp, winp) == -1) { - return -1; - } - - pid_t pid = fork(); - switch (pid) { - case -1: - close(master); - close(slave); - return -1; - case 0: - close(master); - login_tty(slave); - return 0; - default: - close(slave); - *amaster = master; - return pid; - } -} - -#endif - -/// @returns zero on success, or negative error code -int pty_process_spawn(PtyProcess *ptyproc) - FUNC_ATTR_NONNULL_ALL -{ - // termios initialized at first use - static struct termios termios_default; - if (!termios_default.c_cflag) { - init_termios(&termios_default); - } - - int status = 0; // zero or negative error code (libuv convention) - Process *proc = (Process *)ptyproc; - assert(proc->err.s.closed); - uv_signal_start(&proc->loop->children_watcher, chld_handler, SIGCHLD); - ptyproc->winsize = (struct winsize){ ptyproc->height, ptyproc->width, 0, 0 }; - uv_disable_stdio_inheritance(); - int master; - int pid = forkpty(&master, NULL, &termios_default, &ptyproc->winsize); - - if (pid < 0) { - status = -errno; - ELOG("forkpty failed: %s", strerror(errno)); - return status; - } else if (pid == 0) { - init_child(ptyproc); // never returns - } - - // make sure the master file descriptor is non blocking - int master_status_flags = fcntl(master, F_GETFL); - if (master_status_flags == -1) { - status = -errno; - ELOG("Failed to get master descriptor status flags: %s", strerror(errno)); - goto error; - } - if (fcntl(master, F_SETFL, master_status_flags | O_NONBLOCK) == -1) { - status = -errno; - ELOG("Failed to make master descriptor non-blocking: %s", strerror(errno)); - goto error; - } - - // Other jobs and providers should not get a copy of this file descriptor. - if (os_set_cloexec(master) == -1) { - status = -errno; - ELOG("Failed to set CLOEXEC on ptmx file descriptor"); - goto error; - } - - if (!proc->in.closed - && (status = set_duplicating_descriptor(master, &proc->in.uv.pipe))) { - goto error; - } - if (!proc->out.s.closed - && (status = set_duplicating_descriptor(master, &proc->out.s.uv.pipe))) { - goto error; - } - - ptyproc->tty_fd = master; - proc->pid = pid; - return 0; - -error: - close(master); - kill(pid, SIGKILL); - waitpid(pid, NULL, 0); - return status; -} - -const char *pty_process_tty_name(PtyProcess *ptyproc) -{ - return ptsname(ptyproc->tty_fd); -} - -void pty_process_resize(PtyProcess *ptyproc, uint16_t width, uint16_t height) - FUNC_ATTR_NONNULL_ALL -{ - ptyproc->winsize = (struct winsize){ height, width, 0, 0 }; - ioctl(ptyproc->tty_fd, TIOCSWINSZ, &ptyproc->winsize); -} - -void pty_process_close(PtyProcess *ptyproc) - FUNC_ATTR_NONNULL_ALL -{ - pty_process_close_master(ptyproc); - Process *proc = (Process *)ptyproc; - if (proc->internal_close_cb) { - proc->internal_close_cb(proc); - } -} - -void pty_process_close_master(PtyProcess *ptyproc) FUNC_ATTR_NONNULL_ALL -{ - if (ptyproc->tty_fd >= 0) { - close(ptyproc->tty_fd); - ptyproc->tty_fd = -1; - } -} - -void pty_process_teardown(Loop *loop) -{ - uv_signal_stop(&loop->children_watcher); -} - -static void init_child(PtyProcess *ptyproc) - FUNC_ATTR_NONNULL_ALL -{ -#if defined(HAVE__NSGETENVIRON) -# define environ (*_NSGetEnviron()) -#else - extern char **environ; -#endif - // New session/process-group. #6530 - setsid(); - - signal(SIGCHLD, SIG_DFL); - signal(SIGHUP, SIG_DFL); - signal(SIGINT, SIG_DFL); - signal(SIGQUIT, SIG_DFL); - signal(SIGTERM, SIG_DFL); - signal(SIGALRM, SIG_DFL); - - Process *proc = (Process *)ptyproc; - if (proc->cwd && os_chdir(proc->cwd) != 0) { - ELOG("chdir(%s) failed: %s", proc->cwd, strerror(errno)); - return; - } - - const char *prog = process_get_exepath(proc); - - assert(proc->env); - environ = tv_dict_to_env(proc->env); - execvp(prog, proc->argv); - ELOG("execvp(%s) failed: %s", prog, strerror(errno)); - - _exit(122); // 122 is EXEC_FAILED in the Vim source. -} - -static void init_termios(struct termios *termios) FUNC_ATTR_NONNULL_ALL -{ - // Taken from pangoterm - termios->c_iflag = ICRNL|IXON; - termios->c_oflag = OPOST|ONLCR; -#ifdef TAB0 - termios->c_oflag |= TAB0; -#endif - termios->c_cflag = CS8|CREAD; - termios->c_lflag = ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK; - - // not using cfsetspeed, not available on all platforms - cfsetispeed(termios, 38400); - cfsetospeed(termios, 38400); - -#ifdef IUTF8 - termios->c_iflag |= IUTF8; -#endif -#ifdef NL0 - termios->c_oflag |= NL0; -#endif -#ifdef CR0 - termios->c_oflag |= CR0; -#endif -#ifdef BS0 - termios->c_oflag |= BS0; -#endif -#ifdef VT0 - termios->c_oflag |= VT0; -#endif -#ifdef FF0 - termios->c_oflag |= FF0; -#endif -#ifdef ECHOCTL - termios->c_lflag |= ECHOCTL; -#endif -#ifdef ECHOKE - termios->c_lflag |= ECHOKE; -#endif - - termios->c_cc[VINTR] = 0x1f & 'C'; - termios->c_cc[VQUIT] = 0x1f & '\\'; - termios->c_cc[VERASE] = 0x7f; - termios->c_cc[VKILL] = 0x1f & 'U'; - termios->c_cc[VEOF] = 0x1f & 'D'; - termios->c_cc[VEOL] = _POSIX_VDISABLE; - termios->c_cc[VEOL2] = _POSIX_VDISABLE; - termios->c_cc[VSTART] = 0x1f & 'Q'; - termios->c_cc[VSTOP] = 0x1f & 'S'; - termios->c_cc[VSUSP] = 0x1f & 'Z'; - termios->c_cc[VREPRINT] = 0x1f & 'R'; - termios->c_cc[VWERASE] = 0x1f & 'W'; - termios->c_cc[VLNEXT] = 0x1f & 'V'; - termios->c_cc[VMIN] = 1; - termios->c_cc[VTIME] = 0; -} - -static int set_duplicating_descriptor(int fd, uv_pipe_t *pipe) - FUNC_ATTR_NONNULL_ALL -{ - int status = 0; // zero or negative error code (libuv convention) - int fd_dup = dup(fd); - if (fd_dup < 0) { - status = -errno; - ELOG("Failed to dup descriptor %d: %s", fd, strerror(errno)); - return status; - } - - if (os_set_cloexec(fd_dup) == -1) { - status = -errno; - ELOG("Failed to set CLOEXEC on duplicate fd"); - goto error; - } - - status = uv_pipe_open(pipe, fd_dup); - if (status) { - ELOG("Failed to set pipe to descriptor %d: %s", - fd_dup, uv_strerror(status)); - goto error; - } - return status; - -error: - close(fd_dup); - return status; -} - -static void chld_handler(uv_signal_t *handle, int signum) -{ - int stat = 0; - int pid; - - Loop *loop = handle->loop->data; - - kl_iter(WatcherPtr, loop->children, current) { - Process *proc = (*current)->data; - do { - pid = waitpid(proc->pid, &stat, WNOHANG); - } while (pid < 0 && errno == EINTR); - - if (pid <= 0) { - continue; - } - - if (WIFEXITED(stat)) { - proc->status = WEXITSTATUS(stat); - } else if (WIFSIGNALED(stat)) { - proc->status = 128 + WTERMSIG(stat); - } - proc->internal_exit_cb(proc); - } -} - -PtyProcess pty_process_init(Loop *loop, void *data) -{ - PtyProcess rv; - rv.process = process_init(loop, kProcessTypePty, data); - rv.width = 80; - rv.height = 24; - rv.tty_fd = -1; - return rv; -} |