[BACK]Return to cmd-run-shell.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Diff for /src/usr.bin/tmux/cmd-run-shell.c between version 1.1 and 1.2

version 1.1, 2009/09/20 19:15:01 version 1.2, 2009/10/11 08:58:05
Line 29 
Line 29 
   
 int     cmd_run_shell_exec(struct cmd *, struct cmd_ctx *);  int     cmd_run_shell_exec(struct cmd *, struct cmd_ctx *);
   
   void    cmd_run_shell_callback(struct job *);
   void    cmd_run_shell_free(void *);
   
 const struct cmd_entry cmd_run_shell_entry = {  const struct cmd_entry cmd_run_shell_entry = {
         "run-shell", "run",          "run-shell", "run",
         "command",          "command",
Line 40 
Line 43 
         cmd_target_print          cmd_target_print
 };  };
   
   struct cmd_run_shell_data {
           char            *cmd;
           struct cmd_ctx   ctx;
   };
   
 int  int
 cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)  cmd_run_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
 {  {
         struct cmd_target_data  *data = self->data;          struct cmd_target_data          *data = self->data;
         FILE                    *fp;          struct cmd_run_shell_data       *cdata;
         char                    *buf, *lbuf, *msg;          struct job                      *job;
         size_t                   len;  
         int                      has_output, ret, status;  
   
         if ((fp = popen(data->arg, "r")) == NULL) {          cdata = xmalloc(sizeof *cdata);
                 ctx->error(ctx, "popen error");          cdata->cmd = xstrdup(data->arg);
                 return (-1);          memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
         }  
   
         has_output = 0;          if (ctx->cmdclient != NULL)
         lbuf = NULL;                  ctx->cmdclient->references++;
         while ((buf = fgetln(fp, &len)) != NULL) {          if (ctx->curclient != NULL)
                 if (buf[len - 1] == '\n')                  ctx->curclient->references++;
                         buf[len - 1] = '\0';  
                 else {          job = job_add(NULL, NULL,
                         lbuf = xmalloc(len + 1);              data->arg, cmd_run_shell_callback, cmd_run_shell_free, cdata);
                         memcpy(lbuf, buf, len);          job_run(job);
                         lbuf[len] = '\0';  
                         buf = lbuf;          return (1);     /* don't let client exit */
   }
   
   void
   cmd_run_shell_callback(struct job *job)
   {
           struct cmd_run_shell_data       *cdata = job->data;
           struct cmd_ctx                  *ctx = &cdata->ctx;
           char                            *cmd, *msg, *line, *buf;
           size_t                           off, len, llen;
           int                              retcode;
   
           buf = BUFFER_OUT(job->out);
           len = BUFFER_USED(job->out);
   
           cmd = cdata->cmd;
   
           if (len != 0) {
                   line = buf;
                   for (off = 0; off < len; off++) {
                           if (buf[off] == '\n') {
                                   llen = buf + off - line;
                                   if (llen > INT_MAX)
                                           break;
                                   ctx->print(ctx, "%.*s", (int) llen, line);
                                   line = buf + off + 1;
                           }
                 }                  }
                 ctx->print(ctx, "%s", buf);                  llen = buf + len - line;
                 has_output = 1;                  if (llen > 0 && llen < INT_MAX)
                           ctx->print(ctx, "%.*s", (int) llen, line);
         }          }
         if (lbuf != NULL)  
                 xfree(lbuf);  
   
         msg = NULL;          msg = NULL;
         status = pclose(fp);          if (WIFEXITED(job->status)) {
                   if ((retcode = WEXITSTATUS(job->status)) != 0)
         if (WIFEXITED(status)) {                          xasprintf(&msg, "'%s' returned %d", cmd, retcode);
                 if ((ret = WEXITSTATUS(status)) == 0)          } else if (WIFSIGNALED(job->status)) {
                         return (0);                  retcode = WTERMSIG(job->status);
                 xasprintf(&msg, "'%s' returned %d", data->arg, ret);                  xasprintf(&msg, "'%s' terminated by signal %d", cmd, retcode);
         } else if (WIFSIGNALED(status)) {  
                 xasprintf(  
                     &msg, "'%s' terminated by signal %d", data->arg,  
                     WTERMSIG(status));  
         }          }
   
         if (msg != NULL) {          if (msg != NULL) {
                 if (has_output)                  if (len != 0)
                         ctx->print(ctx, "%s", msg);                          ctx->print(ctx, "%s", msg);
                 else                  else
                         ctx->info(ctx, "%s", msg);                          ctx->info(ctx, "%s", msg);
                 xfree(msg);                  xfree(msg);
         }          }
   
         return (0);          job_free(job);  /* calls cmd_run_shell_free */
   }
   
   void
   cmd_run_shell_free(void *data)
   {
           struct cmd_run_shell_data       *cdata = data;
           struct cmd_ctx                  *ctx = &cdata->ctx;
   
           return;
           if (ctx->cmdclient != NULL) {
                   ctx->cmdclient->references--;
                   server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
           }
           if (ctx->curclient != NULL)
                   ctx->curclient->references--;
   
           xfree(cdata->cmd);
           xfree(cdata);
 }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2