driver: New function output_log_nocopy().
[pspp] / src / language / utilities / host.c
index 4a32d463973862739942190cae7cadccb5aa5739..d730e02634860e4286a7ca245e45bc810394ed9a 100644 (file)
@@ -38,8 +38,9 @@
 #include "libpspp/str.h"
 #include "libpspp/string-array.h"
 #include "libpspp/temp-file.h"
-#include "output/text-item.h"
+#include "output/driver.h"
 
+#include "gl/error.h"
 #include "gl/intprops.h"
 #include "gl/localcharset.h"
 #include "gl/read-file.h"
@@ -121,6 +122,11 @@ run_command (const char *command, struct timespec timeout)
     {
       /* Running in the child. */
 
+#if __GNU__
+      /* Hurd doesn't support inheriting process timers in a way that works. */
+      if (setpgid (0, 0) < 0)
+        error (1, errno, _("Failed to set process group."));
+#else
       /* Set up timeout. */
       if (timeout.tv_sec < TYPE_MAXIMUM (time_t))
         {
@@ -136,8 +142,10 @@ run_command (const char *command, struct timespec timeout)
               .tv_usec = left.tv_nsec / 1000
             }
           };
-          setitimer (ITIMER_REAL, &it, NULL);
+          if (setitimer (ITIMER_REAL, &it, NULL) < 0)
+            error (1, errno, _("Failed to set timeout."));
         }
+#endif
 
       /* Set up file descriptors:
          - /dev/null for stdin
@@ -172,7 +180,15 @@ run_command (const char *command, struct timespec timeout)
   int error = 0;
   for (;;)
     {
-      pid_t retval = waitpid (pid, &status, 0);
+#if __GNU__
+      if (timespec_cmp (current_timespec (), timeout) >= 0)
+        kill (-pid, SIGALRM);
+
+      int flags = WNOHANG;
+#else
+      int flags = 0;
+#endif
+      pid_t retval = waitpid (pid, &status, flags);
       if (retval == pid)
         break;
       else if (retval < 0)
@@ -183,6 +199,10 @@ run_command (const char *command, struct timespec timeout)
               break;
             }
         }
+#if __GNU__
+      else if (retval == 0)
+        sleep (1);
+#endif
       else
         NOT_REACHED ();
     }
@@ -241,7 +261,7 @@ run_command (const char *command, struct timespec timeout)
       if (end > output && end[-1] == '\n')
         end[-1] = '\0';
 
-      text_item_submit (text_item_create_nocopy (TEXT_ITEM_LOG, output));
+      output_log_nocopy (output);
     }
   free (locale_output);