[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) )
{
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r32447 - msh/src,
gnunet <=