OSSP CVS Repository

ossp - Difference in ossp-pkg/l2/l2_ch_pipe.c versions 1.12 and 1.13
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/l2/l2_ch_pipe.c 1.12 -> 1.13

--- l2_ch_pipe.c 2001/09/19 16:39:44     1.12
+++ l2_ch_pipe.c 2001/09/20 16:26:56     1.13
@@ -38,22 +38,23 @@
 #define L2_PIPE_MAXARGS    256 /* shell  command execution */
 
 static l2_result_t hook_open(l2_context_t *, l2_channel_t *); /* prototypes */
+static l2_result_t hook_close(l2_context_t *, l2_channel_t *);
 
 
 /* declare private channel configuration */
 typedef struct {
-    int piFd[2];                 /* pipe file descriptor               */
-    int iMode;                   /* execution mode direct or shell     */
-    pid_t Pid;                   /* pid set during fork in hook_open() */
-    char *szCmdpath;             /* path to command and arguments      */
+    int piFd[2];           /* pipe file descriptor                   */
+    int iChild;            /* exception status of child pipe process */
+    int iMode;             /* execution mode direct or shell         */
+    pid_t Pid;             /* pid set during fork in hook_open()     */
+    char *szCmdpath;       /* path to command and arguments          */
 } l2_ch_pipe_t;
 
 static void catchsignal(int sig, ...)
 {
-    int                  iStatus = 0;
-    va_list              ap      = NULL;
-    static l2_context_t *ctx     = NULL;
-    static l2_channel_t *chan    = NULL;
+    va_list              ap     = NULL;
+    static l2_context_t *ctx    = NULL;
+    static l2_channel_t *chan   = NULL;
 
     if (sig == 0) {
         va_start(ap, sig);
@@ -63,15 +64,24 @@
     }
     else if (sig == SIGCHLD) {
 /*        TRACE("SIGCHLD caught\n");*/
-        waitpid(((l2_ch_pipe_t *)ctx->vp)->Pid, &iStatus, 0);
-        close(((l2_ch_pipe_t *)ctx->vp)->piFd[1]);
-        ((l2_ch_pipe_t *)ctx->vp)->piFd[1] = -1;
-        if (hook_open(ctx, chan) != L2_OK) { /* TODO: Fix infinit loop! */
+        waitpid(((l2_ch_pipe_t *)ctx->vp)->Pid, &((l2_ch_pipe_t *)ctx->vp)->iChild, WUNTRACED);
+        if (WIFEXITED(((l2_ch_pipe_t *)ctx->vp)->iChild)) {
             close(((l2_ch_pipe_t *)ctx->vp)->piFd[1]);
             ((l2_ch_pipe_t *)ctx->vp)->piFd[1] = -1;
+            ((l2_ch_pipe_t *)ctx->vp)->Pid = -1;
+            /* check if process called exit() abnormally, then if so restarts */
+            if (WEXITSTATUS(((l2_ch_pipe_t *)ctx->vp)->iChild)) {
+                fprintf(stderr, "exit status is %d\n", WEXITSTATUS(((l2_ch_pipe_t *)ctx->vp)->iChild));
+                if (hook_open(ctx, chan) != L2_OK) { /* TODO: Fix infinit loop! */
+                    close(((l2_ch_pipe_t *)ctx->vp)->piFd[1]);
+                    ((l2_ch_pipe_t *)ctx->vp)->piFd[1] = -1;
+                }
+            }
+        }
+        else if (WIFSTOPPED(((l2_ch_pipe_t *)ctx->vp)->iChild)) {
         }
     }
-    else if (sig == SIGPIPE) {
+    else if (sig == SIGPIPE) { /* thrown when we write to child's closed pipe */
 /*        TRACE("SIGPIPE caught\n");*/
         close(((l2_ch_pipe_t *)ctx->vp)->piFd[1]);
         ((l2_ch_pipe_t *)ctx->vp)->piFd[1] = -1;
@@ -88,9 +98,11 @@
         return L2_ERR_ARG;
 
     /* initialize configuration with reasonable defaults */
-    cfg->piFd[0]    = -1; 
-    cfg->piFd[1]    = -1; 
-    cfg->iMode      = -1; 
+    cfg->piFd[0]   = -1; 
+    cfg->piFd[1]   = -1; 
+    cfg->iChild    =  0; 
+    cfg->iMode     = -1; 
+    cfg->Pid       = -1; 
     cfg->szCmdpath = NULL;
 
     /* link private channel configuration into channel context */
@@ -225,6 +237,13 @@
     if (cfg->piFd[1] == -1)
         return L2_ERR_IO;
 
+    if (WIFSTOPPED(cfg->iChild)) {
+        if (kill(cfg->Pid, SIGCONT)) {
+            hook_close(ctx, ch);
+            cfg->iChild = 0;
+            return L2_ERR_SYS;
+        }
+    }
     /* write message to channel pipe */
     else if (write(cfg->piFd[1], buf, buf_size) == -1)
         return L2_ERR_SYS;
@@ -240,6 +259,9 @@
     /* close channel pipe for parent process created in hook_open() */
     close(cfg->piFd[1]);
     cfg->piFd[1] = -1;
+    if (kill(cfg->Pid, SIGTERM))
+        return L2_ERR_SYS;
+    cfg->Pid = -1;
 
     return L2_OK;
 }

CVSTrac 2.0.1