[svn:parrot] r42521 - in trunk: config/gen/makefiles config/gen/platform/generic src/io src/pmc t/pmc

cotto at svn.parrot.org cotto at svn.parrot.org
Sat Nov 14 21:57:15 UTC 2009


Author: cotto
Date: Sat Nov 14 21:57:13 2009
New Revision: 42521
URL: https://trac.parrot.org/parrot/changeset/42521

Log:
[pmc] make the FileHandle PMC keep track and expose the exit code of a child process run as a pipe
cconstantine++ for windows testing

Modified:
   trunk/config/gen/makefiles/root.in
   trunk/config/gen/platform/generic/exec.c
   trunk/src/io/unix.c
   trunk/src/io/win32.c
   trunk/src/pmc/filehandle.pmc
   trunk/t/pmc/filehandle.t

Modified: trunk/config/gen/makefiles/root.in
==============================================================================
--- trunk/config/gen/makefiles/root.in	Sat Nov 14 20:46:05 2009	(r42520)
+++ trunk/config/gen/makefiles/root.in	Sat Nov 14 21:57:13 2009	(r42521)
@@ -890,9 +890,9 @@
 $(IO_DIR)/core$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/pmc/socket.c
 $(IO_DIR)/socket_api$(O) : $(INC_DIR)/parrot.h $(SRC_DIR)/pmc/socket.c
 $(IO_DIR)/socket_unix$(O) : $(INC_DIR)/parrot.h $(INC_DIR)/pbcversion.h   \
-                            $(SRC_DIR)/pmc/socket.c
+                            $(SRC_DIR)/pmc/socket.c $(PMC_INC_DIR)/pmc/pmc_filehandle.h
 $(IO_DIR)/socket_win32$(O) : $(INC_DIR)/parrot.h $(INC_DIR)/pbcversion.h   \
-                            $(SRC_DIR)/pmc/socket.c
+                            $(SRC_DIR)/pmc/socket.c $(PMC_INC_DIR)/pmc/pmc_filehandle.h
 
 lib_deps_object : $(O_FILES)
 	$(PERL) tools/dev/lib_deps.pl object $(O_FILES)

Modified: trunk/config/gen/platform/generic/exec.c
==============================================================================
--- trunk/config/gen/platform/generic/exec.c	Sat Nov 14 20:46:05 2009	(r42520)
+++ trunk/config/gen/platform/generic/exec.c	Sat Nov 14 21:57:13 2009	(r42521)
@@ -49,8 +49,7 @@
     if (child) {
         /* parent */
         int   status;
-        pid_t returnstat = waitpid(child, &status, 0);
-        UNUSED(returnstat);
+        waitpid(child, &status, 0);
         return status;
     }
     else {

Modified: trunk/src/io/unix.c
==============================================================================
--- trunk/src/io/unix.c	Sat Nov 14 20:46:05 2009	(r42520)
+++ trunk/src/io/unix.c	Sat Nov 14 21:57:13 2009	(r42521)
@@ -30,6 +30,7 @@
 
 #include "parrot/parrot.h"
 #include "io_private.h"
+#include "pmc/pmc_filehandle.h"
 
 #ifdef PIO_OS_UNIX
 
@@ -352,6 +353,13 @@
         if (flags & PIO_F_PIPE) {
             int status;
             waitpid(VTABLE_get_integer_keyed_int(interp, filehandle, 0), &status, 0);
+            if (WIFEXITED(status)) {
+                SETATTR_FileHandle_exit_status(interp, filehandle, WEXITSTATUS(status));
+            }
+            else {
+                /* abnormal termination means non-zero exit status */
+                SETATTR_FileHandle_exit_status(interp, filehandle, 1);
+            }
         }
     }
     Parrot_io_set_os_handle(interp, filehandle, -1);

Modified: trunk/src/io/win32.c
==============================================================================
--- trunk/src/io/win32.c	Sat Nov 14 20:46:05 2009	(r42520)
+++ trunk/src/io/win32.c	Sat Nov 14 21:57:13 2009	(r42521)
@@ -27,6 +27,7 @@
 #endif
 
 #include "parrot/parrot.h"
+#include "pmc/pmc_filehandle.h"
 #include "io_private.h"
 
 #ifdef PIO_OS_WIN32
