Skip to content

Commit

Permalink
patch 8.0.0045
Browse files Browse the repository at this point in the history
Problem:    Calling job_stop() right after job_start() does not work.
Solution:   Block signals while fork is still busy. (Ozaki Kiichi, closes
            #1155)
  • Loading branch information
brammool committed Oct 18, 2016
1 parent 025e3e0 commit bb09ceb
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 6 deletions.
2 changes: 1 addition & 1 deletion src/auto/configure
Expand Up @@ -12004,7 +12004,7 @@ for ac_func in bcmp fchdir fchown fsync getcwd getpseudotty \
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 \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
strnicmp strpbrk strtol tgetent towlower towupper iswupper \
usleep utime utimes
do :
Expand Down
1 change: 1 addition & 0 deletions src/config.h.in
Expand Up @@ -190,6 +190,7 @@
#undef HAVE_SIGSET
#undef HAVE_SIGSETJMP
#undef HAVE_SIGSTACK
#undef HAVE_SIGPROCMASK
#undef HAVE_SIGVEC
#undef HAVE_SMACK
#undef HAVE_STRCASECMP
Expand Down
2 changes: 1 addition & 1 deletion src/configure.in
Expand Up @@ -3598,7 +3598,7 @@ AC_CHECK_FUNCS(bcmp fchdir fchown fsync getcwd getpseudotty \
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 \
sigprocmask sigvec strcasecmp strerror strftime stricmp strncasecmp \
strnicmp strpbrk strtol tgetent towlower towupper iswupper \
usleep utime utimes)
AC_FUNC_FSEEKO
Expand Down
56 changes: 52 additions & 4 deletions src/os_unix.c
Expand Up @@ -211,6 +211,15 @@ static RETSIGTYPE deathtrap SIGPROTOARG;
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 **);

Expand Down Expand Up @@ -1468,6 +1477,33 @@ catch_signals(
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
Expand Down Expand Up @@ -4283,12 +4319,18 @@ mch_call_shell(

if (!pipe_error) /* pty or pipe opened or not used */
{
SIGSET_DECL(curset)

# ifdef __BEOS__
beos_cleanup_read_thread();
# endif

if ((pid = fork()) == -1) /* maybe we should use vfork() */
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
Expand All @@ -4315,6 +4357,7 @@ mch_call_shell(
else if (pid == 0) /* child */
{
reset_signals(); /* handle signals normally */
UNBLOCK_SIGNALS(&curset);

if (!show_shell_mess || (options & SHELL_EXPAND))
{
Expand Down Expand Up @@ -4458,6 +4501,7 @@ mch_call_shell(
*/
catch_signals(SIG_IGN, SIG_ERR);
catch_int_signal();
UNBLOCK_SIGNALS(&curset);

/*
* For the GUI we redirect stdin, stdout and stderr to our window.
Expand Down Expand Up @@ -5069,6 +5113,7 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
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;
Expand Down Expand Up @@ -5140,20 +5185,22 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
goto failed;
}

BLOCK_SIGNALS(&curset);
pid = fork(); /* maybe we should use vfork() */
if (pid == -1)
if (pid == -1)
{
/* failed to fork */
UNBLOCK_SIGNALS(&curset);
goto failed;
}

if (pid == 0)
{
int null_fd = -1;
int stderr_works = TRUE;

/* child */
reset_signals(); /* handle signals normally */
UNBLOCK_SIGNALS(&curset);

# ifdef HAVE_SETSID
/* Create our own process group, so that the child and all its
Expand Down Expand Up @@ -5234,6 +5281,8 @@ mch_start_job(char **argv, job_T *job, jobopt_T *options UNUSED)
}

/* parent */
UNBLOCK_SIGNALS(&curset);

job->jv_pid = pid;
job->jv_status = JOB_STARTED;
job->jv_channel = channel; /* ch_refcount was set above */
Expand Down Expand Up @@ -5357,7 +5406,6 @@ mch_detect_ended_job(job_T *job_list)
}
}
return NULL;

}

int
Expand Down
15 changes: 15 additions & 0 deletions src/testdir/test_channel.vim
Expand Up @@ -1433,6 +1433,21 @@ func Test_job_start_invalid()
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 = {}
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -764,6 +764,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
45,
/**/
44,
/**/
Expand Down

0 comments on commit bb09ceb

Please sign in to comment.