summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorTomoyuki Sahara <[email protected]>2016-06-22 10:29:49 +0900
committerTomoyuki Sahara <[email protected]>2016-06-22 10:29:49 +0900
commit93d481d4b49829e37b1f501c7307663c6327dfab (patch)
tree69e361a7bcbfc055c21b085ebb53899b98a9ca8b /src
parente90ecff67187f612c4e6bfab32b4fed490b41c64 (diff)
downloadmruby-93d481d4b49829e37b1f501c7307663c6327dfab.tar.gz
mruby-93d481d4b49829e37b1f501c7307663c6327dfab.zip
update $? when IO object is closed. closes #58.
Diffstat (limited to 'src')
-rw-r--r--src/io.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/io.c b/src/io.c
index 3f2d5edab..42e9a93a8 100644
--- a/src/io.c
+++ b/src/io.c
@@ -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.");
}
}