summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-16 10:26:06 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-16 10:26:06 +0000
commit00087e3083a30887bab7e305d360089d4f579bdb (patch)
tree68a4f98a18aa37572be7a4af17457a082061661b
parentd1167ba077883491593e6f7e5ddb7b0f12cb1143 (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--ChangeLog13
-rw-r--r--ext/pty/pty.c142
-rw-r--r--process.c7
3 files changed, 100 insertions, 62 deletions
diff --git a/ChangeLog b/ChangeLog
index 8853410044..51288d4fb3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
diff --git a/process.c b/process.c
index 517b4867b1..8b8ed17d86 100644
--- a/process.c
+++ b/process.c
@@ -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]);