[svn:parrot] r39014 - in trunk/src: io pmc

NotFound at svn.parrot.org NotFound at svn.parrot.org
Thu May 21 16:01:08 UTC 2009


Author: NotFound
Date: Thu May 21 16:01:08 2009
New Revision: 39014
URL: https://trac.parrot.org/parrot/changeset/39014

Log:
[core] fix unix pipe handling, now write pipes must works reliably

Modified:
   trunk/src/io/unix.c
   trunk/src/pmc/filehandle.pmc

Modified: trunk/src/io/unix.c
==============================================================================
--- trunk/src/io/unix.c	Thu May 21 15:03:41 2009	(r39013)
+++ trunk/src/io/unix.c	Thu May 21 16:01:08 2009	(r39014)
@@ -33,6 +33,9 @@
 
 #ifdef PIO_OS_UNIX
 
+#include <sys/types.h>
+#include <sys/wait.h>
+
 /* HEADERIZER HFILE: include/parrot/io_unix.h */
 
 /* HEADERIZER BEGIN: static */
@@ -335,11 +338,22 @@
     ASSERT_ARGS(Parrot_io_close_unix)
     INTVAL result = 0;
     PIOHANDLE file_descriptor = Parrot_io_get_os_handle(interp, filehandle);
+    int flags = Parrot_io_get_flags(interp, filehandle);
+
     /* BSD and Solaris need explicit fsync() */
     if (file_descriptor >= 0) {
         fsync(file_descriptor);
         if (close(file_descriptor) != 0)
             result = errno;
+
+        /* Pipes reuse the file_size attribute to store the child
+         * process pid.
+         * Wait for the child after closing the
+         * handle, to let it notice the closing and finish */
+        if (flags & PIO_F_PIPE) {
+            int status;
+            waitpid(Parrot_io_get_file_size(interp, filehandle), &status, 0);
+        }
     }
     Parrot_io_set_os_handle(interp, filehandle, -1);
     return result;
@@ -655,7 +669,7 @@
     if (pid < 0) {
         /* fork failed, cleaning up */
         close(fds[0]);
-	close(fds[1]);
+        close(fds[1]);
         Parrot_ex_throw_from_c_args(interp, NULL, EXCEPTION_PIO_ERROR,
             "fork failed: %s", strerror(errno));
     }
@@ -667,8 +681,8 @@
         else
             io = filehandle;
 
-        Parrot_io_set_flags(interp, io,
-                (Parrot_io_get_flags(interp, io) & (~PIO_F_PIPE)));
+        /* Save the pid of the child, we'll wait for it when closing */
+        Parrot_io_set_file_size(interp, io, pid);
 
         if (f_read) {
             /* close this writer's end of pipe */
@@ -703,7 +717,7 @@
             /* XXX redirect stdout, stderr to pipe */
             close(STDOUT_FILENO);
             close(STDERR_FILENO);
-	    close(fds[0]);
+            close(fds[0]);
 
             if (Parrot_dup(fds[1]) != STDOUT_FILENO)
                 exit(EXIT_FAILURE);
@@ -718,7 +732,7 @@
         execv(argv [0], argv);
 
         /* Will never reach this unless exec fails.
-	   No need to clean up, we're just going to exit */
+         * No need to clean up, we're just going to exit */
         perror("execvp");
         exit(EXIT_FAILURE);
     }

Modified: trunk/src/pmc/filehandle.pmc
==============================================================================
--- trunk/src/pmc/filehandle.pmc	Thu May 21 15:03:41 2009	(r39013)
+++ trunk/src/pmc/filehandle.pmc	Thu May 21 16:01:08 2009	(r39014)
@@ -38,7 +38,7 @@
     ATTR STRING *mode;                /* The mode string used in open */
     ATTR STRING *encoding;            /* The encoding for read/write  */
     ATTR PIOHANDLE os_handle;         /* Low level OS descriptor      */
-    ATTR PIOOFF_T file_size;          /* Current file size            */
+    ATTR PIOOFF_T file_size;          /* Current file size - pipe pid */
     ATTR PIOOFF_T file_pos;           /* Current real file pointer    */
     ATTR PIOOFF_T last_pos;           /* Last file position           */
     ATTR size_t buffer_size;          /* Buffer size                  */


More information about the parrot-commits mailing list