diff options
author | Bram Moolenaar <Bram@vim.org> | 2018-02-27 19:10:00 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2018-02-27 19:10:00 +0100 |
commit | 8195247054a659fe5cbc238197634d5e13e8e8e9 (patch) | |
tree | e1069ff3af65d73c58c694eaf552ff1e27cbbeef | |
parent | 988615f26f262d9ef6472c53b48868968a6b6d16 (diff) | |
download | vim-git-8195247054a659fe5cbc238197634d5e13e8e8e9.tar.gz |
patch 8.0.1552: may leak file descriptors when executing jobv8.0.1552
Problem: May leak file descriptors when executing job.
Solution: Close more file descriptors. (Ozaki Kiichi, closes #2531)
-rw-r--r-- | src/os_unix.c | 18 | ||||
-rw-r--r-- | src/testdir/test_channel.vim | 18 | ||||
-rw-r--r-- | src/version.c | 2 |
3 files changed, 35 insertions, 3 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 59fe77ace..ac89955f2 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -4601,6 +4601,12 @@ mch_call_shell( reset_signals(); /* handle signals normally */ UNBLOCK_SIGNALS(&curset); +# ifdef FEAT_JOB_CHANNEL + if (ch_log_active()) + /* close the log file in the child */ + ch_logfile((char_u *)"", (char_u *)""); +# endif + if (!show_shell_mess || (options & SHELL_EXPAND)) { int fd; @@ -5454,6 +5460,12 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options) reset_signals(); /* handle signals normally */ UNBLOCK_SIGNALS(&curset); +# ifdef FEAT_JOB_CHANNEL + if (ch_log_active()) + /* close the log file in the child */ + ch_logfile((char_u *)"", (char_u *)""); +# endif + # ifdef HAVE_SETSID /* Create our own process group, so that the child and all its * children can be kill()ed. Don't do this when using pipes, @@ -5587,11 +5599,11 @@ mch_job_start(char **argv, job_T *job, jobopt_T *options) if (pty_master_fd >= 0) close(pty_slave_fd); /* not used in the parent */ /* close child stdin, stdout and stderr */ - if (!use_file_for_in && fd_in[0] >= 0) + if (fd_in[0] >= 0) close(fd_in[0]); - if (!use_file_for_out && fd_out[1] >= 0) + if (fd_out[1] >= 0) close(fd_out[1]); - if (!use_out_for_err && !use_file_for_err && fd_err[1] >= 0) + if (fd_err[1] >= 0) close(fd_err[1]); if (channel != NULL) { diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim index 1859afc5b..9de3ca01f 100644 --- a/src/testdir/test_channel.vim +++ b/src/testdir/test_channel.vim @@ -23,6 +23,21 @@ func s:run_server(testfunc, ...) call RunServer('test_channel.py', a:testfunc, a:000) endfunc +" Return a list of open files. +" Can be used to make sure no resources leaked. +" Returns an empty list on systems where this is not supported. +func s:get_resources() + let pid = getpid() + + if has('mac') + return systemlist('lsof -p ' . pid . ' | awk ''$4~/^[0-9]*[rwu]$/&&$5=="REG"{print$NF}''') + elseif isdirectory('/proc/' . pid . '/fd/') + return systemlist('readlink /proc/' . pid . '/fd/* | grep -v ''^/dev/''') + else + return [] + endif +endfunc + let g:Ch_responseMsg = '' func Ch_requestHandler(handle, msg) let g:Ch_responseHandle = a:handle @@ -620,6 +635,7 @@ func Test_nl_write_out_file() call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput')) finally call Stop_g_job() + call assert_equal(-1, match(s:get_resources(), '\(^\|/\)Xoutput$')) call delete('Xoutput') endtry endfunc @@ -663,6 +679,7 @@ func Test_nl_write_both_file() call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput')) finally call Stop_g_job() + call assert_equal(-1, match(s:get_resources(), '\(^\|/\)Xoutput$')) call delete('Xoutput') endtry endfunc @@ -1662,6 +1679,7 @@ func Test_raw_passes_nul() call assert_equal("asdf\nasdf", getline(1)) call assert_equal("xxx\n", getline(2)) call assert_equal("\nyyy", getline(3)) + call assert_equal(-1, match(s:get_resources(), '\(^\|/\)Xtestwrite$')) call delete('Xtestwrite') bwipe! diff --git a/src/version.c b/src/version.c index 389bbb1a5..48da8a351 100644 --- a/src/version.c +++ b/src/version.c @@ -779,6 +779,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1552, +/**/ 1551, /**/ 1550, |