summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-29 14:13:20 +0000
committerakr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-05-29 14:13:20 +0000
commit52e91e0f721057d133b2020c10a3abe390fc1732 (patch)
tree7a0af9325b035ff384c9c82a16bcb53d8125aedc /io.c
parent6f39cf2d1e9677e29fefc76bc22b167b1e987624 (diff)
* io.c (pipe_open): Close pipes when rb_execarg_fixup() raises
an exception. (rb_execarg_fixup_v): New function. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46232 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'io.c')
-rw-r--r--io.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/io.c b/io.c
index 20c093aa43..40ee3d435d 100644
--- a/io.c
+++ b/io.c
@@ -5870,6 +5870,13 @@ popen_exec(void *pp, char *errmsg, size_t errmsg_len)
#endif
static VALUE
+rb_execarg_fixup_v(VALUE execarg_obj)
+{
+ rb_execarg_fixup(execarg_obj);
+ return Qnil;
+}
+
+static VALUE
pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convconfig)
{
struct rb_execarg *eargp = NIL_P(execarg_obj) ? NULL : rb_execarg_get(execarg_obj);
@@ -5884,6 +5891,7 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
char errmsg[80] = { '\0' };
#endif
#if defined(HAVE_FORK) || defined(HAVE_SPAWNV)
+ int state;
struct popen_arg arg;
int e = 0;
#endif
@@ -5964,7 +5972,15 @@ pipe_open(VALUE execarg_obj, const char *modestr, int fmode, convconfig_t *convc
rb_sys_fail_str(prog);
}
if (!NIL_P(execarg_obj)) {
- rb_execarg_fixup(execarg_obj);
+ rb_protect(rb_execarg_fixup_v, execarg_obj, &state);
+ if (state) {
+ if (0 <= arg.write_pair[0]) close(arg.write_pair[0]);
+ if (0 <= arg.write_pair[1]) close(arg.write_pair[1]);
+ if (0 <= arg.pair[0]) close(arg.pair[0]);
+ if (0 <= arg.pair[1]) close(arg.pair[1]);
+ rb_jump_tag(state);
+ }
+
# if defined(HAVE_FORK)
pid = rb_fork_async_signal_safe(&status, popen_exec, &arg, arg.eargp->redirect_fds, errmsg, sizeof(errmsg));
# else