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 }; ...@@ -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 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_modestr_to_flags(mrb_state *mrb, const char *modestr);
static int mrb_io_flags_to_modenum(mrb_state *mrb, int flags); 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 #if MRUBY_RELEASE_NO < 10000
static struct RClass * static struct RClass *
...@@ -69,6 +69,29 @@ io_get_open_fptr(mrb_state *mrb, mrb_value self) ...@@ -69,6 +69,29 @@ io_get_open_fptr(mrb_state *mrb, mrb_value self)
return fptr; 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 static int
mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode) mrb_io_modestr_to_flags(mrb_state *mrb, const char *mode)
{ {
...@@ -389,7 +412,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) ...@@ -389,7 +412,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
fptr = DATA_PTR(io); fptr = DATA_PTR(io);
if (fptr != NULL) { if (fptr != NULL) {
fptr_finalize(mrb, fptr, 0); fptr_finalize(mrb, fptr, TRUE);
mrb_free(mrb, fptr); mrb_free(mrb, fptr);
} }
fptr = mrb_io_alloc(mrb); fptr = mrb_io_alloc(mrb);
...@@ -404,7 +427,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io) ...@@ -404,7 +427,7 @@ mrb_io_initialize(mrb_state *mrb, mrb_value io)
} }
static void 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; int n = 0;
...@@ -428,13 +451,17 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise) ...@@ -428,13 +451,17 @@ fptr_finalize(mrb_state *mrb, struct mrb_io *fptr, int noraise)
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64)
if (fptr->pid != 0) { if (fptr->pid != 0) {
pid_t pid; pid_t pid;
int status;
do { do {
pid = waitpid(fptr->pid, NULL, 0); pid = waitpid(fptr->pid, &status, 0);
} while (pid == -1 && errno == EINTR); } while (pid == -1 && errno == EINTR);
if (!quiet && pid == fptr->pid) {
io_set_process_status(mrb, pid, status);
}
} }
#endif #endif
if (!noraise && n != 0) { if (!quiet && n != 0) {
mrb_sys_fail(mrb, "fptr_finalize failed."); mrb_sys_fail(mrb, "fptr_finalize failed.");
} }
} }
......
...@@ -372,6 +372,7 @@ end ...@@ -372,6 +372,7 @@ end
assert('IO.popen') do assert('IO.popen') do
begin begin
$? = nil
io = IO.popen("ls") io = IO.popen("ls")
assert_true io.close_on_exec? assert_true io.close_on_exec?
assert_equal Fixnum, io.pid.class assert_equal Fixnum, io.pid.class
...@@ -379,7 +380,13 @@ assert('IO.popen') do ...@@ -379,7 +380,13 @@ assert('IO.popen') do
assert_equal ls.class, String assert_equal ls.class, String
assert_include ls, 'AUTHORS' assert_include ls, 'AUTHORS'
assert_include ls, 'mrblib' assert_include ls, 'mrblib'
io.close io.close
if Object.const_defined? :Process
assert_true $?.success?
else
assert_equal 0, $?
end
io.closed? io.closed?
rescue NotImplementedError => e rescue NotImplementedError => e
skip e.message 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