gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r32447 - msh/src


From: gnunet
Subject: [GNUnet-SVN] r32447 - msh/src
Date: Thu, 20 Feb 2014 14:34:54 +0100

Author: harsha
Date: 2014-02-20 14:34:54 +0100 (Thu, 20 Feb 2014)
New Revision: 32447

Modified:
   msh/src/launch.c
   msh/src/server.c
Log:
Fix calls to GNUNET_OS_process_start() as it has been changed in upstream.
Add support for redirecting stderr from child processes.


Modified: msh/src/launch.c
===================================================================
--- msh/src/launch.c    2014-02-20 13:25:53 UTC (rev 32446)
+++ msh/src/launch.c    2014-02-20 13:34:54 UTC (rev 32447)
@@ -20,6 +20,7 @@
                                       GNUNET_OS_INHERIT_STD_NONE,
                                       pin,
                                       pout,
+                                      NULL,
                                       cmd[0], cmd);
   GNUNET_assert (NULL != proc);
   fin = GNUNET_DISK_pipe_detach_end (pin, GNUNET_DISK_PIPE_END_WRITE);

Modified: msh/src/server.c
===================================================================
--- msh/src/server.c    2014-02-20 13:25:53 UTC (rev 32446)
+++ msh/src/server.c    2014-02-20 13:34:54 UTC (rev 32447)
@@ -82,6 +82,11 @@
    * file handle for processes output
    */
   struct GNUNET_DISK_FileHandle *fout;
+
+  /**
+   * file handle for processes output
+   */
+  struct GNUNET_DISK_FileHandle *ferr;
   
   /**
    * input buffer.  Data from this buffer is written to proc's STDIN when it is
@@ -116,6 +121,11 @@
   GNUNET_SCHEDULER_TaskIdentifier fout_task;
 
   /**
+   * task to read the error output from the process
+   */
+  GNUNET_SCHEDULER_TaskIdentifier ferr_task;
+
+  /**
    * task to write data received from the client to proc's STDIN
    */
   GNUNET_SCHEDULER_TaskIdentifier fin_task;
@@ -178,10 +188,14 @@
   }
   GNUNET_DISK_file_close (ctx->fin);
   GNUNET_DISK_file_close (ctx->fout);
+  if (NULL != ctx->ferr)
+    GNUNET_DISK_file_close (ctx->ferr);
   if (GNUNET_SCHEDULER_NO_TASK != ctx->timeout_task)
     GNUNET_SCHEDULER_cancel (ctx->timeout_task);
   if (GNUNET_SCHEDULER_NO_TASK != ctx->fout_task)
     GNUNET_SCHEDULER_cancel (ctx->fout_task);
+  if (GNUNET_SCHEDULER_NO_TASK != ctx->ferr_task)
+    GNUNET_SCHEDULER_cancel (ctx->ferr_task);
   if (NULL != ctx->buf)
     GNUNET_free (ctx->buf);
   GNUNET_free_non_null (ctx->pty_mode);
@@ -497,6 +511,38 @@
 
 
 /**
+ * Function to read from the given stream and write to the given client
+ *
+ * @param fd the file handler for the stream to redirect to the client
+ * @param client the client to send to
+ * @return GNUNET_OK upon success; GNUNET_SYSERR upon error
+ */
+static int
+redirect_stream (struct GNUNET_DISK_FileHandle *fd,
+                 struct GNUNET_SERVER_Client *client)
+{
+
+  struct MSH_MSG_CmdIO *msg;
+  static char data[MAX_IO_DATA];
+  ssize_t size;
+  uint16_t msize;
+  
+  errno = 0;
+  size = GNUNET_DISK_file_read_non_blocking (fd, data, MAX_IO_DATA);
+  if (size <= 0)
+    return GNUNET_SYSERR;
+  msize = size + sizeof (struct MSH_MSG_CmdIO);
+  msg = GNUNET_malloc (msize);
+  msg->header.type = htons (MSH_MTYPE_CMD_STREAM_STDOUT);
+  msg->header.size = htons (msize);
+  memcpy (msg->data, data, size);
+  GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, client,
+                                              &msg->header, GNUNET_NO);
+  return GNUNET_OK;
+}
+
+
+/**
  * Task to read the output from a process and send it to client
  *
  * @param cls the client context
@@ -506,30 +552,16 @@
 read_fout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct ExecCtx *exec_ctx = cls;
-  struct MSH_MSG_CmdIO *msg;
-  static char data[MAX_IO_DATA];
-  ssize_t size;
-  uint16_t msize;
 
   exec_ctx->fout_task = GNUNET_SCHEDULER_NO_TASK;
   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
-  {
     return;
-  }
-  errno = 0;
-  size = GNUNET_DISK_file_read_non_blocking (exec_ctx->fout, data, 
MAX_IO_DATA);
-  if (size <= 0)
+  if (GNUNET_SYSERR == redirect_stream (exec_ctx->fout,
+                                        exec_ctx->client))
   {
     GNUNET_SERVER_client_disconnect (exec_ctx->client);
     return;
   }
-  msize = size + sizeof (struct MSH_MSG_CmdIO);
-  msg = GNUNET_malloc (msize);
-  msg->header.type = htons (MSH_MTYPE_CMD_STREAM_STDOUT);
-  msg->header.size = htons (msize);
-  memcpy (msg->data, data, size);
-  GNUNET_SERVER_notification_context_unicast (daemon_serv_nc, exec_ctx->client,
-                                              &msg->header, GNUNET_NO);
   exec_ctx->fout_task = 
       GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                       exec_ctx->fout, &read_fout, exec_ctx);
@@ -537,6 +569,32 @@
 
 
 /**
+ * Task to read the output from a process and send it to client
+ *
+ * @param cls the client context
+ * @param tc scheduler task context
+ */
+static void
+read_ferr (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ExecCtx *exec_ctx = cls;
+
+  exec_ctx->ferr_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+    return;
+  if (GNUNET_SYSERR == redirect_stream (exec_ctx->ferr,
+                                        exec_ctx->client))
+  {
+    GNUNET_SERVER_client_disconnect (exec_ctx->client);
+    return;
+  }
+  exec_ctx->ferr_task = 
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                      exec_ctx->ferr, &read_ferr, exec_ctx);
+}
+
+
+/**
  * Configure the terminal for the child
  */
 static int
