diff options
author | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-12-16 10:26:06 +0000 |
---|---|---|
committer | yugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2008-12-16 10:26:06 +0000 |
commit | 00087e3083a30887bab7e305d360089d4f579bdb (patch) | |
tree | 68a4f98a18aa37572be7a4af17457a082061661b | |
parent | d1167ba077883491593e6f7e5ddb7b0f12cb1143 (diff) |
merges r20726 from trunk into ruby_1_9_1.
* process.c (forked_child): new variable.
(before_exec): don't call rb_thread_stop_timer_thread if
forked_child.
(after_exec): reset forked_child after rb_thread_start_timer_thread.
(rb_fork): set forked_child just after fork in child.
* ext/pty/pty.c (chfunc): extracted from establishShell.
(establishShell): use rb_fork.
[ruby-dev:37418]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_9_1@20791 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | ext/pty/pty.c | 142 | ||||
-rw-r--r-- | process.c | 7 |
3 files changed, 100 insertions, 62 deletions
@@ -1,3 +1,16 @@ +Sun Dec 14 01:35:48 2008 Tanaka Akira <akr@fsij.org> + + * process.c (forked_child): new variable. + (before_exec): don't call rb_thread_stop_timer_thread if + forked_child. + (after_exec): reset forked_child after rb_thread_start_timer_thread. + (rb_fork): set forked_child just after fork in child. + + * ext/pty/pty.c (chfunc): extracted from establishShell. + (establishShell): use rb_fork. + + [ruby-dev:37418] + Sat Dec 13 18:34:43 2008 Yukihiro Matsumoto <matz@ruby-lang.org> * string.c (sym_printable): wrong condition for string iteration. diff --git a/ext/pty/pty.c b/ext/pty/pty.c index e0d571a581..089322967b 100644 --- a/ext/pty/pty.c +++ b/ext/pty/pty.c @@ -186,6 +186,79 @@ pty_exec(VALUE v) return rb_f_exec(arg->argc, arg->argv); } +struct child_info { + int master, slave; + int argc; + VALUE *argv; +}; + +int chfunc(void *data) +{ + struct child_info *carg = data; + int master = carg->master; + int slave = carg->slave; + int argc = carg->argc; + VALUE *argv = carg->argv; + + struct exec_info arg; + int status; + + /* + * Set free from process group and controlling terminal + */ +#ifdef HAVE_SETSID + (void) setsid(); +#else /* HAS_SETSID */ +# ifdef HAVE_SETPGRP +# ifdef SETGRP_VOID + if (setpgrp() == -1) + perror("setpgrp()"); +# else /* SETGRP_VOID */ + if (setpgrp(0, getpid()) == -1) + rb_sys_fail("setpgrp()"); + { + int i = open("/dev/tty", O_RDONLY); + if (i < 0) rb_sys_fail("/dev/tty"); + if (ioctl(i, TIOCNOTTY, (char *)0)) + perror("ioctl(TIOCNOTTY)"); + close(i); + } +# endif /* SETGRP_VOID */ +# endif /* HAVE_SETPGRP */ +#endif /* HAS_SETSID */ + + /* + * obtain new controlling terminal + */ +#if defined(TIOCSCTTY) + close(master); + (void) ioctl(slave, TIOCSCTTY, (char *)0); + /* errors ignored for sun */ +#else + close(slave); + slave = open(SlaveName, O_RDWR); + if (slave < 0) { + perror("open: pty slave"); + _exit(1); + } + close(master); +#endif + write(slave, "", 1); + dup2(slave,0); + dup2(slave,1); + dup2(slave,2); + close(slave); +#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID) + seteuid(getuid()); +#endif + + arg.argc = argc; + arg.argv = argv; + rb_protect(pty_exec, (VALUE)&arg, &status); + sleep(1); + _exit(1); +} + static void establishShell(int argc, VALUE *argv, struct pty_info *info, char SlaveName[DEVICELEN]) @@ -195,8 +268,7 @@ establishShell(int argc, VALUE *argv, struct pty_info *info, char *p, tmp, *getenv(); struct passwd *pwent; VALUE v; - struct exec_info arg; - int status; + struct child_info carg; if (argc == 0) { const char *shellname; @@ -215,72 +287,22 @@ establishShell(int argc, VALUE *argv, struct pty_info *info, argc = 1; argv = &v; } + getDevice(&master, &slave, SlaveName); + carg.master = master; + carg.slave = slave; + carg.argc = argc; + carg.argv = argv; + pid = rb_fork(0, chfunc, &carg, Qnil); + info->thread = rb_thread_current(); - if ((pid = fork()) < 0) { + if (pid < 0) { close(master); close(slave); rb_sys_fail("fork failed"); } - if (pid == 0) { /* child */ - /* - * Set free from process group and controlling terminal - */ -#ifdef HAVE_SETSID - (void) setsid(); -#else /* HAS_SETSID */ -# ifdef HAVE_SETPGRP -# ifdef SETGRP_VOID - if (setpgrp() == -1) - perror("setpgrp()"); -# else /* SETGRP_VOID */ - if (setpgrp(0, getpid()) == -1) - rb_sys_fail("setpgrp()"); - { - int i = open("/dev/tty", O_RDONLY); - if (i < 0) rb_sys_fail("/dev/tty"); - if (ioctl(i, TIOCNOTTY, (char *)0)) - perror("ioctl(TIOCNOTTY)"); - close(i); - } -# endif /* SETGRP_VOID */ -# endif /* HAVE_SETPGRP */ -#endif /* HAS_SETSID */ - - /* - * obtain new controlling terminal - */ -#if defined(TIOCSCTTY) - close(master); - (void) ioctl(slave, TIOCSCTTY, (char *)0); - /* errors ignored for sun */ -#else - close(slave); - slave = open(SlaveName, O_RDWR); - if (slave < 0) { - perror("open: pty slave"); - _exit(1); - } - close(master); -#endif - write(slave, "", 1); - dup2(slave,0); - dup2(slave,1); - dup2(slave,2); - close(slave); -#if defined(HAVE_SETEUID) || defined(HAVE_SETREUID) || defined(HAVE_SETRESUID) - seteuid(getuid()); -#endif - - arg.argc = argc; - arg.argv = argv; - rb_protect(pty_exec, (VALUE)&arg, &status); - sleep(1); - _exit(1); - } - read(master, &tmp, 1); close(slave); @@ -971,10 +971,12 @@ void rb_thread_stop_timer_thread(void); void rb_thread_start_timer_thread(void); void rb_thread_reset_timer_thread(void); +static int forked_child = 0; + #define before_exec() \ - (rb_enable_interrupt(), rb_thread_stop_timer_thread()) + (rb_enable_interrupt(), forked_child ? 0 : rb_thread_stop_timer_thread()) #define after_exec() \ - (rb_thread_start_timer_thread(), rb_disable_interrupt()) + (rb_thread_start_timer_thread(), forked_child = 0, rb_disable_interrupt()) #define before_fork() before_exec() #define after_fork() after_exec() @@ -2301,6 +2303,7 @@ rb_fork(int *status, int (*chfunc)(void*), void *charg, VALUE fds) } } if (!pid) { + forked_child = 1; if (chfunc) { #ifdef FD_CLOEXEC close(ep[0]); |