aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/os
diff options
context:
space:
mode:
authorMatthew Malcomson <hardenedapple@gmail.com>2017-01-21 14:11:30 +0000
committerJustin M. Keyes <justinkz@gmail.com>2017-03-17 12:20:51 +0100
commitf6946c68aee90c6ae8337b3e42c72943e37a507e (patch)
tree477386daf3393c1a71fec15eac3d75ec46d283d0 /src/nvim/os
parentad1884be0dcf029f7467e5cfad8ffe7c8ba461b6 (diff)
downloadrneovim-f6946c68aee90c6ae8337b3e42c72943e37a507e.tar.gz
rneovim-f6946c68aee90c6ae8337b3e42c72943e37a507e.tar.bz2
rneovim-f6946c68aee90c6ae8337b3e42c72943e37a507e.zip
job-control: set CLOEXEC on pty processes. #5986
Before this change, new processes started with libuv prevented SIGHUP from reaching pty processes (by keeping the ptmx file descriptor open).
Diffstat (limited to 'src/nvim/os')
-rw-r--r--src/nvim/os/fs.c29
-rw-r--r--src/nvim/os/pty_process_unix.c21
2 files changed, 48 insertions, 2 deletions
diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c
index e930561234..af60e1b7af 100644
--- a/src/nvim/os/fs.c
+++ b/src/nvim/os/fs.c
@@ -391,6 +391,35 @@ int os_open(const char* path, int flags, int mode)
return r;
}
+/// Sets file descriptor `fd` to close-on-exec.
+//
+// @return -1 if failed to set, 0 otherwise.
+int os_set_cloexec(const int fd)
+{
+#ifdef HAVE_FD_CLOEXEC
+ int e;
+ int fdflags = fcntl(fd, F_GETFD);
+ if (fdflags < 0) {
+ e = errno;
+ ELOG("Failed to get flags on descriptor %d: %s", fd, strerror(e));
+ errno = e;
+ return -1;
+ }
+ if ((fdflags & FD_CLOEXEC) == 0
+ && fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC) < 0) {
+ e = errno;
+ ELOG("Failed to set CLOEXEC on descriptor %d: %s", fd, strerror(e));
+ errno = e;
+ return -1;
+ }
+ return 0;
+#endif
+
+ // No FD_CLOEXEC flag. On Windows, the file should have been opened with
+ // O_NOINHERIT anyway.
+ return -1;
+}
+
/// Close a file
///
/// @return 0 or libuv error code on failure.
diff --git a/src/nvim/os/pty_process_unix.c b/src/nvim/os/pty_process_unix.c
index f5ba0c2612..71a5e13de5 100644
--- a/src/nvim/os/pty_process_unix.c
+++ b/src/nvim/os/pty_process_unix.c
@@ -73,6 +73,13 @@ int pty_process_spawn(PtyProcess *ptyproc)
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
&& (status = set_duplicating_descriptor(master, &proc->in->uv.pipe))) {
goto error;
@@ -215,14 +222,24 @@ static int set_duplicating_descriptor(int fd, uv_pipe_t *pipe)
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));
- close(fd_dup);
- return status;
+ goto error;
}
return status;
+
+error:
+ close(fd_dup);
+ return status;
}
static void chld_handler(uv_signal_t *handle, int signum)