gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] r28582 - msh/src


From: gnunet
Subject: [GNUnet-SVN] r28582 - msh/src
Date: Tue, 13 Aug 2013 21:09:36 +0200

Author: harsha
Date: 2013-08-13 21:09:35 +0200 (Tue, 13 Aug 2013)
New Revision: 28582

Added:
   msh/src/launch.c
   msh/src/prop.c
   msh/src/run.sh
Modified:
   msh/src/Makefile.am
   msh/src/msh.c
   msh/src/mshd-server.c
Log:
- handle input in nonblocking mode


Modified: msh/src/Makefile.am
===================================================================
--- msh/src/Makefile.am 2013-08-13 17:49:45 UTC (rev 28581)
+++ msh/src/Makefile.am 2013-08-13 19:09:35 UTC (rev 28582)
@@ -26,4 +26,9 @@
   test-bitmap \
   test-addressmap
 
+noinst_PROGRAMS = prop launch
+prop_SOURCES = prop.c
+prop_LDADD = -lgnunetutil
 
+launch_SOURCES = launch.c
+launch_LDADD = -lgnunetutil

Added: msh/src/launch.c
===================================================================
--- msh/src/launch.c                            (rev 0)
+++ msh/src/launch.c    2013-08-13 19:09:35 UTC (rev 28582)
@@ -0,0 +1,40 @@
+#include "common.h"
+#include <gnunet/gnunet_util_lib.h>
+
+int main ()
+{
+  struct GNUNET_OS_Process *proc;
+  struct GNUNET_DISK_PipeHandle *pin;
+  struct GNUNET_DISK_PipeHandle *pout;
+  struct GNUNET_DISK_FileHandle *fin;
+  struct GNUNET_DISK_FileHandle *fout;
+  char *cmd[] = {"./prop", NULL};
+  char *str = "Hello World";
+  char buf[256];
+  ssize_t read;
+
+  GNUNET_log_setup ("msh-launch", NULL, NULL);
+  pin = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
+  pout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
+  proc = GNUNET_OS_start_process_vap (GNUNET_NO,
+                                      GNUNET_OS_INHERIT_STD_ERR,
+                                      pin,
+                                      pout,
+                                      cmd[0], cmd);
+  GNUNET_assert (NULL != proc);
+  fin = GNUNET_DISK_pipe_detach_end (pin, GNUNET_DISK_PIPE_END_WRITE);
+  fout = GNUNET_DISK_pipe_detach_end (pout, GNUNET_DISK_PIPE_END_READ);
+  GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pin));
+  GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pout));
+  /* GNUNET_break (strlen (str) */
+  /*               == GNUNET_DISK_file_write_blocking (fin, str, strlen 
(str))); */
+  read = GNUNET_DISK_file_read (fout, buf, sizeof (buf));
+  GNUNET_assert (GNUNET_SYSERR != read);
+  if (0 == read)
+  {
+    GNUNET_break (0);
+    return 1;
+  }
+  fwrite (buf, read, 1, stdout);
+  return 0;
+}

Modified: msh/src/msh.c
===================================================================
--- msh/src/msh.c       2013-08-13 17:49:45 UTC (rev 28581)
+++ msh/src/msh.c       2013-08-13 19:09:35 UTC (rev 28582)
@@ -402,10 +402,13 @@
   }
   if (0 == size)
   {
-    GNUNET_break (0);
-    goto reschedule;
-  }
+    GNUNET_DISK_file_close (fh_stdin);
+    fh_stdin = NULL;
+    GNUNET_SCHEDULER_shutdown ();
+    return;
+  }  
   msg_size = sizeof (struct MSH_MSG_CmdIO) + size;
+  msg = GNUNET_malloc (msg_size);
   msg->header.size = htons (msg_size);
   msg->header.type = htons (MSH_MTYPE_CMD_STREAM_STDIN);
   (void) memcpy (msg->data, recv_buf, size);

Modified: msh/src/mshd-server.c
===================================================================
--- msh/src/mshd-server.c       2013-08-13 17:49:45 UTC (rev 28581)
+++ msh/src/mshd-server.c       2013-08-13 19:09:35 UTC (rev 28582)
@@ -94,24 +94,25 @@
   struct GNUNET_OS_Process *proc;
 
   /**
-   * Input pipe handle for the process
+   * file handle for processes input
    */
