[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