* 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
This commit is contained in:
akr 2008-12-13 16:40:01 +00:00
Родитель f3634e5dc8
Коммит 6e03277db0
3 изменённых файлов: 100 добавлений и 62 удалений

Просмотреть файл

@ -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 22:17:30 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
* common.mk (help): describes more targets.

Просмотреть файл

@ -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,71 +244,21 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
argc = 1;
argv = &v;
}
getDevice(&master, &slave, SlaveName);
if ((pid = fork()) < 0) {
carg.master = master;
carg.slave = slave;
carg.argc = argc;
carg.argv = argv;
pid = rb_fork(0, chfunc, &carg, Qnil);
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()
@ -2415,6 +2417,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]);