To: vim_dev@googlegroups.com Subject: Patch 8.0.0045 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.0045 Problem: Calling job_stop() right after job_start() does not work. Solution: Block signals while fork is still busy. (Ozaki Kiichi, closes #1155) Files: src/auto/configure, src/config.h.in, src/configure.in, src/os_unix.c, src/testdir/test_channel.vim *** ../vim-8.0.0044/src/auto/configure 2016-08-14 17:30:13.000000000 +0200 --- src/auto/configure 2016-10-18 15:38:10.274500411 +0200 *************** *** 12004,12010 **** getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ ! sigvec strcasecmp strerror strftime stricmp strncasecmp \ strnicmp strpbrk strtol tgetent towlower towupper iswupper \ usleep utime utimes do : --- 12004,12010 ---- getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ ! sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \ strnicmp strpbrk strtol tgetent towlower towupper iswupper \ usleep utime utimes do : *** ../vim-8.0.0044/src/config.h.in 2016-04-24 14:48:57.000000000 +0200 --- src/config.h.in 2016-10-18 15:38:10.274500411 +0200 *************** *** 190,195 **** --- 190,196 ---- #undef HAVE_SIGSET #undef HAVE_SIGSETJMP #undef HAVE_SIGSTACK + #undef HAVE_SIGPROCMASK #undef HAVE_SIGVEC #undef HAVE_SMACK #undef HAVE_STRCASECMP *** ../vim-8.0.0044/src/configure.in 2016-08-14 17:30:09.000000000 +0200 --- src/configure.in 2016-10-18 15:38:10.274500411 +0200 *************** *** 3598,3604 **** getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ ! sigvec strcasecmp strerror strftime stricmp strncasecmp \ strnicmp strpbrk strtol tgetent towlower towupper iswupper \ usleep utime utimes) AC_FUNC_FSEEKO --- 3598,3604 ---- getpwent getpwnam getpwuid getrlimit gettimeofday getwd lstat memcmp \ memset mkdtemp nanosleep opendir putenv qsort readlink select setenv \ setpgid setsid sigaltstack sigstack sigset sigsetjmp sigaction \ ! sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \ strnicmp strpbrk strtol tgetent towlower towupper iswupper \ usleep utime utimes) AC_FUNC_FSEEKO *** ../vim-8.0.0044/src/os_unix.c 2016-10-15 18:36:45.349910306 +0200 --- src/os_unix.c 2016-10-18 16:27:09.580836824 +0200 *************** *** 211,216 **** --- 211,225 ---- static void catch_int_signal(void); static void set_signals(void); static void catch_signals(RETSIGTYPE (*func_deadly)(), RETSIGTYPE (*func_other)()); + #ifdef HAVE_SIGPROCMASK + # define SIGSET_DECL(set) sigset_t set; + # define BLOCK_SIGNALS(set) block_signals(set) + # define UNBLOCK_SIGNALS(set) unblock_signals(set) + #else + # define SIGSET_DECL(set) + # define BLOCK_SIGNALS(set) do { /**/ } while (0) + # define UNBLOCK_SIGNALS(set) do { /**/ } while (0) + #endif static int have_wildcard(int, char_u **); static int have_dollars(int, char_u **); *************** *** 1468,1473 **** --- 1477,1509 ---- signal(signal_info[i].sig, func_other); } + #ifdef HAVE_SIGPROCMASK + static void + block_signals(sigset_t *set) + { + sigset_t newset; + int i; + + sigemptyset(&newset); + + for (i = 0; signal_info[i].sig != -1; i++) + sigaddset(&newset, signal_info[i].sig); + + # if defined(_REENTRANT) && defined(SIGCONT) + /* SIGCONT isn't in the list, because its default action is ignore */ + sigaddset(&newset, SIGCONT); + # endif + + sigprocmask(SIG_BLOCK, &newset, set); + } + + static void + unblock_signals(sigset_t *set) + { + sigprocmask(SIG_SETMASK, set, NULL); + } + #endif + /* * Handling of SIGHUP, SIGQUIT and SIGTERM: * "when" == a signal: when busy, postpone and return FALSE, otherwise *************** *** 4283,4294 **** if (!pipe_error) /* pty or pipe opened or not used */ { # ifdef __BEOS__ beos_cleanup_read_thread(); # endif ! if ((pid = fork()) == -1) /* maybe we should use vfork() */ { MSG_PUTS(_("\nCannot fork\n")); if ((options & (SHELL_READ|SHELL_WRITE)) # ifdef FEAT_GUI --- 4319,4336 ---- if (!pipe_error) /* pty or pipe opened or not used */ { + SIGSET_DECL(curset) + # ifdef __BEOS__ beos_cleanup_read_thread(); # endif ! BLOCK_SIGNALS(&curset); ! pid = fork(); /* maybe we should use vfork() */ ! if (pid == -1) { + UNBLOCK_SIGNALS(&curset); + MSG_PUTS(_("\nCannot fork\n")); if ((options & (SHELL_READ|SHELL_WRITE)) # ifdef FEAT_GUI *************** *** 4315,4320 **** --- 4357,4363 ---- else if (pid == 0) /* child */ { reset_signals(); /* handle signals normally */ + UNBLOCK_SIGNALS(&curset); if (!show_shell_mess || (options & SHELL_EXPAND)) { *************** *** 4458,4463 **** --- 4501,4507 ---- */ catch_signals(SIG_IGN, SIG_ERR); catch_int_signal(); + UNBLOCK_SIGNALS(&curset); /* * For the GUI we redirect stdin, stdout and stderr to our window. *************** *** 5069,5074 **** --- 5113,5119 ---- int use_file_for_out = options->jo_io[PART_OUT] == JIO_FILE; int use_file_for_err = options->jo_io[PART_ERR] == JIO_FILE; int use_out_for_err = options->jo_io[PART_ERR] == JIO_OUT; + SIGSET_DECL(curset) if (use_out_for_err && use_null_for_out) use_null_for_err = TRUE; *************** *** 5140,5152 **** goto failed; } pid = fork(); /* maybe we should use vfork() */ ! if (pid == -1) { /* failed to fork */ goto failed; } - if (pid == 0) { int null_fd = -1; --- 5185,5198 ---- goto failed; } + BLOCK_SIGNALS(&curset); pid = fork(); /* maybe we should use vfork() */ ! if (pid == -1) { /* failed to fork */ + UNBLOCK_SIGNALS(&curset); goto failed; } if (pid == 0) { int null_fd = -1; *************** *** 5154,5159 **** --- 5200,5206 ---- /* child */ reset_signals(); /* handle signals normally */ + UNBLOCK_SIGNALS(&curset); # ifdef HAVE_SETSID /* Create our own process group, so that the child and all its *************** *** 5234,5239 **** --- 5281,5288 ---- } /* parent */ + UNBLOCK_SIGNALS(&curset); + job->jv_pid = pid; job->jv_status = JOB_STARTED; job->jv_channel = channel; /* ch_refcount was set above */ *************** *** 5357,5363 **** } } return NULL; - } int --- 5406,5411 ---- *** ../vim-8.0.0044/src/testdir/test_channel.vim 2016-10-15 18:36:45.353910276 +0200 --- src/testdir/test_channel.vim 2016-10-18 15:38:10.274500411 +0200 *************** *** 1433,1438 **** --- 1433,1453 ---- call assert_fails('call job_start("")', 'E474:') endfunc + func Test_job_stop_immediately() + if !has('job') + return + endif + + let job = job_start([s:python, '-c', 'import time;time.sleep(10)']) + try + call job_stop(job) + call WaitFor('"dead" == job_status(job)') + call assert_equal('dead', job_status(job)) + finally + call job_stop(job, 'kill') + endtry + endfunc + " This was leaking memory. func Test_partial_in_channel_cycle() let d = {} *** ../vim-8.0.0044/src/version.c 2016-10-18 14:50:14.731694041 +0200 --- src/version.c 2016-10-18 16:25:17.693661467 +0200 *************** *** 766,767 **** --- 766,769 ---- { /* Add new patch number below this line */ + /**/ + 45, /**/ -- Females are strictly forbidden to appear unshaven in public. [real standing law in New Mexico, United States of America] /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///