-  struct GNUNET_DISK_PipeHandle *pin;
+  struct GNUNET_DISK_FileHandle *fin;
 
   /**
-   * Input pipe handle for the process
+   * file handle for processes output
    */
-  struct GNUNET_DISK_PipeHandle *pout;
-
+  struct GNUNET_DISK_FileHandle *fout;
+  
   /**
-   * file handle for processes input
+   * input buffer.  Data from this buffer is written to proc's STDIN when it is
+   * available for writing.
    */
-  struct GNUNET_DISK_FileHandle *fin;
+  void *buf;
 
   /**
-   * file handle for processes output
+   * The size of the input buffer
    */
-  struct GNUNET_DISK_FileHandle *fout;
+  size_t bufsize;
 
   /**
    * salt hash used for authentication
@@ -129,6 +130,11 @@
   GNUNET_SCHEDULER_TaskIdentifier fout_task;
 
   /**
+   * task to write data received from the client to proc's STDIN
+   */
+  GNUNET_SCHEDULER_TaskIdentifier fin_task;
+
+  /**
    * the file descriptor associated with the client connection
    */
   int conn_fd;
@@ -196,10 +202,14 @@
       GNUNET_free (ctx->args[cnt]);
     GNUNET_free (ctx->args);
   }
+  GNUNET_DISK_file_close (ctx->fin);
+  GNUNET_DISK_file_close (ctx->fout);
   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 (NULL != ctx->buf)
+    GNUNET_free (ctx->buf);
   GNUNET_free (ctx);
 }
 
@@ -681,20 +691,31 @@
 static int
 exec_proc (struct ExecCtx *ctx)
 {
-  ctx->pin = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
-  ctx->pout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
-  GNUNET_assert ((NULL != ctx->pin && (NULL != ctx->pout)));
+  struct GNUNET_DISK_PipeHandle *pin;
+  struct GNUNET_DISK_PipeHandle *pout;
+  
+  sleep (10);
+  pin = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
+  pout = GNUNET_DISK_pipe (GNUNET_NO, GNUNET_NO, 0, 0);
+  GNUNET_assert ((NULL != pin && (NULL != pout)));
   ctx->proc = GNUNET_OS_start_process_vap (GNUNET_NO,
                                            GNUNET_OS_INHERIT_STD_NONE,
-                                           ctx->pin,
-                                           ctx->pout,
+                                           pin,
+                                           pout,
                                            ctx->args[0],
                                            ctx->args);
   if (NULL == ctx->proc)
     return GNUNET_SYSERR;
-  ctx->fin = GNUNET_DISK_pipe_detach_end (ctx->pin, 
GNUNET_DISK_PIPE_END_WRITE);
-  ctx->fout = GNUNET_DISK_pipe_detach_end (ctx->pout, 
GNUNET_DISK_PIPE_END_READ);
+  ctx->fin = GNUNET_DISK_pipe_detach_end (pin, GNUNET_DISK_PIPE_END_WRITE);
+  GNUNET_assert (GNUNET_OK == 
+                 GNUNET_DISK_pipe_close_end (pin, 
+                                             GNUNET_DISK_PIPE_END_READ));
+  ctx->fout = GNUNET_DISK_pipe_detach_end (pout, GNUNET_DISK_PIPE_END_READ);
+  GNUNET_assert (GNUNET_OK == 
+                 GNUNET_DISK_pipe_close_end (pout, 
GNUNET_DISK_PIPE_END_WRITE));
   GNUNET_assert ((NULL != ctx->fin && (NULL != ctx->fout)));
+  GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pin));
+  GNUNET_assert (GNUNET_OK == GNUNET_DISK_pipe_close (pout));
   ctx->fout_task = 
       GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                       ctx->fout, read_fout, ctx);
