зеркало из https://github.com/github/ruby.git
* process.c (rb_exec): follow older behavior if close-on-exec is not
available. * process.c (rb_fork): protect from exceptions while waiting failed process, if status is given. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@6046 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
712de4408c
Коммит
846f087a07
|
@ -1,3 +1,11 @@
|
||||||
|
Mon Mar 29 20:17:16 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
|
* process.c (rb_exec): follow older behavior if close-on-exec is not
|
||||||
|
available.
|
||||||
|
|
||||||
|
* process.c (rb_fork): protect from exceptions while waiting failed
|
||||||
|
process, if status is given.
|
||||||
|
|
||||||
Sun Mar 28 16:25:37 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
Sun Mar 28 16:25:37 2004 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* cygwin/GNUmakefile.in (clean-local, distclean-local): remove
|
* cygwin/GNUmakefile.in (clean-local, distclean-local): remove
|
||||||
|
|
94
process.c
94
process.c
|
@ -108,6 +108,9 @@ static VALUE S_Tms;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define preserving_errno(stmts) \
|
||||||
|
do {int saved_errno = errno; stmts; errno = saved_errno;} while (0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
@ -915,8 +918,6 @@ proc_exec_v(argv, prog)
|
||||||
char **argv;
|
char **argv;
|
||||||
const char *prog;
|
const char *prog;
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
|
|
||||||
if (!prog)
|
if (!prog)
|
||||||
prog = argv[0];
|
prog = argv[0];
|
||||||
security(prog);
|
security(prog);
|
||||||
|
@ -965,9 +966,7 @@ proc_exec_v(argv, prog)
|
||||||
#endif /* MSDOS or __human68k__ or __EMX__ */
|
#endif /* MSDOS or __human68k__ or __EMX__ */
|
||||||
before_exec();
|
before_exec();
|
||||||
execv(prog, argv);
|
execv(prog, argv);
|
||||||
err = errno;
|
preserving_errno(after_exec());
|
||||||
after_exec();
|
|
||||||
errno = err;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1030,9 +1029,7 @@ rb_proc_exec(str)
|
||||||
#else
|
#else
|
||||||
before_exec();
|
before_exec();
|
||||||
execl("/bin/sh", "sh", "-c", str, (char *)NULL);
|
execl("/bin/sh", "sh", "-c", str, (char *)NULL);
|
||||||
status = errno;
|
preserving_errno(after_exec());
|
||||||
after_exec();
|
|
||||||
errno = status;
|
|
||||||
#endif
|
#endif
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1251,17 +1248,60 @@ rb_exec(e)
|
||||||
else {
|
else {
|
||||||
rb_proc_exec_n(argc, argv, prog);
|
rb_proc_exec_n(argc, argv, prog);
|
||||||
}
|
}
|
||||||
return errno;
|
#ifndef FD_CLOEXEC
|
||||||
|
preserving_errno({
|
||||||
|
fprintf(stderr, "%s:%d: command not found: %s\n",
|
||||||
|
ruby_sourcefile, ruby_sourceline, prog);
|
||||||
|
});
|
||||||
|
#endif
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_FORK
|
#ifdef HAVE_FORK
|
||||||
|
#ifdef FD_CLOEXEC
|
||||||
|
#if SIZEOF_INT == SIZEOF_LONG
|
||||||
|
#define proc_syswait (VALUE (*)_((VALUE)))rb_syswait
|
||||||
|
#else
|
||||||
|
static VALUE
|
||||||
|
proc_syswait(pid)
|
||||||
|
VALUE pid;
|
||||||
|
{
|
||||||
|
rb_syswait((int)pid);
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Forks child process, and returns the process ID in the parent
|
||||||
|
* process.
|
||||||
|
*
|
||||||
|
* If +status+ is given, protects from any exceptions and sets the
|
||||||
|
* jump status to it.
|
||||||
|
*
|
||||||
|
* In the child process, just returns 0 if +chfunc+ is +NULL+.
|
||||||
|
* Otherwise +chfunc+ will be called with +charg+, and then the child
|
||||||
|
* process exits with +EXIT_SUCCESS+ when it returned zero.
|
||||||
|
*
|
||||||
|
* In the case of the function is called and returns non-zero value,
|
||||||
|
* the child process exits with non-+EXIT_SUCCESS+ value (normaly
|
||||||
|
* 127). And, on the platforms where +FD_CLOEXEC+ is available,
|
||||||
|
* +errno+ is propagated to the parent process, and this function
|
||||||
|
* returns -1 in the parent process. On the other platforms, just
|
||||||
|
* returns pid.
|
||||||
|
*
|
||||||
|
* +chfunc+ must not raise any exceptions.
|
||||||
|
*/
|
||||||
int
|
int
|
||||||
rb_fork(status, chfunc, charg)
|
rb_fork(status, chfunc, charg)
|
||||||
int *status;
|
int *status;
|
||||||
int (*chfunc) _((void *));
|
int (*chfunc) _((void *));
|
||||||
void *charg;
|
void *charg;
|
||||||
{
|
{
|
||||||
int pid, err, state = 0, ep[2];
|
int pid, err, state = 0;
|
||||||
|
#ifdef FD_CLOEXEC
|
||||||
|
int ep[2];
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __VMS
|
#ifndef __VMS
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -1271,12 +1311,8 @@ rb_fork(status, chfunc, charg)
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
if (chfunc) {
|
if (chfunc) {
|
||||||
if (pipe(ep)) return -1;
|
if (pipe(ep)) return -1;
|
||||||
if (fcntl(ep[0], F_SETFD, FD_CLOEXEC) ||
|
if (fcntl(ep[1], F_SETFD, FD_CLOEXEC)) {
|
||||||
fcntl(ep[1], F_SETFD, FD_CLOEXEC)) {
|
preserving_errno((close(ep[0]), close(ep[1])));
|
||||||
err = errno;
|
|
||||||
close(ep[0]);
|
|
||||||
close(ep[1]);
|
|
||||||
errno = err;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1299,10 +1335,7 @@ rb_fork(status, chfunc, charg)
|
||||||
default:
|
default:
|
||||||
#ifdef FD_CLOEXEC
|
#ifdef FD_CLOEXEC
|
||||||
if (chfunc) {
|
if (chfunc) {
|
||||||
err = errno;
|
preserving_errno((close(ep[0]), close(ep[1])));
|
||||||
close(ep[0]);
|
|
||||||
close(ep[1]);
|
|
||||||
errno = err;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (state && !status) rb_jump_tag(state);
|
if (state && !status) rb_jump_tag(state);
|
||||||
|
@ -1311,11 +1344,22 @@ rb_fork(status, chfunc, charg)
|
||||||
}
|
}
|
||||||
if (!pid) {
|
if (!pid) {
|
||||||
if (chfunc) {
|
if (chfunc) {
|
||||||
err = (*chfunc)(charg);
|
#ifdef FD_CLOEXEC
|
||||||
|
close(ep[0]);
|
||||||
|
#endif
|
||||||
|
if (!(*chfunc)(charg)) _exit(EXIT_SUCCESS);
|
||||||
|
#ifdef FD_CLOEXEC
|
||||||
|
err = errno;
|
||||||
write(ep[1], &err, sizeof(err));
|
write(ep[1], &err, sizeof(err));
|
||||||
|
#endif
|
||||||
|
#if EXIT_SUCCESS == 127
|
||||||
|
_exit(EXIT_FAILURE);
|
||||||
|
#else
|
||||||
_exit(127);
|
_exit(127);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef FD_CLOEXEC
|
||||||
else if (chfunc) {
|
else if (chfunc) {
|
||||||
close(ep[1]);
|
close(ep[1]);
|
||||||
if ((state = read(ep[0], &err, sizeof(err))) < 0) {
|
if ((state = read(ep[0], &err, sizeof(err))) < 0) {
|
||||||
|
@ -1323,11 +1367,17 @@ rb_fork(status, chfunc, charg)
|
||||||
}
|
}
|
||||||
close(ep[0]);
|
close(ep[0]);
|
||||||
if (state) {
|
if (state) {
|
||||||
rb_syswait(pid);
|
if (status) {
|
||||||
|
rb_protect(proc_syswait, (VALUE)pid, status);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_syswait(pid);
|
||||||
|
}
|
||||||
errno = err;
|
errno = err;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Загрузка…
Ссылка в новой задаче