@@ -336,10 +337,17 @@
         if (CloseHandle(os_handle) == 0)
             result = GetLastError();
         Parrot_io_set_os_handle(interp, filehandle, INVALID_HANDLE_VALUE);
+
         if (flags & PIO_F_PIPE) {
-            INTVAL procid =  VTABLE_get_integer_keyed_int(interp, filehandle, 0);
+            INTVAL procid  = VTABLE_get_integer_keyed_int(interp, filehandle, 0);
             HANDLE process = (HANDLE) procid;
-            WaitForSingleObject(process, INFINITE);
+            DWORD  status  = WaitForSingleObject(process, INFINITE);
+            DWORD  exit_code;
+
+            if (status != WAIT_FAILED && GetExitCodeProcess(process, &exit_code))
+                SETATTR_FileHandle_exit_status(interp, filehandle, exit_code);
+            else
+                SETATTR_FileHandle_exit_status(interp, filehandle, 1);
             CloseHandle(process);
         }
     }

Modified: trunk/src/pmc/filehandle.pmc
==============================================================================
--- trunk/src/pmc/filehandle.pmc	Sat Nov 14 20:46:05 2009	(r42520)
+++ trunk/src/pmc/filehandle.pmc	Sat Nov 14 21:57:13 2009	(r42521)
@@ -37,6 +37,7 @@
     ATTR STRING *mode;                /* The mode string used in open */
     ATTR STRING *encoding;            /* The encoding for read/write  */
     ATTR INTVAL process_id;           /* Child process on pipes       */
+    ATTR INTVAL exit_status;          /* Child exit status on pipes   */
     ATTR PIOOFF_T file_size;          /* Current file size            */
     ATTR PIOOFF_T file_pos;           /* Current real file pointer    */
     ATTR PIOOFF_T last_pos;           /* Last file position           */
@@ -70,6 +71,7 @@
         data_struct->mode          = NULL;
         data_struct->encoding      = NULL;
         data_struct->process_id    = 0;
+        data_struct->exit_status   = 0;
         data_struct->file_size     = 0;
         data_struct->file_pos      = piooffsetzero;
         data_struct->last_pos      = piooffsetzero;
@@ -666,6 +668,21 @@
         RETURN(INTVAL flags);
     }
 
+/*
+
+=item C<METHOD exit_status()>
+
+If this is a pipe, return the exit status of the child process.
+
+=cut
+
+*/
+    METHOD exit_status() {
+        INTVAL exit_status;
+        GET_ATTR_exit_status(INTERP, SELF, exit_status);
+        RETURN(INTVAL exit_status);
+    }
+
 
 /*
 

Modified: trunk/t/pmc/filehandle.t
==============================================================================
--- trunk/t/pmc/filehandle.t	Sat Nov 14 20:46:05 2009	(r42520)
+++ trunk/t/pmc/filehandle.t	Sat Nov 14 21:57:13 2009	(r42521)
@@ -7,7 +7,7 @@
 use lib qw( . lib ../lib ../../lib );
 
 use Test::More;
-use Parrot::Test tests => 17;
+use Parrot::Test tests => 18;
 use Parrot::Test::Util 'create_tempfile';
 use Parrot::Test::Util 'create_tempfile';
 
@@ -585,6 +585,35 @@
 utf8
 OUTPUT
 
+pir_output_is( <<"CODE", <<"OUTPUT", "exit status" );
+.sub 'main'
+    .local pmc pipe
+    .local string cmd
+    pipe = new ['FileHandle']
+
+    cmd = 'parrot'
+    pipe = open cmd, "rp"
+    pipe.'readall'()
+    pipe.'close'()
+    print "expect 0 exit status: "
+    \$I0 = pipe.'exit_status'()
+    say \$I0
+
+    cmd = 'parrot --this_is_not_a_valid_option'
+    pipe = open cmd, "rp"
+    pipe.'readall'()
+    pipe.'close'()
+    print "expect 1 exit status: "
+    \$I0 = pipe.'exit_status'()
+    \$I0 = \$I0 != 0
+    say \$I0
+
+.end
+CODE
+expect 0 exit status: 0
+expect 1 exit status: 1
+OUTPUT
+
 # RT #46843
 # L<PDD22/I\/O PMC API/=item get_fd>
 # NOTES: this is going to be platform dependent


More information about the parrot-commits mailing list