diff options
author | Eliseo Martínez <eliseomarmol@gmail.com> | 2015-03-17 18:45:26 +0100 |
---|---|---|
committer | Eliseo Martínez <eliseomarmol@gmail.com> | 2015-03-22 11:32:20 +0100 |
commit | a2b4535747afcbd374cd97bbfd47457c52319723 (patch) | |
tree | dd1929c3102262478e885d6f1bbab5e293ffb7a7 | |
parent | 3db0a40d691c103a26ef3df74528f12d89b0fa61 (diff) | |
download | rneovim-a2b4535747afcbd374cd97bbfd47457c52319723.tar.gz rneovim-a2b4535747afcbd374cd97bbfd47457c52319723.tar.bz2 rneovim-a2b4535747afcbd374cd97bbfd47457c52319723.zip |
coverity/105982: Unckecked return value: RI.
Problem : Unchecked return value from library @ 91.
Diagnostic : Real issue.
Rationale : fcntl can fail, which is not being checked.
Resolution : Add corresponding error handling.
Helped-by: oni-link <knil.ino@gmail.com>
-rw-r--r-- | src/nvim/os/pty_process.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/src/nvim/os/pty_process.c b/src/nvim/os/pty_process.c index bd7247c741..a1edebb846 100644 --- a/src/nvim/os/pty_process.c +++ b/src/nvim/os/pty_process.c @@ -40,6 +40,7 @@ typedef struct { void pty_process_init(Job *job) { PtyProcess *ptyproc = xmalloc(sizeof(PtyProcess)); + ptyproc->tty_fd = -1; if (job->opts.writable) { uv_pipe_init(uv_default_loop(), &ptyproc->proc_stdin, 0); @@ -69,6 +70,9 @@ void pty_process_destroy(Job *job) job->process = NULL; } +static const unsigned int KILL_RETRIES = 5; +static const unsigned int KILL_TIMEOUT = 2; // seconds + bool pty_process_spawn(Job *job) { int master; @@ -88,7 +92,15 @@ bool pty_process_spawn(Job *job) } // make sure the master file descriptor is non blocking - fcntl(master, F_SETFL, fcntl(master, F_GETFL) | O_NONBLOCK); + int master_status_flags = fcntl(master, F_GETFL); + if (master_status_flags == -1) { + ELOG("Failed to get master descriptor status flags: %s", strerror(errno)); + goto error; + } + if (fcntl(master, F_SETFL, master_status_flags | O_NONBLOCK) == -1) { + ELOG("Failed to make master descriptor non-blocking: %s", strerror(errno)); + goto error; + } if (job->opts.writable) { uv_pipe_open(&ptyproc->proc_stdin, dup(master)); @@ -108,6 +120,22 @@ bool pty_process_spawn(Job *job) ptyproc->tty_fd = master; job->pid = pid; return true; + +error: + close(master); + + // terminate spawned process + kill(pid, SIGTERM); + int status, child; + unsigned int try = 0; + while (try++ < KILL_RETRIES && !(child = waitpid(pid, &status, WNOHANG))) { + sleep(KILL_TIMEOUT); + } + if (child != pid) { + kill(pid, SIGKILL); + } + + return false; } void pty_process_close(Job *job) @@ -115,10 +143,20 @@ void pty_process_close(Job *job) PtyProcess *ptyproc = job->process; uv_signal_stop(&ptyproc->schld); uv_close((uv_handle_t *)&ptyproc->schld, NULL); + pty_process_close_master(job); job_close_streams(job); job_decref(job); } +void pty_process_close_master(Job *job) +{ + PtyProcess *ptyproc = job->process; + if (ptyproc->tty_fd >= 0) { + close(ptyproc->tty_fd); + ptyproc->tty_fd = -1; + } +} + void pty_process_resize(Job *job, uint16_t width, uint16_t height) { PtyProcess *ptyproc = job->process; |