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

Diff for /src/usr.bin/tmux/cmd-if-shell.c between version 1.4 and 1.5

version 1.4, 2009/09/21 15:32:06 version 1.5, 2009/10/11 09:10:57
Line 2 
Line 2 
   
 /*  /*
  * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>   * Copyright (c) 2009 Tiago Cunha <me@tiagocunha.org>
    * Copyright (c) 2009 Nicholas Marriott <nicm@openbsd.org>
  *   *
  * Permission to use, copy, modify, and distribute this software for any   * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above   * purpose with or without fee is hereby granted, provided that the above
Line 17 
Line 18 
  */   */
   
 #include <sys/types.h>  #include <sys/types.h>
   #include <sys/wait.h>
   
 #include <errno.h>  
 #include <stdlib.h>  
 #include <string.h>  #include <string.h>
   
 #include "tmux.h"  #include "tmux.h"
Line 28 
Line 28 
  * Executes a tmux command if a shell command returns true.   * Executes a tmux command if a shell command returns true.
  */   */
   
 int     cmd_if_shell_parse(struct cmd *, int, char **, char **);  
 int     cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);  int     cmd_if_shell_exec(struct cmd *, struct cmd_ctx *);
 void    cmd_if_shell_free(struct cmd *);  
 void    cmd_if_shell_init(struct cmd *, int);  
 size_t  cmd_if_shell_print(struct cmd *, char *, size_t);  
   
 struct cmd_if_shell_data {  void    cmd_if_shell_callback(struct job *);
         char *cmd;  void    cmd_if_shell_free(void *);
         char *sh_cmd;  
 };  
   
 const struct cmd_entry cmd_if_shell_entry = {  const struct cmd_entry cmd_if_shell_entry = {
         "if-shell", "if",          "if-shell", "if",
         "shell-command command",          "shell-command command",
         0, 0,          CMD_ARG2, 0,
         cmd_if_shell_init,          cmd_target_init,
         cmd_if_shell_parse,          cmd_target_parse,
         cmd_if_shell_exec,          cmd_if_shell_exec,
         cmd_if_shell_free,          cmd_target_free,
         cmd_if_shell_print          cmd_target_print
 };  };
   
 void  struct cmd_if_shell_data {
 cmd_if_shell_init(struct cmd *self, unused int arg)          char            *cmd;
 {          struct cmd_ctx   ctx;
         struct cmd_if_shell_data        *data;  };
   
         self->data = data = xmalloc(sizeof *data);  
         data->cmd = NULL;  
         data->sh_cmd = NULL;  
 }  
   
 int  int
 cmd_if_shell_parse(struct cmd *self, int argc, char **argv, char **cause)  cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)
 {  {
         struct cmd_if_shell_data        *data;          struct cmd_target_data          *data = self->data;
         int                              opt;          struct cmd_if_shell_data        *cdata;
           struct job                      *job;
   
         self->entry->init(self, KEYC_NONE);          cdata = xmalloc(sizeof *cdata);
         data = self->data;          cdata->cmd = xstrdup(data->arg2);
           memcpy(&cdata->ctx, ctx, sizeof cdata->ctx);
   
         while ((opt = getopt(argc, argv, "")) != -1) {          if (ctx->cmdclient != NULL)
                 switch (opt) {                  ctx->cmdclient->references++;
                 default:          if (ctx->curclient != NULL)
                         goto usage;                  ctx->curclient->references++;
                 }  
         }  
         argc -= optind;  
         argv += optind;  
         if (argc != 2)  
                 goto usage;  
   
         data->sh_cmd = xstrdup(argv[0]);          job = job_add(NULL, NULL,
         data->cmd = xstrdup(argv[1]);              data->arg, cmd_if_shell_callback, cmd_if_shell_free, cdata);
         return (0);          job_run(job);
   
 usage:          return (1);     /* don't let client exit */
         xasprintf(cause, "usage: %s %s", self->entry->name, self->entry->usage);  
   
         self->entry->free(self);  
         return (-1);  
 }  }
   
 int  void
 cmd_if_shell_exec(struct cmd *self, struct cmd_ctx *ctx)  cmd_if_shell_callback(struct job *job)
 {  {
         struct cmd_if_shell_data        *data = self->data;          struct cmd_if_shell_data        *cdata = job->data;
           struct cmd_ctx                  *ctx = &cdata->ctx;
         struct cmd_list                 *cmdlist;          struct cmd_list                 *cmdlist;
         char                            *cause;          char                            *cause;
         int                              ret;  
   
         if ((ret = system(data->sh_cmd)) < 0) {          if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) {
                 ctx->error(ctx, "system error: %s", strerror(errno));                  job_free(job);  /* calls cmd_if_shell_free */
                 return (-1);                  return;
         } else if (ret != 0)          }
                 return (0);  
   
         if (cmd_string_parse(data->cmd, &cmdlist, &cause) != 0) {          if (cmd_string_parse(cdata->cmd, &cmdlist, &cause) != 0) {
                 if (cause != NULL) {                  if (cause != NULL) {
                         ctx->error(ctx, "%s", cause);                          ctx->error(ctx, "%s", cause);
                         xfree(cause);                          xfree(cause);
                 }                  }
                 return (-1);                  return;
         }          }
   
         if (cmd_list_exec(cmdlist, ctx) < 0) {          if (cmd_list_exec(cmdlist, ctx) < 0) {
                 cmd_list_free(cmdlist);                  cmd_list_free(cmdlist);
                 return (-1);                  return;
         }          }
   
         cmd_list_free(cmdlist);          cmd_list_free(cmdlist);
         return (0);  
 }  }
   
 void  void
 cmd_if_shell_free(struct cmd *self)  cmd_if_shell_free(void *data)
 {  {
         struct cmd_if_shell_data        *data = self->data;          struct cmd_if_shell_data        *cdata = data;
           struct cmd_ctx                  *ctx = &cdata->ctx;
   
         if (data->cmd != NULL)          if (ctx->cmdclient != NULL) {
                 xfree(data->cmd);                  ctx->cmdclient->references--;
         if (data->sh_cmd != NULL)                  server_write_client(ctx->cmdclient, MSG_EXIT, NULL, 0);
                 xfree(data->sh_cmd);          }
         xfree(data);          if (ctx->curclient != NULL)
 }                  ctx->curclient->references--;
   
 size_t          xfree(cdata->cmd);
 cmd_if_shell_print(struct cmd *self, char *buf, size_t len)          xfree(cdata);
 {  
         struct cmd_if_shell_data        *data = self->data;  
         size_t                          off = 0;  
   
         off += xsnprintf(buf, len, "%s", self->entry->name);  
         if (data == NULL)  
                 return (off);  
         if (off < len && data->sh_cmd != NULL)  
                 off += cmd_prarg(buf + off, len - off, " ", data->sh_cmd);  
         if (off < len && data->cmd != NULL)  
                 off += cmd_prarg(buf + off, len - off, " ", data->cmd);  
         return (off);  
 }  }

Legend:
Removed from v.1.4  
changed lines
  Added in v.1.5