Commit 93d481d4 authored by Tomoyuki Sahara's avatar Tomoyuki Sahara

update $? when IO object is closed. closes #58.

parent e90ecff6
......@@ -47,7 +47,7 @@ struct mrb_data_type mrb_io_type = { "IO", mrb_io_free };
static struct mrb_io *io_get_open_fptr(mrb_state *mrb, mrb_value self);
static int mrb_io_modestr_to_flags(mrb_state *mrb, const char *modestr);
static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags);
static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise);
static void fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet);
#if MRUBY_RELEASE_NO < 10000
static struct RClass *
......@@ -69,6 +69,29 @@ io_get_open_fptr(mrb_state *mrb, mrb_value self)
return fptr;
}
#if !defined(_WIN32) && !defined(_WIN64)
static void
io_set_process_status(mrb_state *mrb, pid_t pid, int status)
{
struct RClass *c_process, *c_status;
mrb_value v;
c_status = NULL;
if (mrb_class_defined(mrb, "Process")) {
c_process = mrb_class_get(mrb, "Process");
if (mrb_const_defined(mrb, mrb_obj_value(c_process), mrb_intern_cstr(mrb, "Status"))) {
c_status = mrb_class_get_under(mrb, c_process, "Status");
}
}
if (c_status != NULL) {
v = mrb_funcall(mrb, mrb_obj_value(c_status), "new", 2, mrb_fixnum_value(pid), mrb_fixnum_value(status));
} else {
v = mrb_fixnum_value(WEXITSTATUS(status));
}
mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$?"), v);
}
#endif
static int
mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode)
{
......@@ -389,7 +412,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
fptr = DATA_PTR(io);
if (fptr != NULL) {
fptr_finalize(mrb, fptr, 0);
fptr_finalize(mrb, fptr, TRUE);
mrb_free(mrb, fptr);
}
fptr = mrb_io_alloc(mrb);
......@@ -404,7 +427,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
}
static void
fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise)
fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int quiet)
{
int n = 0;
......@@ -428,13 +451,17 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise)
#if !defined(_WIN32) && !defined(_WIN64)
if (fptr->pid != 0) {
pid_t pid;
int status;
do {
pid = waitpid(fptr->pid, NULL, 0);
pid = waitpid(fptr->pid, &status, 0);
} while (pid == -1 && errno == EINTR);
if (!quiet && pid == fptr->pid) {
io_set_process_status(mrb, pid, status);
}
}
#endif
if (!noraise && n != 0) {
if (!quiet && n != 0) {
mrb_sys_fail(mrb, "fptr_finalize failed.");
}
}
......
......@@ -372,6 +372,7 @@ end
assert('IO.popen') do
begin
$? = nil
io = IO.popen("ls")
assert_true io.close_on_exec?
assert_equal Fixnum, io.pid.class
......@@ -379,7 +380,13 @@ assert('IO.popen') do
assert_equal ls.class, String
assert_include ls, 'AUTHORS'
assert_include ls, 'mrblib'
io.close
if Object.const_defined? :Process
assert_true $?.success?
else
assert_equal 0, $?
end
io.closed?
rescue NotImplementedError => e
skip e.message
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment