* internal.h (rb_execarg): add fd_dup2, fd_close, fd_open,
fd_dup2_child fields. * process.c (EXEC_OPTION_DUP2): removed. (EXEC_OPTION_CLOSE): removed. (EXEC_OPTION_OPEN): removed. (EXEC_OPTION_DUP2_CHILD): removed. (mark_exec_arg): mark the new fields. (check_exec_redirect1): change condition for default option. (check_exec_redirect): take a struct rb_execarg argument. use the new fields. (rb_execarg_addopt): follow the check_exec_redirect change. (check_exec_fds): use the new fields. (save_redirect_fd): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36201 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
fe688f2d30
commit
345ecf3711
17
ChangeLog
17
ChangeLog
@ -1,3 +1,20 @@
|
|||||||
|
Sat Jun 23 20:26:36 2012 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
|
* internal.h (rb_execarg): add fd_dup2, fd_close, fd_open,
|
||||||
|
fd_dup2_child fields.
|
||||||
|
|
||||||
|
* process.c (EXEC_OPTION_DUP2): removed.
|
||||||
|
(EXEC_OPTION_CLOSE): removed.
|
||||||
|
(EXEC_OPTION_OPEN): removed.
|
||||||
|
(EXEC_OPTION_DUP2_CHILD): removed.
|
||||||
|
(mark_exec_arg): mark the new fields.
|
||||||
|
(check_exec_redirect1): change condition for default option.
|
||||||
|
(check_exec_redirect): take a struct rb_execarg argument.
|
||||||
|
use the new fields.
|
||||||
|
(rb_execarg_addopt): follow the check_exec_redirect change.
|
||||||
|
(check_exec_fds): use the new fields.
|
||||||
|
(save_redirect_fd): ditto.
|
||||||
|
|
||||||
Sat Jun 23 19:01:18 2012 Tanaka Akira <akr@fsij.org>
|
Sat Jun 23 19:01:18 2012 Tanaka Akira <akr@fsij.org>
|
||||||
|
|
||||||
* process.c (rb_execarg_fixup): fix envopts condition.
|
* process.c (rb_execarg_fixup): fix envopts condition.
|
||||||
|
@ -186,6 +186,10 @@ struct rb_execarg {
|
|||||||
pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0<V). */
|
pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0<V). */
|
||||||
VALUE rlimit_limits; /* Qfalse or [[rtype, softlim, hardlim], ...] */
|
VALUE rlimit_limits; /* Qfalse or [[rtype, softlim, hardlim], ...] */
|
||||||
mode_t umask_mask;
|
mode_t umask_mask;
|
||||||
|
VALUE fd_dup2;
|
||||||
|
VALUE fd_close;
|
||||||
|
VALUE fd_open;
|
||||||
|
VALUE fd_dup2_child;
|
||||||
int close_others_maxhint;
|
int close_others_maxhint;
|
||||||
VALUE env_modification; /* Qfalse or [[k1,v1], ...] */
|
VALUE env_modification; /* Qfalse or [[k1,v1], ...] */
|
||||||
VALUE chdir_dir;
|
VALUE chdir_dir;
|
||||||
|
102
process.c
102
process.c
@ -1254,10 +1254,6 @@ rb_proc_exec(const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
EXEC_OPTION_DUP2,
|
|
||||||
EXEC_OPTION_CLOSE,
|
|
||||||
EXEC_OPTION_OPEN,
|
|
||||||
EXEC_OPTION_DUP2_CHILD,
|
|
||||||
EXEC_OPTION_NEW_PGROUP
|
EXEC_OPTION_NEW_PGROUP
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1279,6 +1275,10 @@ mark_exec_arg(void *ptr)
|
|||||||
rb_gc_mark(eargp->envp_buf);
|
rb_gc_mark(eargp->envp_buf);
|
||||||
rb_gc_mark(eargp->dup2_tmpbuf);
|
rb_gc_mark(eargp->dup2_tmpbuf);
|
||||||
rb_gc_mark(eargp->rlimit_limits);
|
rb_gc_mark(eargp->rlimit_limits);
|
||||||
|
rb_gc_mark(eargp->fd_dup2);
|
||||||
|
rb_gc_mark(eargp->fd_close);
|
||||||
|
rb_gc_mark(eargp->fd_open);
|
||||||
|
rb_gc_mark(eargp->fd_dup2_child);
|
||||||
rb_gc_mark(eargp->env_modification);
|
rb_gc_mark(eargp->env_modification);
|
||||||
rb_gc_mark(eargp->chdir_dir);
|
rb_gc_mark(eargp->chdir_dir);
|
||||||
}
|
}
|
||||||
@ -1433,7 +1433,7 @@ check_exec_redirect_fd(VALUE v, int iskey)
|
|||||||
static VALUE
|
static VALUE
|
||||||
check_exec_redirect1(VALUE ary, VALUE key, VALUE param)
|
check_exec_redirect1(VALUE ary, VALUE key, VALUE param)
|
||||||
{
|
{
|
||||||
if (NIL_P(ary)) {
|
if (ary == Qfalse) {
|
||||||
ary = hide_obj(rb_ary_new());
|
ary = hide_obj(rb_ary_new());
|
||||||
}
|
}
|
||||||
if (!RB_TYPE_P(key, T_ARRAY)) {
|
if (!RB_TYPE_P(key, T_ARRAY)) {
|
||||||
@ -1453,10 +1453,9 @@ check_exec_redirect1(VALUE ary, VALUE key, VALUE param)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
check_exec_redirect(VALUE key, VALUE val, VALUE options)
|
check_exec_redirect(VALUE key, VALUE val, struct rb_execarg *eargp)
|
||||||
{
|
{
|
||||||
int index;
|
VALUE param;
|
||||||
VALUE ary, param;
|
|
||||||
VALUE path, flags, perm;
|
VALUE path, flags, perm;
|
||||||
ID id;
|
ID id;
|
||||||
|
|
||||||
@ -1464,20 +1463,20 @@ check_exec_redirect(VALUE key, VALUE val, VALUE options)
|
|||||||
case T_SYMBOL:
|
case T_SYMBOL:
|
||||||
id = SYM2ID(val);
|
id = SYM2ID(val);
|
||||||
if (id == rb_intern("close")) {
|
if (id == rb_intern("close")) {
|
||||||
index = EXEC_OPTION_CLOSE;
|
|
||||||
param = Qnil;
|
param = Qnil;
|
||||||
|
eargp->fd_close = check_exec_redirect1(eargp->fd_close, key, param);
|
||||||
}
|
}
|
||||||
else if (id == rb_intern("in")) {
|
else if (id == rb_intern("in")) {
|
||||||
index = EXEC_OPTION_DUP2;
|
|
||||||
param = INT2FIX(0);
|
param = INT2FIX(0);
|
||||||
|
eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
|
||||||
}
|
}
|
||||||
else if (id == rb_intern("out")) {
|
else if (id == rb_intern("out")) {
|
||||||
index = EXEC_OPTION_DUP2;
|
|
||||||
param = INT2FIX(1);
|
param = INT2FIX(1);
|
||||||
|
eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
|
||||||
}
|
}
|
||||||
else if (id == rb_intern("err")) {
|
else if (id == rb_intern("err")) {
|
||||||
index = EXEC_OPTION_DUP2;
|
|
||||||
param = INT2FIX(2);
|
param = INT2FIX(2);
|
||||||
|
eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_raise(rb_eArgError, "wrong exec redirect symbol: %s",
|
rb_raise(rb_eArgError, "wrong exec redirect symbol: %s",
|
||||||
@ -1489,19 +1488,18 @@ check_exec_redirect(VALUE key, VALUE val, VALUE options)
|
|||||||
val = check_exec_redirect_fd(val, 0);
|
val = check_exec_redirect_fd(val, 0);
|
||||||
/* fall through */
|
/* fall through */
|
||||||
case T_FIXNUM:
|
case T_FIXNUM:
|
||||||
index = EXEC_OPTION_DUP2;
|
|
||||||
param = val;
|
param = val;
|
||||||
|
eargp->fd_dup2 = check_exec_redirect1(eargp->fd_dup2, key, param);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
path = rb_ary_entry(val, 0);
|
path = rb_ary_entry(val, 0);
|
||||||
if (RARRAY_LEN(val) == 2 && SYMBOL_P(path) &&
|
if (RARRAY_LEN(val) == 2 && SYMBOL_P(path) &&
|
||||||
SYM2ID(path) == rb_intern("child")) {
|
SYM2ID(path) == rb_intern("child")) {
|
||||||
index = EXEC_OPTION_DUP2_CHILD;
|
|
||||||
param = check_exec_redirect_fd(rb_ary_entry(val, 1), 0);
|
param = check_exec_redirect_fd(rb_ary_entry(val, 1), 0);
|
||||||
|
eargp->fd_dup2_child = check_exec_redirect1(eargp->fd_dup2_child, key, param);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
index = EXEC_OPTION_OPEN;
|
|
||||||
FilePathValue(path);
|
FilePathValue(path);
|
||||||
flags = rb_ary_entry(val, 1);
|
flags = rb_ary_entry(val, 1);
|
||||||
if (NIL_P(flags))
|
if (NIL_P(flags))
|
||||||
@ -1514,11 +1512,11 @@ check_exec_redirect(VALUE key, VALUE val, VALUE options)
|
|||||||
perm = NIL_P(perm) ? INT2FIX(0644) : rb_to_int(perm);
|
perm = NIL_P(perm) ? INT2FIX(0644) : rb_to_int(perm);
|
||||||
param = hide_obj(rb_ary_new3(3, hide_obj(rb_str_dup(path)),
|
param = hide_obj(rb_ary_new3(3, hide_obj(rb_str_dup(path)),
|
||||||
flags, perm));
|
flags, perm));
|
||||||
|
eargp->fd_open = check_exec_redirect1(eargp->fd_open, key, param);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
index = EXEC_OPTION_OPEN;
|
|
||||||
path = val;
|
path = val;
|
||||||
FilePathValue(path);
|
FilePathValue(path);
|
||||||
if (RB_TYPE_P(key, T_FILE))
|
if (RB_TYPE_P(key, T_FILE))
|
||||||
@ -1530,15 +1528,13 @@ check_exec_redirect(VALUE key, VALUE val, VALUE options)
|
|||||||
perm = INT2FIX(0644);
|
perm = INT2FIX(0644);
|
||||||
param = hide_obj(rb_ary_new3(3, hide_obj(rb_str_dup(path)),
|
param = hide_obj(rb_ary_new3(3, hide_obj(rb_str_dup(path)),
|
||||||
flags, perm));
|
flags, perm));
|
||||||
|
eargp->fd_open = check_exec_redirect1(eargp->fd_open, key, param);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rb_raise(rb_eArgError, "wrong exec redirect action");
|
rb_raise(rb_eArgError, "wrong exec redirect action");
|
||||||
}
|
}
|
||||||
|
|
||||||
ary = rb_ary_entry(options, index);
|
|
||||||
ary = check_exec_redirect1(ary, key, param);
|
|
||||||
rb_ary_store(options, index, ary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
|
#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
|
||||||
@ -1550,7 +1546,6 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
|
|||||||
{
|
{
|
||||||
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
|
struct rb_execarg *eargp = rb_execarg_get(execarg_obj);
|
||||||
|
|
||||||
VALUE options = eargp->options;
|
|
||||||
ID id;
|
ID id;
|
||||||
#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
|
#if defined(HAVE_SETRLIMIT) && defined(NUM2RLIM)
|
||||||
int rtype;
|
int rtype;
|
||||||
@ -1673,7 +1668,7 @@ rb_execarg_addopt(VALUE execarg_obj, VALUE key, VALUE val)
|
|||||||
case T_FILE:
|
case T_FILE:
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
redirect:
|
redirect:
|
||||||
check_exec_redirect(key, val, options);
|
check_exec_redirect(key, val, eargp);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1702,15 +1697,21 @@ check_exec_options_i(st_data_t st_key, st_data_t st_val, st_data_t arg)
|
|||||||
static VALUE
|
static VALUE
|
||||||
check_exec_fds(struct rb_execarg *eargp)
|
check_exec_fds(struct rb_execarg *eargp)
|
||||||
{
|
{
|
||||||
VALUE options = eargp->options;
|
|
||||||
VALUE h = rb_hash_new();
|
VALUE h = rb_hash_new();
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
int index, maxhint = -1;
|
int maxhint = -1;
|
||||||
long i;
|
long i;
|
||||||
|
int j;
|
||||||
|
VALUE fd_opts[] = {
|
||||||
|
eargp->fd_dup2,
|
||||||
|
eargp->fd_close,
|
||||||
|
eargp->fd_open,
|
||||||
|
eargp->fd_dup2_child
|
||||||
|
};
|
||||||
|
|
||||||
for (index = EXEC_OPTION_DUP2; index <= EXEC_OPTION_DUP2_CHILD; index++) {
|
for (j = 0; j < (int)(sizeof(fd_opts)/sizeof(*fd_opts)); j++) {
|
||||||
ary = rb_ary_entry(options, index);
|
ary = fd_opts[j];
|
||||||
if (NIL_P(ary))
|
if (ary == Qfalse)
|
||||||
continue;
|
continue;
|
||||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||||
VALUE elt = RARRAY_PTR(ary)[i];
|
VALUE elt = RARRAY_PTR(ary)[i];
|
||||||
@ -1718,15 +1719,15 @@ check_exec_fds(struct rb_execarg *eargp)
|
|||||||
if (RTEST(rb_hash_lookup(h, INT2FIX(fd)))) {
|
if (RTEST(rb_hash_lookup(h, INT2FIX(fd)))) {
|
||||||
rb_raise(rb_eArgError, "fd %d specified twice", fd);
|
rb_raise(rb_eArgError, "fd %d specified twice", fd);
|
||||||
}
|
}
|
||||||
if (index == EXEC_OPTION_OPEN || index == EXEC_OPTION_DUP2)
|
if (ary == eargp->fd_open || ary == eargp->fd_dup2)
|
||||||
rb_hash_aset(h, INT2FIX(fd), Qtrue);
|
rb_hash_aset(h, INT2FIX(fd), Qtrue);
|
||||||
else if (index == EXEC_OPTION_DUP2_CHILD)
|
else if (ary == eargp->fd_dup2_child)
|
||||||
rb_hash_aset(h, INT2FIX(fd), RARRAY_PTR(elt)[1]);
|
rb_hash_aset(h, INT2FIX(fd), RARRAY_PTR(elt)[1]);
|
||||||
else /* index == EXEC_OPTION_CLOSE */
|
else /* ary == eargp->fd_close */
|
||||||
rb_hash_aset(h, INT2FIX(fd), INT2FIX(-1));
|
rb_hash_aset(h, INT2FIX(fd), INT2FIX(-1));
|
||||||
if (maxhint < fd)
|
if (maxhint < fd)
|
||||||
maxhint = fd;
|
maxhint = fd;
|
||||||
if (index == EXEC_OPTION_DUP2 || index == EXEC_OPTION_DUP2_CHILD) {
|
if (ary == eargp->fd_dup2 || ary == eargp->fd_dup2_child) {
|
||||||
fd = FIX2INT(RARRAY_PTR(elt)[1]);
|
fd = FIX2INT(RARRAY_PTR(elt)[1]);
|
||||||
if (maxhint < fd)
|
if (maxhint < fd)
|
||||||
maxhint = fd;
|
maxhint = fd;
|
||||||
@ -1734,8 +1735,8 @@ check_exec_fds(struct rb_execarg *eargp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ary = rb_ary_entry(options, EXEC_OPTION_DUP2_CHILD);
|
if (eargp->fd_dup2_child) {
|
||||||
if (!NIL_P(ary)) {
|
ary = eargp->fd_dup2_child;
|
||||||
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
for (i = 0; i < RARRAY_LEN(ary); i++) {
|
||||||
VALUE elt = RARRAY_PTR(ary)[i];
|
VALUE elt = RARRAY_PTR(ary)[i];
|
||||||
int newfd = FIX2INT(RARRAY_PTR(elt)[0]);
|
int newfd = FIX2INT(RARRAY_PTR(elt)[0]);
|
||||||
@ -2126,8 +2127,8 @@ rb_execarg_fixup(VALUE execarg_obj)
|
|||||||
|
|
||||||
eargp->redirect_fds = check_exec_fds(eargp);
|
eargp->redirect_fds = check_exec_fds(eargp);
|
||||||
|
|
||||||
ary = rb_ary_entry(eargp->options, EXEC_OPTION_DUP2);
|
ary = eargp->fd_dup2;
|
||||||
if (!NIL_P(ary)) {
|
if (ary != Qfalse) {
|
||||||
size_t len = run_exec_dup2_tmpbuf_size(RARRAY_LEN(ary));
|
size_t len = run_exec_dup2_tmpbuf_size(RARRAY_LEN(ary));
|
||||||
VALUE tmpbuf = hide_obj(rb_str_new(0, len));
|
VALUE tmpbuf = hide_obj(rb_str_new(0, len));
|
||||||
rb_str_set_len(tmpbuf, len);
|
rb_str_set_len(tmpbuf, len);
|
||||||
@ -2349,7 +2350,6 @@ static int
|
|||||||
save_redirect_fd(int fd, struct rb_execarg *sargp, char *errmsg, size_t errmsg_buflen)
|
save_redirect_fd(int fd, struct rb_execarg *sargp, char *errmsg, size_t errmsg_buflen)
|
||||||
{
|
{
|
||||||
if (sargp) {
|
if (sargp) {
|
||||||
VALUE soptions = sargp->options;
|
|
||||||
VALUE newary;
|
VALUE newary;
|
||||||
int save_fd = redirect_dup(fd);
|
int save_fd = redirect_dup(fd);
|
||||||
if (save_fd == -1) {
|
if (save_fd == -1) {
|
||||||
@ -2359,18 +2359,18 @@ save_redirect_fd(int fd, struct rb_execarg *sargp, char *errmsg, size_t errmsg_b
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rb_update_max_fd(save_fd);
|
rb_update_max_fd(save_fd);
|
||||||
newary = rb_ary_entry(soptions, EXEC_OPTION_DUP2);
|
newary = sargp->fd_dup2;
|
||||||
if (NIL_P(newary)) {
|
if (newary == Qfalse) {
|
||||||
newary = hide_obj(rb_ary_new());
|
newary = hide_obj(rb_ary_new());
|
||||||
rb_ary_store(soptions, EXEC_OPTION_DUP2, newary);
|
sargp->fd_dup2 = newary;
|
||||||
}
|
}
|
||||||
rb_ary_push(newary,
|
rb_ary_push(newary,
|
||||||
hide_obj(rb_assoc_new(INT2FIX(fd), INT2FIX(save_fd))));
|
hide_obj(rb_assoc_new(INT2FIX(fd), INT2FIX(save_fd))));
|
||||||
|
|
||||||
newary = rb_ary_entry(soptions, EXEC_OPTION_CLOSE);
|
newary = sargp->fd_close;
|
||||||
if (NIL_P(newary)) {
|
if (newary == Qfalse) {
|
||||||
newary = hide_obj(rb_ary_new());
|
newary = hide_obj(rb_ary_new());
|
||||||
rb_ary_store(soptions, EXEC_OPTION_CLOSE, newary);
|
sargp->fd_close = newary;
|
||||||
}
|
}
|
||||||
rb_ary_push(newary, hide_obj(rb_assoc_new(INT2FIX(save_fd), Qnil)));
|
rb_ary_push(newary, hide_obj(rb_assoc_new(INT2FIX(save_fd), Qnil)));
|
||||||
}
|
}
|
||||||
@ -2789,14 +2789,14 @@ rb_execarg_run_options(const struct rb_execarg *eargp, struct rb_execarg *sargp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = rb_ary_entry(options, EXEC_OPTION_DUP2);
|
obj = eargp->fd_dup2;
|
||||||
if (!NIL_P(obj)) {
|
if (obj != Qfalse) {
|
||||||
if (run_exec_dup2(obj, eargp->dup2_tmpbuf, sargp, errmsg, errmsg_buflen) == -1) /* hopefully async-signal-safe */
|
if (run_exec_dup2(obj, eargp->dup2_tmpbuf, sargp, errmsg, errmsg_buflen) == -1) /* hopefully async-signal-safe */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = rb_ary_entry(options, EXEC_OPTION_CLOSE);
|
obj = eargp->fd_close;
|
||||||
if (!NIL_P(obj)) {
|
if (obj != Qfalse) {
|
||||||
if (sargp)
|
if (sargp)
|
||||||
rb_warn("cannot close fd before spawn");
|
rb_warn("cannot close fd before spawn");
|
||||||
else {
|
else {
|
||||||
@ -2811,14 +2811,14 @@ rb_execarg_run_options(const struct rb_execarg *eargp, struct rb_execarg *sargp,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
obj = rb_ary_entry(options, EXEC_OPTION_OPEN);
|
obj = eargp->fd_open;
|
||||||
if (!NIL_P(obj)) {
|
if (obj != Qfalse) {
|
||||||
if (run_exec_open(obj, sargp, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
|
if (run_exec_open(obj, sargp, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
obj = rb_ary_entry(options, EXEC_OPTION_DUP2_CHILD);
|
obj = eargp->fd_dup2_child;
|
||||||
if (!NIL_P(obj)) {
|
if (obj != Qfalse) {
|
||||||
if (run_exec_dup2_child(obj, sargp, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
|
if (run_exec_dup2_child(obj, sargp, errmsg, errmsg_buflen) == -1) /* async-signal-safe */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -2837,8 +2837,8 @@ rb_execarg_run_options(const struct rb_execarg *eargp, struct rb_execarg *sargp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sargp) {
|
if (sargp) {
|
||||||
VALUE ary = rb_ary_entry(sargp->options, EXEC_OPTION_DUP2);
|
VALUE ary = sargp->fd_dup2;
|
||||||
if (!NIL_P(ary)) {
|
if (ary != Qfalse) {
|
||||||
size_t len = run_exec_dup2_tmpbuf_size(RARRAY_LEN(ary));
|
size_t len = run_exec_dup2_tmpbuf_size(RARRAY_LEN(ary));
|
||||||
VALUE tmpbuf = hide_obj(rb_str_new(0, len));
|
VALUE tmpbuf = hide_obj(rb_str_new(0, len));
|
||||||
rb_str_set_len(tmpbuf, len);
|
rb_str_set_len(tmpbuf, len);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user