mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	process.c: do not discard status
* process.c (rb_spawn_process): do not discard global escape status. [ruby-core:69304] [Bug #11166] * process.c (rb_execarg_spawn): extract the start procedure in a parent process with ensuring the end procedure. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50600 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
		
							parent
							
								
									224172757e
								
							
						
					
					
						commit
						46c64caff6
					
				
					 3 changed files with 61 additions and 18 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,11 @@
 | 
			
		|||
Fri May 22 19:42:06 2015  Nobuyoshi Nakada  <nobu@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* process.c (rb_spawn_process): do not discard global escape
 | 
			
		||||
	  status.  [ruby-core:69304] [Bug #11166]
 | 
			
		||||
 | 
			
		||||
	* process.c (rb_execarg_spawn): extract the start procedure in a
 | 
			
		||||
	  parent process with ensuring the end procedure.
 | 
			
		||||
 | 
			
		||||
Fri May 22 16:48:32 2015  SHIBATA Hiroshi  <hsbt@ruby-lang.org>
 | 
			
		||||
 | 
			
		||||
	* NEWS: added news for net-telnet and rake
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										59
									
								
								process.c
									
										
									
									
									
								
							
							
						
						
									
										59
									
								
								process.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2436,8 +2436,8 @@ rb_execarg_parent_start(VALUE execarg_obj)
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rb_execarg_parent_end(VALUE execarg_obj)
 | 
			
		||||
static VALUE
 | 
			
		||||
execarg_parent_end(VALUE execarg_obj)
 | 
			
		||||
{
 | 
			
		||||
    struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
 | 
			
		||||
    int err = errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -2461,6 +2461,13 @@ rb_execarg_parent_end(VALUE execarg_obj)
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    errno = err;
 | 
			
		||||
    return execarg_obj;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
rb_execarg_parent_end(VALUE execarg_obj)
 | 
			
		||||
{
 | 
			
		||||
    execarg_parent_end(execarg_obj);
 | 
			
		||||
    RB_GC_GUARD(execarg_obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3845,16 +3852,13 @@ static rb_pid_t
 | 
			
		|||
rb_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
 | 
			
		||||
{
 | 
			
		||||
    rb_pid_t pid;
 | 
			
		||||
#if !USE_SPAWNV
 | 
			
		||||
    int status;
 | 
			
		||||
#endif
 | 
			
		||||
#if !defined HAVE_WORKING_FORK || USE_SPAWNV
 | 
			
		||||
    VALUE prog;
 | 
			
		||||
    struct rb_execarg sarg;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#if defined HAVE_WORKING_FORK && !USE_SPAWNV
 | 
			
		||||
    pid = rb_fork_async_signal_safe(&status, rb_exec_atfork, eargp, eargp->redirect_fds, errmsg, errmsg_buflen);
 | 
			
		||||
    pid = rb_fork_async_signal_safe(NULL, rb_exec_atfork, eargp, eargp->redirect_fds, errmsg, errmsg_buflen);
 | 
			
		||||
#else
 | 
			
		||||
    prog = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -3892,20 +3896,42 @@ rb_spawn_process(struct rb_execarg *eargp, char *errmsg, size_t errmsg_buflen)
 | 
			
		|||
    return pid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct spawn_args {
 | 
			
		||||
    VALUE execarg;
 | 
			
		||||
    struct {
 | 
			
		||||
	char *ptr;
 | 
			
		||||
	size_t buflen;
 | 
			
		||||
    } errmsg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static VALUE
 | 
			
		||||
do_spawn_process(VALUE arg)
 | 
			
		||||
{
 | 
			
		||||
    struct spawn_args *argp = (struct spawn_args *)arg;
 | 
			
		||||
    rb_execarg_parent_start1(argp->execarg);
 | 
			
		||||
    return (VALUE)rb_spawn_process(DATA_PTR(argp->execarg),
 | 
			
		||||
				   argp->errmsg.ptr, argp->errmsg.buflen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rb_pid_t
 | 
			
		||||
rb_execarg_spawn(VALUE execarg_obj, char *errmsg, size_t errmsg_buflen)
 | 
			
		||||
{
 | 
			
		||||
    struct spawn_args args;
 | 
			
		||||
 | 
			
		||||
    args.execarg = execarg_obj;
 | 
			
		||||
    args.errmsg.ptr = errmsg;
 | 
			
		||||
    args.errmsg.buflen = errmsg_buflen;
 | 
			
		||||
    return (rb_pid_t)rb_ensure(do_spawn_process, (VALUE)&args,
 | 
			
		||||
			       execarg_parent_end, execarg_obj);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static rb_pid_t
 | 
			
		||||
rb_spawn_internal(int argc, const VALUE *argv, char *errmsg, size_t errmsg_buflen)
 | 
			
		||||
{
 | 
			
		||||
    VALUE execarg_obj;
 | 
			
		||||
    struct rb_execarg *eargp;
 | 
			
		||||
    rb_pid_t ret;
 | 
			
		||||
 | 
			
		||||
    execarg_obj = rb_execarg_new(argc, argv, TRUE);
 | 
			
		||||
    eargp = rb_execarg_get(execarg_obj);
 | 
			
		||||
    rb_execarg_parent_start(execarg_obj);
 | 
			
		||||
    ret = rb_spawn_process(eargp, errmsg, errmsg_buflen);
 | 
			
		||||
    rb_execarg_parent_end(execarg_obj);
 | 
			
		||||
    RB_GC_GUARD(execarg_obj);
 | 
			
		||||
    return ret;
 | 
			
		||||
    return rb_execarg_spawn(execarg_obj, errmsg, errmsg_buflen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
rb_pid_t
 | 
			
		||||
| 
						 | 
				
			
			@ -4267,12 +4293,9 @@ rb_f_spawn(int argc, VALUE *argv)
 | 
			
		|||
 | 
			
		||||
    execarg_obj = rb_execarg_new(argc, argv, TRUE);
 | 
			
		||||
    eargp = rb_execarg_get(execarg_obj);
 | 
			
		||||
    rb_execarg_parent_start(execarg_obj);
 | 
			
		||||
    fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;
 | 
			
		||||
 | 
			
		||||
    pid = rb_spawn_process(eargp, errmsg, sizeof(errmsg));
 | 
			
		||||
    rb_execarg_parent_end(execarg_obj);
 | 
			
		||||
    RB_GC_GUARD(execarg_obj);
 | 
			
		||||
    pid = rb_execarg_spawn(execarg_obj, errmsg, sizeof(errmsg));
 | 
			
		||||
 | 
			
		||||
    if (pid == -1) {
 | 
			
		||||
	const char *prog = errmsg;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2017,4 +2017,16 @@ EOS
 | 
			
		|||
    status = th.value
 | 
			
		||||
    assert status.success?, status.inspect
 | 
			
		||||
  end if defined?(fork)
 | 
			
		||||
 | 
			
		||||
  def test_kill_at_spawn_failure
 | 
			
		||||
    bug11166 = '[ruby-core:69304] [Bug #11166]'
 | 
			
		||||
    th = nil
 | 
			
		||||
    x = with_tmpchdir {|d|
 | 
			
		||||
      prog = "#{d}/notexist"
 | 
			
		||||
      th = Thread.start {system(prog);sleep}
 | 
			
		||||
      th.kill
 | 
			
		||||
      th.join(0.1)
 | 
			
		||||
    }
 | 
			
		||||
    assert_equal(th, x)
 | 
			
		||||
  end if defined?(fork)
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue