diff options
author | Eliseo Martínez <eliseomarmol@gmail.com> | 2015-03-17 19:08:44 +0100 |
---|---|---|
committer | Eliseo Martínez <eliseomarmol@gmail.com> | 2015-03-22 11:32:30 +0100 |
commit | c6784d9f6f2bcb648072486d90390e3760c579c6 (patch) | |
tree | f49476f09e85c5b591dc489bb762aa7e226b6968 | |
parent | a2b4535747afcbd374cd97bbfd47457c52319723 (diff) | |
download | rneovim-c6784d9f6f2bcb648072486d90390e3760c579c6.tar.gz rneovim-c6784d9f6f2bcb648072486d90390e3760c579c6.tar.bz2 rneovim-c6784d9f6f2bcb648072486d90390e3760c579c6.zip |
coverity/105985: Resource leak: RI.
Problem : Resource leak @ 94, 98, 102.
Diagnostic : Real issue.
Rationale : Coverity doesn't know that uv_pipe_open will save file
descriptor to close them later. So, it signals file
descriptors being leaked. This would then seem like a false
positive we can fix by teaching coverity about uv_pipe_open
through model file.
But then we realize that the above is only true if
uv_pipe_open succeeds. It it fails, then descriptors are
really being leaked, which is why this is considered a real
issue and not a false positive after all.
Resolution : Add error handling to correctly close descriptors if
uv_pipe_open fails at any point.
Add model for uv_pipe_open so that Coverity knows it will
save descriptors when no error.
Helped-by: oni-link <knil.ino@gmail.com>
-rw-r--r-- | src/nvim/os/pty_process.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/nvim/os/pty_process.c b/src/nvim/os/pty_process.c index a1edebb846..ed98d3e0c0 100644 --- a/src/nvim/os/pty_process.c +++ b/src/nvim/os/pty_process.c @@ -70,6 +70,23 @@ void pty_process_destroy(Job *job) job->process = NULL; } +static bool set_pipe_duplicating_descriptor(int fd, uv_pipe_t *pipe) +{ + int fd_dup = dup(fd); + if (fd_dup < 0) { + ELOG("Failed to dup descriptor %d: %s", fd, strerror(errno)); + return false; + } + int uv_result = uv_pipe_open(pipe, fd_dup); + if (uv_result) { + ELOG("Failed to set pipe to descriptor %d: %s", + fd_dup, uv_strerror(uv_result)); + close(fd_dup); + return false; + } + return true; +} + static const unsigned int KILL_RETRIES = 5; static const unsigned int KILL_TIMEOUT = 2; // seconds @@ -102,16 +119,19 @@ bool pty_process_spawn(Job *job) goto error; } - if (job->opts.writable) { - uv_pipe_open(&ptyproc->proc_stdin, dup(master)); + if (job->opts.writable + && !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stdin)) { + goto error; } - if (job->opts.stdout_cb) { - uv_pipe_open(&ptyproc->proc_stdout, dup(master)); + if (job->opts.stdout_cb + && !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stdout)) { + goto error; } - if (job->opts.stderr_cb) { - uv_pipe_open(&ptyproc->proc_stderr, dup(master)); + if (job->opts.stderr_cb + && !set_pipe_duplicating_descriptor(master, &ptyproc->proc_stderr)) { + goto error; } uv_signal_init(uv_default_loop(), &ptyproc->schld); |