Just appending -l to $SHELL to create a login shell is wrong: -l is not POSIX,

and some people may use shells which do not support it. Instead, make an empty
default-command option mean a login shell, and fork it with a - in argv[0]
which is the method used by login(1).

Also fix the automatic-rename code to handle this correctly and to strip a
leading - if present.
This commit is contained in:
Nicholas Marriott 2009-07-08 05:26:45 +00:00
parent b4efd1ca89
commit 084d07f4eb
5 changed files with 53 additions and 18 deletions

15
names.c
View File

@ -59,7 +59,16 @@ set_window_names(void)
if (name == NULL) if (name == NULL)
wname = default_window_name(w); wname = default_window_name(w);
else { else {
wname = parse_window_name(name); /*
* If tmux is using the default command, it will be a
* login shell and argv[0] may have a - prefix. Remove
* this if it is present. Ick.
*/
if (w->active->cmd != NULL && *w->active->cmd == '\0' &&
name != NULL && name[0] == '-' && name[1] != '\0')
wname = parse_window_name(name + 1);
else
wname = parse_window_name(name);
xfree(name); xfree(name);
} }
@ -78,7 +87,9 @@ default_window_name(struct window *w)
{ {
if (w->active->screen != &w->active->base) if (w->active->screen != &w->active->base)
return (xstrdup("[tmux]")); return (xstrdup("[tmux]"));
return (parse_window_name(w->active->cmd)); if (w->active->cmd != NULL && *w->active->cmd != '\0')
return (parse_window_name(w->active->cmd));
return (parse_window_name(window_default_command()));
} }
char * char *

8
tmux.1
View File

@ -1070,8 +1070,12 @@ maintain this maximum length.
Set the command used for new windows (if not specified when the window is Set the command used for new windows (if not specified when the window is
created) to created) to
.Ar command . .Ar command .
The default is The default is an empty string, which instructs
.Dq exec $SHELL -l . .Nm
to create a login shell using the
.Ev SHELL
environment variable or, if it is unset, the user's shell returned by
.Xr getpwuid 3 .
.It Ic default-path Ar path .It Ic default-path Ar path
Set the default working directory for processes created from keys, or Set the default working directory for processes created from keys, or
interactively from the prompt. interactively from the prompt.

13
tmux.c
View File

@ -209,7 +209,6 @@ main(int argc, char **argv)
struct cmd *cmd; struct cmd *cmd;
struct pollfd pfd; struct pollfd pfd;
struct hdr hdr; struct hdr hdr;
const char *shell;
struct passwd *pw; struct passwd *pw;
char *s, *path, *label, *cause, *home, *pass = NULL; char *s, *path, *label, *cause, *home, *pass = NULL;
char cwd[MAXPATHLEN]; char cwd[MAXPATHLEN];
@ -270,6 +269,7 @@ main(int argc, char **argv)
options_init(&global_s_options, NULL); options_init(&global_s_options, NULL);
options_set_number(&global_s_options, "bell-action", BELL_ANY); options_set_number(&global_s_options, "bell-action", BELL_ANY);
options_set_number(&global_s_options, "buffer-limit", 9); options_set_number(&global_s_options, "buffer-limit", 9);
options_set_string(&global_s_options, "default-command", "%s", "");
options_set_number(&global_s_options, "display-time", 750); options_set_number(&global_s_options, "display-time", 750);
options_set_number(&global_s_options, "history-limit", 2000); options_set_number(&global_s_options, "history-limit", 2000);
options_set_number(&global_s_options, "lock-after-time", 0); options_set_number(&global_s_options, "lock-after-time", 0);
@ -358,17 +358,6 @@ main(int argc, char **argv)
} }
xfree(label); xfree(label);
shell = getenv("SHELL");
if (shell == NULL || *shell == '\0') {
pw = getpwuid(getuid());
if (pw != NULL)
shell = pw->pw_shell;
if (shell == NULL || *shell == '\0')
shell = _PATH_BSHELL;
}
options_set_string(
&global_s_options, "default-command", "exec %s -l", shell);
if (getcwd(cwd, sizeof cwd) == NULL) { if (getcwd(cwd, sizeof cwd) == NULL) {
pw = getpwuid(getuid()); pw = getpwuid(getuid());
if (pw->pw_dir != NULL && *pw->pw_dir != '\0') if (pw->pw_dir != NULL && *pw->pw_dir != '\0')

1
tmux.h
View File

@ -1408,6 +1408,7 @@ int screen_check_selection(struct screen *, u_int, u_int);
/* window.c */ /* window.c */
extern struct windows windows; extern struct windows windows;
const char *window_default_command(void);
int window_cmp(struct window *, struct window *); int window_cmp(struct window *, struct window *);
int winlink_cmp(struct winlink *, struct winlink *); int winlink_cmp(struct winlink *, struct winlink *);
RB_PROTOTYPE(windows, window, entry, window_cmp); RB_PROTOTYPE(windows, window, entry, window_cmp);

View File

@ -23,6 +23,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <fnmatch.h> #include <fnmatch.h>
#include <paths.h> #include <paths.h>
#include <pwd.h>
#include <signal.h> #include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -57,6 +58,23 @@ struct windows windows;
RB_GENERATE(winlinks, winlink, entry, winlink_cmp); RB_GENERATE(winlinks, winlink, entry, winlink_cmp);
const char *
window_default_command(void)
{
const char *shell;
struct passwd *pw;
shell = getenv("SHELL");
if (shell != NULL && *shell != '\0')
return (shell);
pw = getpwuid(getuid());
if (pw != NULL && pw->pw_shell != NULL && *pw->pw_shell != '\0')
return (pw->pw_shell);
return (_PATH_BSHELL);
}
int int
winlink_cmp(struct winlink *wl1, struct winlink *wl2) winlink_cmp(struct winlink *wl1, struct winlink *wl2)
{ {
@ -424,7 +442,8 @@ window_pane_spawn(struct window_pane *wp,
{ {
struct winsize ws; struct winsize ws;
int mode; int mode;
const char **envq; const char **envq, *ptr;
char *argv0;
struct timeval tv; struct timeval tv;
if (wp->fd != -1) if (wp->fd != -1)
@ -465,7 +484,18 @@ window_pane_spawn(struct window_pane *wp,
sigreset(); sigreset();
log_close(); log_close();
execl(_PATH_BSHELL, "sh", "-c", wp->cmd, (char *) NULL); if (*wp->cmd != '\0') {
execl(_PATH_BSHELL, "sh", "-c", wp->cmd, (char *) NULL);
fatal("execl failed");
}
/* No command; fork a login shell. */
cmd = window_default_command();
if ((ptr = strrchr(cmd, '/')) != NULL && *(ptr + 1) != '\0')
xasprintf(&argv0, "-%s", ptr + 1);
else
xasprintf(&argv0, "-%s", cmd);
execl(cmd, argv0, (char *) NULL);
fatal("execl failed"); fatal("execl failed");
} }