* 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:
parent
f3634e5dc8
commit
6e03277db0
13
ChangeLog
13
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 22:17:30 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
|
Sat Dec 13 22:17:30 2008 Yuki Sonoda (Yugui) <yugui@yugui.jp>
|
||||||
|
|
||||||
* common.mk (help): describes more targets.
|
* common.mk (help): describes more targets.
|
||||||
|
142
ext/pty/pty.c
142
ext/pty/pty.c
@ -143,6 +143,79 @@ pty_exec(VALUE v)
|
|||||||
return rb_f_exec(arg->argc, arg->argv);
|
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
|
static void
|
||||||
establishShell(int argc, VALUE *argv, struct pty_info *info,
|
establishShell(int argc, VALUE *argv, struct pty_info *info,
|
||||||
char SlaveName[DEVICELEN])
|
char SlaveName[DEVICELEN])
|
||||||
@ -152,8 +225,7 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
|
|||||||
char *p, tmp, *getenv();
|
char *p, tmp, *getenv();
|
||||||
struct passwd *pwent;
|
struct passwd *pwent;
|
||||||
VALUE v;
|
VALUE v;
|
||||||
struct exec_info arg;
|
struct child_info carg;
|
||||||
int status;
|
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
const char *shellname;
|
const char *shellname;
|
||||||
@ -172,71 +244,21 @@ establishShell(int argc, VALUE *argv, struct pty_info *info,
|
|||||||
argc = 1;
|
argc = 1;
|
||||||
argv = &v;
|
argv = &v;
|
||||||
}
|
}
|
||||||
|
|
||||||
getDevice(&master, &slave, SlaveName);
|
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(master);
|
||||||
close(slave);
|
close(slave);
|
||||||
rb_sys_fail("fork failed");
|
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);
|
read(master, &tmp, 1);
|
||||||
close(slave);
|
close(slave);
|
||||||
|
|
||||||
|
@ -971,10 +971,12 @@ void rb_thread_stop_timer_thread(void);
|
|||||||
void rb_thread_start_timer_thread(void);
|
void rb_thread_start_timer_thread(void);
|
||||||
void rb_thread_reset_timer_thread(void);
|
void rb_thread_reset_timer_thread(void);
|
||||||
|
|
||||||
|
static int forked_child = 0;
|
||||||
|
|
||||||
#define before_exec() \
|
#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() \
|
#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 before_fork() before_exec()
|
||||||
#define after_fork() after_exec()
|
#define after_fork() after_exec()
|
||||||
|
|
||||||
@ -2415,6 +2417,7 @@ rb_fork(int *status, int (*chfunc)(void*), void *charg, VALUE fds)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
|
forked_child = 1;
|
||||||
if (chfunc) {
|
if (chfunc) {
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
close(ep[0]);
|
close(ep[0]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user