@@ -760,6 +781,58 @@
 
 
 /**
+ * Task to write data from input buffer to proc's STDIN
+ *
+ * @param cls the client context
+ * @return tc scheduler task context
+ */
+static void
+write_fin (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct ClientCtx *ctx = cls;
+  struct ExecCtx *exec_ctx = ctx->exec_ctx;
+  ssize_t wrote;
+  
+  exec_ctx->fin_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 == (tc->reason & GNUNET_SCHEDULER_REASON_WRITE_READY))
+  {
+    GNUNET_free (exec_ctx->buf);
+    exec_ctx->buf = NULL;
+    exec_ctx->bufsize = 0;
+    GNUNET_SERVER_receive_done (ctx->client, GNUNET_SYSERR);
+    destroy_client_ctx (ctx);
+    return;
+  }
+  wrote = GNUNET_DISK_file_write (exec_ctx->fin,
+                                  exec_ctx->buf, exec_ctx->bufsize);
+  if (GNUNET_SYSERR == wrote)
+  {
+    LOG_ERROR ("Error writing to proc's STDIN\n");
+    GNUNET_SERVER_receive_done (ctx->client, GNUNET_SYSERR);
+    destroy_client_ctx (ctx);
+    return;
+  }
+  if (wrote == exec_ctx->bufsize)
+  {
+    GNUNET_free (exec_ctx->buf);
+    exec_ctx->buf = NULL;
+    exec_ctx->bufsize = 0;
+    GNUNET_SERVER_receive_done (ctx->client, GNUNET_OK);
+    return;
+  }
+  GNUNET_assert (wrote < exec_ctx->bufsize);
+  exec_ctx->bufsize -= wrote;
+  exec_ctx->buf = memmove (exec_ctx->buf, exec_ctx->buf + wrote,
+                           exec_ctx->bufsize);
+  exec_ctx->buf = GNUNET_realloc (exec_ctx->buf, exec_ctx->bufsize);
+  exec_ctx->fin_task = 
+      GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                       exec_ctx->fin,
+                                       &write_fin, ctx);
+}
+
+
+/**
  * Handler for messages with command's input stream data.  The date will be
  * written to the command's standard input stream.
  *
@@ -775,6 +848,7 @@
   const struct MSH_MSG_CmdIO *msg;
   struct ClientCtx *ctx;
   struct ExecCtx *exec_ctx;
+  ssize_t wrote;
   uint16_t size;
  
   LOG_DEBUG ("Received CMD_IO_STDIN message\n");
@@ -785,9 +859,32 @@
   exec_ctx = ctx->exec_ctx;
   GNUNET_assert (NULL != exec_ctx);
   size -= sizeof (struct MSH_MSG_CmdIO);
-  GNUNET_break (size == GNUNET_DISK_file_write (exec_ctx->fin, msg->data,
-                                                size));
-  GNUNET_SERVER_receive_done (client, GNUNET_OK);
+  wrote = GNUNET_DISK_file_write (exec_ctx->fin, msg->data, size);
+  if (GNUNET_SYSERR == wrote)
+  {
+    LOG_ERROR ("Error writing to proc's STDIN\n");
+    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
+    destroy_client_ctx (ctx);
+    return;
+  }
+  LOG_DEBUG ("Wrote %zd to proc's STDIN\n", wrote);
+  if (wrote == size)
+  {
+    GNUNET_SERVER_receive_done (client, GNUNET_OK);
+    return;
+  }
+  GNUNET_assert (wrote < size);
+  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == exec_ctx->fin_task);
+  GNUNET_assert (NULL == exec_ctx->buf);
+  GNUNET_assert (0 == exec_ctx->bufsize);
+  exec_ctx->bufsize = size - wrote;
+  exec_ctx->buf = GNUNET_malloc (exec_ctx->bufsize);
+  (void) memcpy (exec_ctx->buf, msg->data + wrote, exec_ctx->bufsize);
+  exec_ctx->fin_task = 
+      GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                       exec_ctx->fin,
+                                       &write_fin, ctx);
+  GNUNET_SERVER_disable_receive_done_warning (client);
 }
 
 

Added: msh/src/prop.c
===================================================================
--- msh/src/prop.c                              (rev 0)
+++ msh/src/prop.c      2013-08-13 19:09:35 UTC (rev 28582)
@@ -0,0 +1,17 @@
+#include "common.h"
+#include <gnunet/gnunet_util_lib.h>
+
+int main ()
+{
+  char buf[256];
+  
+  //GNUNET_log_setup ("msh-prop", NULL, NULL);
+  if (NULL == fgets (buf, sizeof (buf) -1, stdin))
+  {
+    printf ("Input stream closed\n");
+    return 0;
+  }
+  buf[255] = '\0';
+  printf ("%s", buf);
+  return 0;
+}

Added: msh/src/run.sh
===================================================================
--- msh/src/run.sh                              (rev 0)
+++ msh/src/run.sh      2013-08-13 19:09:35 UTC (rev 28582)
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+echo $MSHD_SOCK
+xterm
+


Property changes on: msh/src/run.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property



reply via email to

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