summaryrefslogtreecommitdiff
path: root/ext/pty/pty.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-13 16:40:01 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-12-13 16:40:01 +0000
commit6e03277db0fc91b496b7f2e70640a50159797100 (patch)
treeb94b83a5067594ffbc0458860ce3195a0a01dcc0 /ext/pty/pty.c
parentf3634e5dc82e3eacfb9078681f8f46454b3df092 (diff)
* 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/trunk@20726 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/pty/pty.c')
-rw-r--r--ext/pty/pty.c142
1 files changed, 82 insertions, 60 deletions
diff --git a/ext/pty/pty.c b/ext/pty/pty.c
index 46278991a3..b7da3d17ab 100644
--- a/ext/pty/pty.c
+++ b/ext/pty/pty.c
@@ -143,6 +143,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])
@@ -152,8 +225,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;
@@ -172,69 +244,19 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
argc = 1;
argv = &v;
}
+
getDevice(&master, &slave, SlaveName);
- if ((pid = fork()) < 0) {
- close(master);
- close(slave);
- rb_sys_fail("fork failed");
- }
+ carg.master = master;
+ carg.slave = slave;
+ carg.argc = argc;
+ carg.argv = argv;
+ pid = rb_fork(0, chfunc, &carg, Qnil);
- 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)
+ if (pid < 0) {
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);
+ rb_sys_fail("fork failed");
}
read(master, &tmp, 1);