This looks good, it needs to go in the man page, but I'm not sure
where... any ideas?


On Fri, Apr 25, 2014 at 01:37:50PM -0500, J Raynor wrote:
> Sorry, I made an off-by-one error in cmd_stringify_argv.  I've
> attached a new patch.
> 
> 
> On Thu, Apr 24, 2014 at 5:42 PM, J Raynor <jxray...@gmail.com> wrote:
> >> Only bit I don't like now is passing return from xstrdup() to xrealloc()
> >> in cmd_stringify_argv, better just to start len = 1 and x = 0.
> >
> > I've attached a new patch.  The only difference is the implementation
> > of cmd_stringify_argv, which I've altered to remove what you disliked.

> diff --git a/cmd-new-session.c b/cmd-new-session.c
> index 3071bd6..c907a0c 100644
> --- a/cmd-new-session.c
> +++ b/cmd-new-session.c
> @@ -35,7 +35,7 @@ enum cmd_retval      cmd_new_session_exec(struct cmd *, 
> struct cmd_q *);
>  
>  const struct cmd_entry cmd_new_session_entry = {
>       "new-session", "new",
> -     "Ac:dDF:n:Ps:t:x:y:", 0, 1,
> +     "Ac:dDF:n:Ps:t:x:y:", 0, -1,
>       "[-AdDP] [-c start-directory] [-F format] [-n window-name] "
>       "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] [-y height] "
>       "[command]",
> @@ -55,8 +55,9 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
>       struct termios           tio, *tiop;
>       const char              *newname, *target, *update, *errstr, *template;
>       const char              *path;
> -     char                    *cmd, *cause, *cp;
> +     char                   **argv, *cmd, *cause, *cp;
>       int                      detached, already_attached, idx, cwd, fd = -1;
> +     int                      argc;
>       u_int                    sx, sy;
>       struct format_tree      *ft;
>       struct environ_entry    *envent;
> @@ -183,12 +184,22 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>               sy = 1;
>  
>       /* Figure out the command for the new window. */
> -     if (target != NULL)
> -             cmd = NULL;
> -     else if (args->argc != 0)
> -             cmd = args->argv[0];
> -     else
> -             cmd = options_get_string(&global_s_options, "default-command");
> +     argc = -1;
> +     argv = NULL;
> +     if (target == NULL) {
> +             if (args->argc != 0) {
> +                     argc = args->argc;
> +                     argv = args->argv;
> +             } else {
> +                     argc = 0;
> +                     cmd = options_get_string(&global_s_options,
> +                             "default-command");
> +                     if (cmd != NULL && *cmd != '\0') {
> +                             argc = 1;
> +                             argv = &cmd;
> +                     }
> +             }
> +     }
>  
>       path = NULL;
>       if (c != NULL && c->session == NULL)
> @@ -206,8 +217,8 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
>  
>       /* Create the new session. */
>       idx = -1 - options_get_number(&global_s_options, "base-index");
> -     s = session_create(newname, cmd, path, cwd, &env, tiop, idx, sx, sy,
> -         &cause);
> +     s = session_create(newname, argc, argv, path, cwd, &env, tiop, idx, sx,
> +         sy, &cause);
>       if (s == NULL) {
>               cmdq_error(cmdq, "create session failed: %s", cause);
>               free(cause);
> @@ -216,7 +227,7 @@ cmd_new_session_exec(struct cmd *self, struct cmd_q *cmdq)
>       environ_free(&env);
>  
>       /* Set the initial window name if one given. */
> -     if (cmd != NULL && args_has(args, 'n')) {
> +     if (argc >= 0 && args_has(args, 'n')) {
>               w = s->curw->window;
>               window_set_name(w, args_get(args, 'n'));
>               options_set_number(&w->options, "automatic-rename", 0);
> diff --git a/cmd-new-window.c b/cmd-new-window.c
> index 6e9fea5..a6b6b63 100644
> --- a/cmd-new-window.c
> +++ b/cmd-new-window.c
> @@ -34,7 +34,7 @@ enum cmd_retval     cmd_new_window_exec(struct cmd *, 
> struct cmd_q *);
>  
>  const struct cmd_entry cmd_new_window_entry = {
>       "new-window", "neww",
> -     "ac:dF:kn:Pt:", 0, 1,
> +     "ac:dF:kn:Pt:", 0, -1,
>       "[-adkP] [-c start-directory] [-F format] [-n window-name] "
>       CMD_TARGET_WINDOW_USAGE " [command]",
>       0,
> @@ -50,8 +50,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
>       struct winlink          *wl;
>       struct client           *c;
>       const char              *cmd, *path, *template;
> -     char                    *cause, *cp;
> -     int                      idx, last, detached, cwd, fd = -1;
> +     char                   **argv, *cause, *cp;
> +     int                      argc, idx, last, detached, cwd, fd = -1;
>       struct format_tree      *ft;
>       struct environ_entry    *envent;
>  
> @@ -84,10 +84,18 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
>       }
>       detached = args_has(args, 'd');
>  
> -     if (args->argc == 0)
> +     if (args->argc == 0) {
> +             argc = 0;
> +             argv = NULL;
>               cmd = options_get_string(&s->options, "default-command");
> -     else
> -             cmd = args->argv[0];
> +             if (cmd != NULL && *cmd != '\0') {
> +                     argc = 1;
> +                     argv = &cmd;
> +             }
> +     } else {
> +             argc = args->argc;
> +             argv = args->argv;
> +     }
>  
>       path = NULL;
>       if (cmdq->client != NULL && cmdq->client->session == NULL)
> @@ -145,7 +153,8 @@ cmd_new_window_exec(struct cmd *self, struct cmd_q *cmdq)
>  
>       if (idx == -1)
>               idx = -1 - options_get_number(&s->options, "base-index");
> -     wl = session_new(s, args_get(args, 'n'), cmd, path, cwd, idx, &cause);
> +     wl = session_new(s, args_get(args, 'n'), argc, argv, path, cwd, idx,
> +             &cause);
>       if (wl == NULL) {
>               cmdq_error(cmdq, "create window failed: %s", cause);
>               free(cause);
> diff --git a/cmd-respawn-pane.c b/cmd-respawn-pane.c
> index 9ac5b0b..f951685 100644
> --- a/cmd-respawn-pane.c
> +++ b/cmd-respawn-pane.c
> @@ -32,7 +32,7 @@ enum cmd_retval      cmd_respawn_pane_exec(struct cmd *, 
> struct cmd_q *);
>  
>  const struct cmd_entry cmd_respawn_pane_entry = {
>       "respawn-pane", "respawnp",
> -     "kt:", 0, 1,
> +     "kt:", 0, -1,
>       "[-k] " CMD_TARGET_PANE_USAGE " [command]",
>       0,
>       NULL,
> @@ -48,7 +48,7 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
>       struct window_pane      *wp;
>       struct session          *s;
>       struct environ           env;
> -     const char              *cmd, *path;
> +     const char              *path;
>       char                    *cause;
>       u_int                    idx;
>       struct environ_entry    *envent;
> @@ -74,11 +74,6 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
>       screen_reinit(&wp->base);
>       input_init(wp);
>  
> -     if (args->argc != 0)
> -             cmd = args->argv[0];
> -     else
> -             cmd = NULL;
> -
>       path = NULL;
>       if (cmdq->client != NULL && cmdq->client->session == NULL)
>               envent = environ_find(&cmdq->client->environ, "PATH");
> @@ -87,8 +82,8 @@ cmd_respawn_pane_exec(struct cmd *self, struct cmd_q *cmdq)
>       if (envent != NULL)
>               path = envent->value;
>  
> -     if (window_pane_spawn(wp, cmd, path, NULL, -1, &env, s->tio,
> -         &cause) != 0) {
> +     if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
> +         s->tio, &cause) != 0) {
>               cmdq_error(cmdq, "respawn pane failed: %s", cause);
>               free(cause);
>               environ_free(&env);
> diff --git a/cmd-respawn-window.c b/cmd-respawn-window.c
> index d891eff..307560b 100644
> --- a/cmd-respawn-window.c
> +++ b/cmd-respawn-window.c
> @@ -31,7 +31,7 @@ enum cmd_retval      cmd_respawn_window_exec(struct cmd *, 
> struct cmd_q *);
>  
>  const struct cmd_entry cmd_respawn_window_entry = {
>       "respawn-window", "respawnw",
> -     "kt:", 0, 1,
> +     "kt:", 0, -1,
>       "[-k] " CMD_TARGET_WINDOW_USAGE " [command]",
>       0,
>       NULL,
> @@ -47,7 +47,7 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>       struct window_pane      *wp;
>       struct session          *s;
>       struct environ           env;
> -     const char              *cmd, *path;
> +     const char              *path;
>       char                    *cause;
>       struct environ_entry    *envent;
>  
> @@ -76,10 +76,6 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>       window_destroy_panes(w);
>       TAILQ_INSERT_HEAD(&w->panes, wp, entry);
>       window_pane_resize(wp, w->sx, w->sy);
> -     if (args->argc != 0)
> -             cmd = args->argv[0];
> -     else
> -             cmd = NULL;
>  
>       path = NULL;
>       if (cmdq->client != NULL && cmdq->client->session == NULL)
> @@ -89,8 +85,8 @@ cmd_respawn_window_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>       if (envent != NULL)
>               path = envent->value;
>  
> -     if (window_pane_spawn(wp, cmd, path, NULL, -1, &env, s->tio,
> -         &cause) != 0) {
> +     if (window_pane_spawn(wp, args->argc, args->argv, path, NULL, -1, &env,
> +         s->tio, &cause) != 0) {
>               cmdq_error(cmdq, "respawn window failed: %s", cause);
>               free(cause);
>               environ_free(&env);
> diff --git a/cmd-split-window.c b/cmd-split-window.c
> index 9c4734b..9263e69 100644
> --- a/cmd-split-window.c
> +++ b/cmd-split-window.c
> @@ -35,7 +35,7 @@ enum cmd_retval      cmd_split_window_exec(struct cmd *, 
> struct cmd_q *);
>  
>  const struct cmd_entry cmd_split_window_entry = {
>       "split-window", "splitw",
> -     "c:dF:l:hp:Pt:v", 0, 1,
> +     "c:dF:l:hp:Pt:v", 0, -1,
>       "[-dhvP] [-c start-directory] [-F format] [-p percentage|-l size] "
>       CMD_TARGET_PANE_USAGE " [command]",
>       0,
> @@ -61,9 +61,9 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q *cmdq)
>       struct window_pane      *wp, *new_wp = NULL;
>       struct environ           env;
>       const char              *cmd, *path, *shell, *template;
> -     char                    *cause, *new_cause, *cp;
> +     char                   **argv, *cause, *new_cause, *cp;
>       u_int                    hlimit;
> -     int                      size, percentage, cwd, fd = -1;
> +     int                      argc, size, percentage, cwd, fd = -1;
>       enum layout_type         type;
>       struct layout_cell      *lc;
>       struct client           *c;
> @@ -80,10 +80,18 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>       environ_copy(&s->environ, &env);
>       server_fill_environ(s, &env);
>  
> -     if (args->argc == 0)
> +     if (args->argc == 0) {
> +             argc = 0;
> +             argv = NULL;
>               cmd = options_get_string(&s->options, "default-command");
> -     else
> -             cmd = args->argv[0];
> +             if (cmd != NULL && *cmd != '\0') {
> +                     argc = 1;
> +                     argv = &cmd;
> +             }
> +     } else {
> +             argc = args->argc;
> +             argv = args->argv;
> +     }
>  
>       if (args_has(args, 'c')) {
>               ft = format_create();
> @@ -158,7 +166,7 @@ cmd_split_window_exec(struct cmd *self, struct cmd_q 
> *cmdq)
>               path = envent->value;
>  
>       if (window_pane_spawn(
> -         new_wp, cmd, path, shell, cwd, &env, s->tio, &cause) != 0)
> +         new_wp, argc, argv, path, shell, cwd, &env, s->tio, &cause) != 0)
>               goto error;
>       layout_assign_pane(lc, new_wp);
>  
> diff --git a/cmd.c b/cmd.c
> index f2d88c0..c10c758 100644
> --- a/cmd.c
> +++ b/cmd.c
> @@ -206,6 +206,34 @@ cmd_free_argv(int argc, char **argv)
>       free(argv);
>  }
>  
> +char *
> +cmd_stringify_argv(int argc, char *const *argv)
> +{
> +     char    *buf;
> +     int      x;
> +     size_t   len;
> +
> +     if (argc == 0)
> +             return (xstrdup(""));
> +
> +     len = 0;
> +     buf = NULL;
> +
> +     for (x = 0; x < argc; x++)
> +     {
> +             len += strlen(argv[x]) + 1;
> +             buf = xrealloc(buf, 1, len);
> +
> +             if (x == 0)
> +                     *buf = '\0';
> +             else
> +                     strlcat(buf, " ", len);
> +
> +             strlcat(buf, argv[x], len);
> +     }
> +     return (buf);
> +}
> +
>  struct cmd *
>  cmd_parse(int argc, char **argv, const char *file, u_int line, char **cause)
>  {
> diff --git a/format.c b/format.c
> index 6f988b9..4a1a171 100644
> --- a/format.c
> +++ b/format.c
> @@ -368,7 +368,7 @@ format_get_command(struct window_pane *wp)
>       cmd = osdep_get_name(wp->fd, wp->tty);
>       if (cmd == NULL || *cmd == '\0') {
>               free(cmd);
> -             cmd = xstrdup(wp->cmd);
> +             cmd = cmd_stringify_argv(wp->argc, wp->argv);
>               if (cmd == NULL || *cmd == '\0') {
>                       free(cmd);
>                       cmd = xstrdup(wp->shell);
> @@ -559,8 +559,11 @@ format_window_pane(struct format_tree *ft, struct 
> window_pane *wp)
>       if (wp->tty != NULL)
>               format_add(ft, "pane_tty", "%s", wp->tty);
>       format_add(ft, "pane_pid", "%ld", (long) wp->pid);
> -     if (wp->cmd != NULL)
> -             format_add(ft, "pane_start_command", "%s", wp->cmd);
> +
> +     cmd = cmd_stringify_argv(wp->argc, wp->argv);
> +     format_add(ft, "pane_start_command", "%s", cmd);
> +     free(cmd);
> +
>       if ((cwd = osdep_get_cwd(wp->fd)) != NULL)
>               format_add(ft, "pane_current_path", "%s", cwd);
>       if ((cmd = format_get_command(wp)) != NULL) {
> diff --git a/names.c b/names.c
> index 7c02961..0ed8836 100644
> --- a/names.c
> +++ b/names.c
> @@ -68,8 +68,15 @@ window_name_callback(unused int fd, unused short events, 
> void *data)
>  char *
>  default_window_name(struct window *w)
>  {
> -     if (w->active->cmd != NULL && *w->active->cmd != '\0')
> -             return (parse_window_name(w->active->cmd));
> +     char    *wpcmd, *s;
> +
> +     wpcmd = cmd_stringify_argv(w->active->argc, w->active->argv);
> +     if (wpcmd != NULL && *wpcmd != '\0') {
> +             s = parse_window_name(wpcmd);
> +             free(wpcmd);
> +             return (s);
> +     }
> +     free(wpcmd);
>       return (parse_window_name(w->active->shell));
>  }
>  
> diff --git a/session.c b/session.c
> index ae6f35c..f8d0a14 100644
> --- a/session.c
> +++ b/session.c
> @@ -84,9 +84,9 @@ session_find_by_id(u_int id)
>  
>  /* Create a new session. */
>  struct session *
> -session_create(const char *name, const char *cmd, const char *path, int cwd,
> -    struct environ *env, struct termios *tio, int idx, u_int sx, u_int sy,
> -    char **cause)
> +session_create(const char *name, int argc, char *const *argv, const char 
> *path,
> +    int cwd, struct environ *env, struct termios *tio, int idx, u_int sx,
> +    u_int sy, char **cause)
>  {
>       struct session  *s;
>  
> @@ -131,8 +131,9 @@ session_create(const char *name, const char *cmd, const 
> char *path, int cwd,
>       }
>       RB_INSERT(sessions, &sessions, s);
>  
> -     if (cmd != NULL) {
> -             if (session_new(s, NULL, cmd, path, cwd, idx, cause) == NULL) {
> +     if (argc >= 0) {
> +             if (session_new(
> +                 s, NULL, argc, argv, path, cwd, idx, cause) == NULL) {
>                       session_destroy(s);
>                       return (NULL);
>               }
> @@ -226,7 +227,7 @@ session_previous_session(struct session *s)
>  
>  /* Create a new window on a session. */
>  struct winlink *
> -session_new(struct session *s, const char *name, const char *cmd,
> +session_new(struct session *s, const char *name, int argc, char *const *argv,
>      const char *path, int cwd, int idx, char **cause)
>  {
>       struct window   *w;
> @@ -250,8 +251,8 @@ session_new(struct session *s, const char *name, const 
> char *cmd,
>               shell = _PATH_BSHELL;
>  
>       hlimit = options_get_number(&s->options, "history-limit");
> -     w = window_create(name, cmd, path, shell, cwd, &env, s->tio, s->sx,
> -         s->sy, hlimit, cause);
> +     w = window_create(name, argc, argv, path, shell, cwd, &env, s->tio,
> +         s->sx, s->sy, hlimit, cause);
>       if (w == NULL) {
>               winlink_remove(&s->windows, wl);
>               environ_free(&env);
> diff --git a/tmux.h b/tmux.h
> index 6f29126..7fcead7 100644
> --- a/tmux.h
> +++ b/tmux.h
> @@ -908,7 +908,8 @@ struct window_pane {
>  #define PANE_RESIZE 0x8
>  #define PANE_FOCUSPUSH 0x10
>  
> -     char            *cmd;
> +     int              argc;
> +     char           **argv;
>       char            *shell;
>       int              cwd;
>  
> @@ -1735,6 +1736,7 @@ int              cmd_pack_argv(int, char **, char *, 
> size_t);
>  int           cmd_unpack_argv(char *, size_t, int, char ***);
>  char        **cmd_copy_argv(int, char *const *);
>  void          cmd_free_argv(int, char **);
> +char         *cmd_stringify_argv(int, char *const *);
>  struct cmd   *cmd_parse(int, char **, const char *, u_int, char **);
>  size_t                cmd_print(struct cmd *, char *, size_t);
>  struct session       *cmd_current_session(struct cmd_q *, int);
> @@ -2126,7 +2128,7 @@ void             winlink_stack_remove(struct 
> winlink_stack *, struct winlink *);
>  int           window_index(struct window *, u_int *);
>  struct window        *window_find_by_id(u_int);
>  struct window        *window_create1(u_int, u_int);
> -struct window        *window_create(const char *, const char *, const char *,
> +struct window        *window_create(const char *, int, char *const *, const 
> char *,
>                    const char *, int, struct environ *, struct termios *,
>                    u_int, u_int, u_int, char **);
>  void          window_destroy(struct window *);
> @@ -2152,7 +2154,7 @@ struct window_pane *window_pane_find_by_id(u_int);
>  struct window_pane *window_pane_create(struct window *, u_int, u_int, u_int);
>  void          window_pane_destroy(struct window_pane *);
>  void          window_pane_timer_start(struct window_pane *);
> -int           window_pane_spawn(struct window_pane *, const char *,
> +int           window_pane_spawn(struct window_pane *, int, char *const *,
>                    const char *, const char *, int, struct environ *,
>                    struct termios *, char **);
>  void          window_pane_resize(struct window_pane *, u_int, u_int);
> @@ -2290,16 +2292,16 @@ RB_PROTOTYPE(sessions, session, entry, session_cmp);
>  int           session_alive(struct session *);
>  struct session       *session_find(const char *);
>  struct session       *session_find_by_id(u_int);
> -struct session       *session_create(const char *, const char *, const char 
> *, int,
> -                  struct environ *, struct termios *, int, u_int, u_int,
> +struct session       *session_create(const char *, int, char *const *, const 
> char *,
> +                  int, struct environ *, struct termios *, int, u_int, u_int,
>                    char **);
>  void          session_destroy(struct session *);
>  int           session_check_name(const char *);
>  void          session_update_activity(struct session *);
>  struct session       *session_next_session(struct session *);
>  struct session       *session_previous_session(struct session *);
> -struct winlink       *session_new(struct session *, const char *, const char 
> *,
> -                  const char *, int, int, char **);
> +struct winlink       *session_new(struct session *, const char *, int,
> +                  char *const *, const char *, int, int, char **);
>  struct winlink       *session_attach(
>                    struct session *, struct window *, int, char **);
>  int           session_detach(struct session *, struct winlink *);
> diff --git a/window.c b/window.c
> index ee851bd..196832f 100644
> --- a/window.c
> +++ b/window.c
> @@ -307,7 +307,7 @@ window_create1(u_int sx, u_int sy)
>  }
>  
>  struct window *
> -window_create(const char *name, const char *cmd, const char *path,
> +window_create(const char *name, int argc, char *const *argv, const char 
> *path,
>      const char *shell, int cwd, struct environ *env, struct termios *tio,
>      u_int sx, u_int sy, u_int hlimit, char **cause)
>  {
> @@ -318,7 +318,7 @@ window_create(const char *name, const char *cmd, const 
> char *path,
>       wp = window_add_pane(w, hlimit);
>       layout_init(w, wp);
>  
> -     if (window_pane_spawn(wp, cmd, path, shell, cwd, env, tio,
> +     if (window_pane_spawn(wp, argc, argv, path, shell, cwd, env, tio,
>           cause) != 0) {
>               window_destroy(w);
>               return (NULL);
> @@ -736,7 +736,8 @@ window_pane_create(struct window *w, u_int sx, u_int sy, 
> u_int hlimit)
>       wp->id = next_window_pane_id++;
>       RB_INSERT(window_pane_tree, &all_window_panes, wp);
>  
> -     wp->cmd = NULL;
> +     wp->argc = 0;
> +     wp->argv = NULL;
>       wp->shell = NULL;
>       wp->cwd = -1;
>  
> @@ -808,17 +809,17 @@ window_pane_destroy(struct window_pane *wp)
>  
>       close(wp->cwd);
>       free(wp->shell);
> -     free(wp->cmd);
> +     cmd_free_argv(wp->argc, wp->argv);
>       free(wp);
>  }
>  
>  int
> -window_pane_spawn(struct window_pane *wp, const char *cmd, const char *path,
> -    const char *shell, int cwd, struct environ *env, struct termios *tio,
> -    char **cause)
> +window_pane_spawn(struct window_pane *wp, int argc, char *const *argv,
> +    const char *path, const char *shell, int cwd, struct environ *env,
> +    struct termios *tio, char **cause)
>  {
>       struct winsize   ws;
> -     char            *argv0, paneid[16];
> +     char            *argv0, *cmd, *wpcmd, **exec_argv, paneid[16];
>       const char      *ptr;
>       struct termios   tio2;
>  #ifdef HAVE_UTEMPTER
> @@ -829,9 +830,10 @@ window_pane_spawn(struct window_pane *wp, const char 
> *cmd, const char *path,
>               bufferevent_free(wp->event);
>               close(wp->fd);
>       }
> -     if (cmd != NULL) {
> -             free(wp->cmd);
> -             wp->cmd = xstrdup(cmd);
> +     if (argc > 0) {
> +             cmd_free_argv(wp->argc, wp->argv);
> +             wp->argc = argc;
> +             wp->argv = cmd_copy_argv(argc, argv);
>       }
>       if (shell != NULL) {
>               free(wp->shell);
> @@ -842,7 +844,8 @@ window_pane_spawn(struct window_pane *wp, const char 
> *cmd, const char *path,
>               wp->cwd = dup(cwd);
>       }
>  
> -     log_debug("spawn: %s -- %s", wp->shell, wp->cmd);
> +     wpcmd = cmd_stringify_argv(wp->argc, wp->argv);
> +     log_debug("spawn: %s -- %s", wp->shell, wpcmd);
>  
>       memset(&ws, 0, sizeof ws);
>       ws.ws_col = screen_size_x(&wp->base);
> @@ -851,7 +854,10 @@ window_pane_spawn(struct window_pane *wp, const char 
> *cmd, const char *path,
>       switch (wp->pid = forkpty(&wp->fd, wp->tty, NULL, &ws)) {
>       case -1:
>               wp->fd = -1;
> +             cmd = cmd_stringify_argv(argc, argv);
>               xasprintf(cause, "%s: %s", cmd, strerror(errno));
> +             free(cmd);
> +             free(wpcmd);
>               return (-1);
>       case 0:
>               if (fchdir(wp->cwd) != 0)
> @@ -883,14 +889,24 @@ window_pane_spawn(struct window_pane *wp, const char 
> *cmd, const char *path,
>               setenv("SHELL", wp->shell, 1);
>               ptr = strrchr(wp->shell, '/');
>  
> -             if (*wp->cmd != '\0') {
> +             if (wp->argc > 0) {
>                       /* Use the command. */
> -                     if (ptr != NULL && *(ptr + 1) != '\0')
> -                             xasprintf(&argv0, "%s", ptr + 1);
> -                     else
> -                             xasprintf(&argv0, "%s", wp->shell);
> -                     execl(wp->shell, argv0, "-c", wp->cmd, (char *) NULL);
> -                     fatal("execl failed");
> +                     if (wp->argc == 1) {
> +                             if (ptr != NULL && *(ptr + 1) != '\0')
> +                                     xasprintf(&argv0, "%s", ptr + 1);
> +                             else
> +                                     xasprintf(&argv0, "%s", wp->shell);
> +                             execl(wp->shell, argv0, "-c", wp->argv[0],
> +                                             (char *) NULL);
> +                             fatal("execl failed");
> +                     }
> +
> +                     exec_argv = cmd_copy_argv(wp->argc, wp->argv);
> +                     exec_argv = xrealloc(exec_argv, wp->argc + 1,
> +                                     sizeof *wp->argv);
> +                     exec_argv[wp->argc] = NULL;
> +                     execvp(exec_argv[0], exec_argv);
> +                     fatal("execvp failed");
>               }
>  
>               /* No command; fork a login shell. */
> @@ -913,6 +929,7 @@ window_pane_spawn(struct window_pane *wp, const char 
> *cmd, const char *path,
>           window_pane_read_callback, NULL, window_pane_error_callback, wp);
>       bufferevent_enable(wp->event, EV_READ|EV_WRITE);
>  
> +     free(wpcmd);
>       return (0);
>  }
>  


------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
tmux-users mailing list
tmux-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/tmux-users

Reply via email to