Using -l to specify a login shell is non-POSIX and causes problems with shells

that do not support it. Instead, set an empty default-command to invoke $SHELL
with - prefixed to argv[0], and make this the default setting.
This commit is contained in:
Nicholas Marriott 2009-07-01 19:42:55 +00:00
parent d50810267e
commit 22d1b9412e
3 changed files with 43 additions and 18 deletions

8
tmux.1
View File

@ -1044,8 +1044,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.

15
tmux.c
View File

@ -1,4 +1,4 @@
/* $Id: tmux.c,v 1.137 2009-06-25 16:56:08 nicm Exp $ */ /* $Id: tmux.c,v 1.138 2009-07-01 19:42:55 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -218,7 +218,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];
@ -279,6 +278,7 @@ main(int argc, char **argv)
options_init(&global_options, NULL); options_init(&global_options, NULL);
options_set_number(&global_options, "bell-action", BELL_ANY); options_set_number(&global_options, "bell-action", BELL_ANY);
options_set_number(&global_options, "buffer-limit", 9); options_set_number(&global_options, "buffer-limit", 9);
options_set_string(&global_options, "default-command", "%s", "");
options_set_number(&global_options, "display-time", 750); options_set_number(&global_options, "display-time", 750);
options_set_number(&global_options, "history-limit", 2000); options_set_number(&global_options, "history-limit", 2000);
options_set_number(&global_options, "lock-after-time", 0); options_set_number(&global_options, "lock-after-time", 0);
@ -368,17 +368,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_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')

View File

@ -1,4 +1,4 @@
/* $Id: window.c,v 1.85 2009-06-25 16:47:00 nicm Exp $ */ /* $Id: window.c,v 1.86 2009-07-01 19:42:55 nicm Exp $ */
/* /*
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
@ -22,6 +22,7 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <fnmatch.h> #include <fnmatch.h>
#include <pwd.h>
#include <signal.h> #include <signal.h>
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
@ -53,8 +54,27 @@
/* Global window list. */ /* Global window list. */
struct windows windows; struct windows windows;
const char *window_default_command(void);
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)
{ {
@ -422,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)
@ -463,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");
} }