@@ -635,6 +693,11 @@
   exec_ctx->child_pid = 0;
   GNUNET_SCHEDULER_cancel (exec_ctx->fout_task);
   exec_ctx->fout_task = GNUNET_SCHEDULER_add_now (&read_fout, exec_ctx);
+  if (GNUNET_SCHEDULER_NO_TASK != exec_ctx->ferr_task)
+  {
+    GNUNET_SCHEDULER_cancel (exec_ctx->ferr_task);
+    exec_ctx->ferr_task = GNUNET_SCHEDULER_add_now (&read_ferr, exec_ctx);
+  }
 }
 
 
@@ -649,6 +712,7 @@
 {
   struct GNUNET_DISK_PipeHandle *pin;
   struct GNUNET_DISK_PipeHandle *pout;
+  struct GNUNET_DISK_PipeHandle *perr;
   struct GNUNET_OS_Process *proc;
   char *fnpty;
   char *termstr;
@@ -662,11 +726,13 @@
     LOG_DEBUG ("Execing non interactively `%s'\n", ctx->args[0]);
     pin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, 0, 0);
     pout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_YES, 0, 0);
-    GNUNET_assert ((NULL != pin && (NULL != pout)));
+    perr = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_YES, 0, 0);
+    GNUNET_assert ((NULL != pin && (NULL != pout) && (NULL != perr)));
     proc = GNUNET_OS_start_process_vap (GNUNET_NO,
                                         GNUNET_OS_INHERIT_STD_NONE,
                                         pin,
                                         pout,
+                                        perr,
                                         ctx->args[0],
                                         ctx->args);
     if (NULL == proc)
@@ -676,12 +742,17 @@
     MSH_monitor_process_pid (ctx->child_pid, &proc_exit_cb, ctx);
     ctx->fin = GNUNET_DISK_pipe_detach_end (pin, GNUNET_DISK_PIPE_END_WRITE);
     ctx->fout = GNUNET_DISK_pipe_detach_end (pout, GNUNET_DISK_PIPE_END_READ);
-    GNUNET_assert ((NULL != ctx->fin && (NULL != ctx->fout)));
+    ctx->ferr = GNUNET_DISK_pipe_detach_end (perr, GNUNET_DISK_PIPE_END_READ);
+    GNUNET_assert (((NULL != ctx->fin) && (NULL != ctx->fout) && (NULL != 
ctx->fout)));
     GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pin));
     GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pout));
+    GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (perr));
     ctx->fout_task = 
         GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                         ctx->fout, &read_fout, ctx);
+    ctx->ferr_task = 
+        GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                        ctx->ferr, &read_ferr, ctx);
     return GNUNET_OK;
   }
   LOG_DEBUG ("Execing interactively `%s'\n", ctx->args[0]);
@@ -707,6 +778,9 @@
     /* forward streams to and from child */
     fd_in = dup (ctx->master);
     fd_out = dup (ctx->master);
+    /* We don't have to forward stderr here as that stream can also be read
+       from fd_out since it gets muxed at the pty */
+    //fd_err = dup (ctx->master);
     GNUNET_break (0 == close (ctx->master));
     if ( (-1 == fd_in) || (-1 == fd_out) )
     {




reply via email to

[Prev in Thread] Current Thread [Next in Thread]