diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ex_cmds2.c | 9 | ||||
-rw-r--r-- | src/nvim/fileio.c | 13 | ||||
-rw-r--r-- | src/nvim/memfile.c | 7 | ||||
-rw-r--r-- | src/nvim/memline.c | 9 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 29 | ||||
-rw-r--r-- | src/nvim/os/pty_process_unix.c | 21 |
6 files changed, 55 insertions, 33 deletions
diff --git a/src/nvim/ex_cmds2.c b/src/nvim/ex_cmds2.c index 048323b137..36f50ae7a2 100644 --- a/src/nvim/ex_cmds2.c +++ b/src/nvim/ex_cmds2.c @@ -2692,14 +2692,7 @@ static FILE *fopen_noinh_readbin(char *filename) return NULL; } -#ifdef HAVE_FD_CLOEXEC - { - int fdflags = fcntl(fd_tmp, F_GETFD); - if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) { - (void)fcntl(fd_tmp, F_SETFD, fdflags | FD_CLOEXEC); - } - } -#endif + (void)os_set_cloexec(fd_tmp); return fdopen(fd_tmp, READBIN); } diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 040df707de..9c64be6d0c 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -1742,16 +1742,11 @@ failed: } # endif - if (!read_buffer && !read_stdin) - close(fd); /* errors are ignored */ -#ifdef HAVE_FD_CLOEXEC - else { - int fdflags = fcntl(fd, F_GETFD); - if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) { - (void)fcntl(fd, F_SETFD, fdflags | FD_CLOEXEC); - } + if (!read_buffer && !read_stdin) { + close(fd); // errors are ignored + } else { + (void)os_set_cloexec(fd); } -#endif xfree(buffer); if (read_stdin) { diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 43412e3916..5d6639c4d0 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -909,12 +909,7 @@ static bool mf_do_open(memfile_T *mfp, char_u *fname, int flags) return false; } -#ifdef HAVE_FD_CLOEXEC - int fdflags = fcntl(mfp->mf_fd, F_GETFD); - if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) { - (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC); - } -#endif + (void)os_set_cloexec(mfp->mf_fd); #ifdef HAVE_SELINUX mch_copy_sec(fname, mfp->mf_fname); #endif diff --git a/src/nvim/memline.c b/src/nvim/memline.c index 1a315fce8b..f9d3751390 100644 --- a/src/nvim/memline.c +++ b/src/nvim/memline.c @@ -439,14 +439,7 @@ void ml_setname(buf_T *buf) EMSG(_("E301: Oops, lost the swap file!!!")); return; } -#ifdef HAVE_FD_CLOEXEC - { - int fdflags = fcntl(mfp->mf_fd, F_GETFD); - if (fdflags >= 0 && (fdflags & FD_CLOEXEC) == 0) { - (void)fcntl(mfp->mf_fd, F_SETFD, fdflags | FD_CLOEXEC); - } - } -#endif + (void)os_set_cloexec(mfp->mf_fd); } if (!success) EMSG(_("E302: Could not rename swap file")); 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) |