Thanks - full diff below with some mostly style changes. In the manpage I changed it a bit because shell-command is still used as a single item for pipe-pane and some other places so better to list the commands that accept it as a multiple.
I'd like a better example for the multiple arguments case to demonstrate when this can avoid quoting nonsense, but I can't think of a good one offhand. Full diff below. I will apply this and the named buffers one tomorrow or next week probably. Index: cmd-new-session.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/cmd-new-session.c,v retrieving revision 1.59 diff -u -p -r1.59 cmd-new-session.c --- cmd-new-session.c 17 Apr 2014 13:02:59 -0000 1.59 +++ cmd-new-session.c 9 May 2014 10:36:41 -0000 @@ -35,10 +35,10 @@ enum cmd_retval cmd_new_session_exec(st 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]", + "[-s session-name] " CMD_TARGET_SESSION_USAGE " [-x width] " + "[-y height] [command]", CMD_STARTSERVER|CMD_CANTNEST, NULL, cmd_new_session_exec @@ -55,8 +55,9 @@ cmd_new_session_exec(struct cmd *self, s 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,21 @@ cmd_new_session_exec(struct cmd *self, s 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 + argc = -1; + argv = NULL; + if (target == NULL && args->argc != 0) { + argc = args->argc; + argv = args->argv; + } else if (target == NULL) { cmd = options_get_string(&global_s_options, "default-command"); + if (cmd != NULL && *cmd != '\0') { + argc = 1; + argv = &cmd; + } else { + argc = 0; + argv = NULL; + } + } path = NULL; if (c != NULL && c->session == NULL) @@ -206,8 +216,8 @@ cmd_new_session_exec(struct cmd *self, s /* 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 +226,7 @@ cmd_new_session_exec(struct cmd *self, s 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); Index: cmd-new-window.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/cmd-new-window.c,v retrieving revision 1.39 diff -u -p -r1.39 cmd-new-window.c --- cmd-new-window.c 17 Apr 2014 13:02:59 -0000 1.39 +++ cmd-new-window.c 9 May 2014 10:40:09 -0000 @@ -34,7 +34,7 @@ enum cmd_retval cmd_new_window_exec(stru 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, st 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,19 @@ cmd_new_window_exec(struct cmd *self, st } detached = args_has(args, 'd'); - if (args->argc == 0) + if (args->argc == 0) { cmd = options_get_string(&s->options, "default-command"); - else - cmd = args->argv[0]; + if (cmd != NULL && *cmd != '\0') { + argc = 1; + argv = (char**)&cmd; + } else { + argc = 0; + argv = NULL; + } + } else { + argc = args->argc; + argv = args->argv; + } path = NULL; if (cmdq->client != NULL && cmdq->client->session == NULL) @@ -145,7 +154,8 @@ cmd_new_window_exec(struct cmd *self, st 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); Index: cmd-respawn-pane.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/cmd-respawn-pane.c,v retrieving revision 1.11 diff -u -p -r1.11 cmd-respawn-pane.c --- cmd-respawn-pane.c 17 Apr 2014 13:02:59 -0000 1.11 +++ cmd-respawn-pane.c 9 May 2014 09:00:59 -0000 @@ -32,7 +32,7 @@ enum cmd_retval cmd_respawn_pane_exec(s 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 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, 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, 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); Index: cmd-respawn-window.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/cmd-respawn-window.c,v retrieving revision 1.21 diff -u -p -r1.21 cmd-respawn-window.c --- cmd-respawn-window.c 17 Apr 2014 13:02:59 -0000 1.21 +++ cmd-respawn-window.c 9 May 2014 09:00:59 -0000 @@ -31,7 +31,7 @@ enum cmd_retval cmd_respawn_window_exec 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 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 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 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); Index: cmd-split-window.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/cmd-split-window.c,v retrieving revision 1.49 diff -u -p -r1.49 cmd-split-window.c --- cmd-split-window.c 17 Apr 2014 13:02:59 -0000 1.49 +++ cmd-split-window.c 9 May 2014 10:38:54 -0000 @@ -36,7 +36,7 @@ enum cmd_retval cmd_split_window_exec(s 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, @@ -62,9 +62,9 @@ cmd_split_window_exec(struct cmd *self, 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; @@ -81,10 +81,19 @@ cmd_split_window_exec(struct cmd *self, environ_copy(&s->environ, &env); server_fill_environ(s, &env); - if (args->argc == 0) + if (args->argc == 0) { cmd = options_get_string(&s->options, "default-command"); - else - cmd = args->argv[0]; + if (cmd != NULL && *cmd != '\0') { + argc = 1; + argv = (char**)&cmd; + } else { + argc = 0; + argv = NULL; + } + } else { + argc = args->argc; + argv = args->argv; + } if (args_has(args, 'c')) { ft = format_create(); @@ -158,8 +167,8 @@ cmd_split_window_exec(struct cmd *self, if (envent != NULL) path = envent->value; - if (window_pane_spawn( - new_wp, cmd, path, shell, cwd, &env, s->tio, &cause) != 0) + if (window_pane_spawn(new_wp, argc, argv, path, shell, cwd, &env, + s->tio, &cause) != 0) goto error; layout_assign_pane(lc, new_wp); Index: cmd.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/cmd.c,v retrieving revision 1.93 diff -u -p -r1.93 cmd.c --- cmd.c 9 May 2014 09:11:24 -0000 1.93 +++ cmd.c 9 May 2014 10:32:01 -0000 @@ -187,7 +187,7 @@ cmd_copy_argv(int argc, char **argv) if (argc == 0) return (NULL); - new_argv = xcalloc(argc, sizeof *new_argv); + new_argv = xcalloc(argc + 1, sizeof *new_argv); for (i = 0; i < argc; i++) { if (argv[i] != NULL) new_argv[i] = xstrdup(argv[i]); @@ -205,6 +205,32 @@ cmd_free_argv(int argc, char **argv) for (i = 0; i < argc; i++) free(argv[i]); free(argv); +} + +char * +cmd_stringify_argv(int argc, char **argv) +{ + char *buf; + int i; + size_t len; + + if (argc == 0) + return (xstrdup("")); + + len = 0; + buf = NULL; + + for (i = 0; i < argc; i++) { + len += strlen(argv[i]) + 1; + buf = xrealloc(buf, 1, len); + + if (i == 0) + *buf = '\0'; + else + strlcat(buf, " ", len); + strlcat(buf, argv[i], len); + } + return (buf); } struct cmd * Index: format.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/format.c,v retrieving revision 1.44 diff -u -p -r1.44 format.c --- format.c 17 Apr 2014 15:37:55 -0000 1.44 +++ format.c 9 May 2014 09:02:05 -0000 @@ -368,7 +368,7 @@ format_get_command(struct window_pane *w cmd = get_proc_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,10 @@ format_window_pane(struct format_tree *f 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); + if ((cmd = cmd_stringify_argv(wp->argc, wp->argv)) != NULL) { + format_add(ft, "pane_start_command", "%s", cmd); + free(cmd); + } if ((cmd = format_get_command(wp)) != NULL) { format_add(ft, "pane_current_command", "%s", cmd); free(cmd); Index: names.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/names.c,v retrieving revision 1.22 diff -u -p -r1.22 names.c --- names.c 10 Oct 2013 11:56:50 -0000 1.22 +++ names.c 9 May 2014 10:37:57 -0000 @@ -68,9 +68,15 @@ window_name_callback(unused int fd, unus char * default_window_name(struct window *w) { - if (w->active->cmd != NULL && *w->active->cmd != '\0') - return (parse_window_name(w->active->cmd)); - return (parse_window_name(w->active->shell)); + char *cmd, *s; + + cmd = cmd_stringify_argv(w->active->argc, w->active->argv); + if (cmd != NULL && *cmd != '\0') + s = parse_window_name(cmd); + else + s = parse_window_name(w->active->shell); + free(cmd); + return (s); } char * Index: session.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/session.c,v retrieving revision 1.43 diff -u -p -r1.43 session.c --- session.c 17 Apr 2014 13:02:59 -0000 1.43 +++ session.c 9 May 2014 10:33:37 -0000 @@ -85,11 +85,12 @@ 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 **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; + struct winlink *wl; s = xmalloc(sizeof *s); s->references = 0; @@ -132,8 +133,9 @@ session_create(const char *name, const c } RB_INSERT(sessions, &sessions, s); - if (cmd != NULL) { - if (session_new(s, NULL, cmd, path, cwd, idx, cause) == NULL) { + if (argc >= 0) { + wl = session_new(s, NULL, argc, argv, path, cwd, idx, cause); + if (wl == NULL) { session_destroy(s); return (NULL); } @@ -227,7 +229,7 @@ session_previous_session(struct session /* 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 **argv, const char *path, int cwd, int idx, char **cause) { struct window *w; @@ -251,8 +253,8 @@ session_new(struct session *s, const cha 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); Index: tmux.1 =================================================================== RCS file: /cvs/src/usr.bin/tmux/tmux.1,v retrieving revision 1.391 diff -u -p -r1.391 tmux.1 --- tmux.1 17 Apr 2014 15:48:02 -0000 1.391 +++ tmux.1 9 May 2014 10:50:00 -0000 @@ -478,11 +478,36 @@ It may be used alone to target a pane or arguments are .Xr sh 1 commands. -These must be passed as a single item, which typically means quoting them, for -example: +This may be a single argument passed to the shell, for example: .Bd -literal -offset indent new-window 'vi /etc/passwd' .Ed +.Pp +Will run: +.Bd -literal -offset indent +/bin/sh -c 'vi /etc/passwd' +.Ed +.Pp +Additionally, the +.Ic new-window , +.Ic new-session , +.Ic split-window , +.Ic respawn-window +and +.Ic respawn-pane +commands allow +.Ar shell-command +to be given as multiple arguments and executed directly (without +.Ql sh -c ) . +This can avoid issues with shell quoting. +For example: +.Bd -literal -offset indent +$ tmux new-window vi /etc/passwd +.Ed +.Pp +Will run +.Xr vi 1 +directly without invoking the shell. .Pp .Ar command .Op Ar arguments Index: tmux.h =================================================================== RCS file: /cvs/src/usr.bin/tmux/tmux.h,v retrieving revision 1.460 diff -u -p -r1.460 tmux.h --- tmux.h 9 May 2014 09:11:24 -0000 1.460 +++ tmux.h 9 May 2014 09:11:43 -0000 @@ -912,7 +912,8 @@ struct window_pane { #define PANE_RESIZE 0x8 #define PANE_FOCUSPUSH 0x10 - char *cmd; + int argc; + char **argv; char *shell; int cwd; @@ -1740,6 +1741,7 @@ int cmd_pack_argv(int, char **, char * int cmd_unpack_argv(char *, size_t, int, char ***); char **cmd_copy_argv(int, char **); void cmd_free_argv(int, char **); +char *cmd_stringify_argv(int, char **); 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); @@ -2130,7 +2132,7 @@ void winlink_stack_remove(struct winli 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 char *, const char *, int, struct environ *, struct termios *, u_int, u_int, u_int, char **); void window_destroy(struct window *); @@ -2156,7 +2158,7 @@ struct window_pane *window_pane_find_by_ 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 char *, const char *, int, struct environ *, struct termios *, char **); void window_pane_resize(struct window_pane *, u_int, u_int); @@ -2294,18 +2296,18 @@ RB_PROTOTYPE(sessions, session, entry, s 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, - char **); +struct session *session_create(const char *, int, char **, 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 *, +struct winlink *session_new(struct session *, const char *, int, char **, const char *, int, int, char **); -struct winlink *session_attach( - struct session *, struct window *, int, char **); +struct winlink *session_attach(struct session *, struct window *, int, + char **); int session_detach(struct session *, struct winlink *); struct winlink *session_has(struct session *, struct window *); int session_next(struct session *, int); Index: window.c =================================================================== RCS file: /cvs/src/usr.bin/tmux/window.c,v retrieving revision 1.109 diff -u -p -r1.109 window.c --- window.c 8 May 2014 06:03:30 -0000 1.109 +++ window.c 9 May 2014 10:50:31 -0000 @@ -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 **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 ch 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); @@ -678,7 +678,8 @@ window_pane_create(struct window *w, u_i 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; @@ -737,27 +738,29 @@ window_pane_destroy(struct window_pane * 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 **argv, + const char *path, const char *shell, int cwd, struct environ *env, + struct termios *tio, char **cause) { struct winsize ws; - char *argv0, paneid[16]; - const char *ptr; + char *argv0, *cmd, **argvp, paneid[16]; + const char *ptr, *first; struct termios tio2; + int i; if (wp->fd != -1) { 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); @@ -768,7 +771,10 @@ window_pane_spawn(struct window_pane *wp wp->cwd = dup(cwd); } - log_debug("spawn: %s -- %s", wp->shell, wp->cmd); + cmd = cmd_stringify_argv(wp->argc, wp->argv); + log_debug("spawn: %s -- %s", wp->shell, cmd); + for (i = 0; i < wp->argc; i++) + log_debug("spawn: argv[%d] = %s", i, wp->argv[i]); memset(&ws, 0, sizeof ws); ws.ws_col = screen_size_x(&wp->base); @@ -778,6 +784,7 @@ window_pane_spawn(struct window_pane *wp case -1: wp->fd = -1; xasprintf(cause, "%s: %s", cmd, strerror(errno)); + free(cmd); return (-1); case 0: if (fchdir(wp->cwd) != 0) @@ -805,31 +812,42 @@ window_pane_spawn(struct window_pane *wp setenv("SHELL", wp->shell, 1); ptr = strrchr(wp->shell, '/'); - if (*wp->cmd != '\0') { - /* Use the command. */ + /* + * If given one argument, assume it should be passed to sh -c; + * with more than one argument, use execvp(). If there is no + * arguments, create a login shell. + */ + if (wp->argc > 0) { + if (wp->argc != 1) { + /* Copy to ensure argv ends in NULL. */ + argvp = cmd_copy_argv(wp->argc, wp->argv); + execvp(argvp[0], argvp); + fatal("execvp failed"); + } + first = wp->argv[0]; + 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); + execl(wp->shell, argv0, "-c", first, (char *)NULL); fatal("execl failed"); } - - /* No command; fork a login shell. */ if (ptr != NULL && *(ptr + 1) != '\0') xasprintf(&argv0, "-%s", ptr + 1); else xasprintf(&argv0, "-%s", wp->shell); - execl(wp->shell, argv0, (char *) NULL); + execl(wp->shell, argv0, (char *)NULL); fatal("execl failed"); } setblocking(wp->fd, 0); - wp->event = bufferevent_new(wp->fd, - window_pane_read_callback, NULL, window_pane_error_callback, wp); + wp->event = bufferevent_new(wp->fd, window_pane_read_callback, NULL, + window_pane_error_callback, wp); bufferevent_enable(wp->event, EV_READ|EV_WRITE); + free(cmd); return (0); } On Thu, May 08, 2014 at 08:03:08PM -0500, J Raynor wrote: > I've attached a patch that just updates the man page. If this patch > is acceptable, let me know if you would like this combined with the > patch for the code into a single patch. > > On Thu, May 8, 2014 at 2:41 AM, Nicholas Marriott > <nicholas.marri...@gmail.com> wrote: > > This looks good, it needs to go in the man page, but I'm not sure > > where... any ideas? > diff --git a/tmux.1 b/tmux.1 > index c05eacf..d35f88c 100644 > --- a/tmux.1 > +++ b/tmux.1 > @@ -482,12 +482,16 @@ It may be used alone to target a pane or the window > containing it. > arguments are > .Xr sh 1 > commands. > -These must be passed as a single item, which typically means quoting them, > for > +These may be passed as a single item, which typically means quoting them, for > example: > .Bd -literal -offset indent > new-window 'vi /etc/passwd' > .Ed > .Pp > +If passed as a single item, the SHELL will receive them as a single argument, > +and will parse the command according to its rules. If not passed as a single > +item, the command will be spawned directly, without the use of the SHELL. > +.Pp > .Ar command > .Op Ar arguments > refers to a ------------------------------------------------------------------------------ Is your legacy SCM system holding you back? Join Perforce May 7 to find out: • 3 signs your SCM is hindering your productivity • Requirements for releasing software faster • 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