diff --git a/client.c b/client.c
index 271568da..55c5aa56 100644
--- a/client.c
+++ b/client.c
@@ -33,6 +33,7 @@
 
 #include "tmux.h"
 
+int		client_flags;
 struct imsgbuf	client_ibuf;
 struct event	client_event;
 struct event	client_stdin;
@@ -51,9 +52,10 @@ enum msgtype	client_exittype;
 const char     *client_exitsession;
 int		client_attached;
 
+__dead void	client_exec(const char *);
 int		client_get_lock(char *);
 int		client_connect(struct event_base *, char *, int);
-void		client_send_identify(int);
+void		client_send_identify(void);
 int		client_write_one(enum msgtype, int, const void *, size_t);
 int		client_write_server(enum msgtype, const void *, size_t);
 void		client_update_event(void);
@@ -62,7 +64,7 @@ void		client_stdin_callback(int, short, void *);
 void		client_write(int, const char *, size_t);
 void		client_callback(int, short, void *);
 int		client_dispatch_attached(void);
-int		client_dispatch_wait(void *);
+int		client_dispatch_wait(void);
 const char     *client_exit_message(void);
 
 /*
@@ -215,6 +217,9 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
 	struct termios		 tio, saved_tio;
 	size_t			 size;
 
+	/* Save the flags. */
+	client_flags = flags;
+
 	/* Set up the initial command. */
 	cmdflags = 0;
 	if (shell_cmd != NULL) {
@@ -266,13 +271,13 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
 
 	/* Create imsg. */
 	imsg_init(&client_ibuf, fd);
-	event_set(&client_event, fd, EV_READ, client_callback, shell_cmd);
+	event_set(&client_event, fd, EV_READ, client_callback, NULL);
 
 	/* Create stdin handler. */
 	setblocking(STDIN_FILENO, 0);
 	event_set(&client_stdin, STDIN_FILENO, EV_READ|EV_PERSIST,
 	    client_stdin_callback, NULL);
-	if (flags & CLIENT_CONTROLCONTROL) {
+	if (client_flags & CLIENT_CONTROLCONTROL) {
 		if (tcgetattr(STDIN_FILENO, &saved_tio) != 0) {
 			fprintf(stderr, "tcgetattr failed: %s\n",
 			    strerror(errno));
@@ -291,7 +296,7 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
 	}
 
 	/* Send identify messages. */
-	client_send_identify(flags);
+	client_send_identify();
 
 	/* Send first command. */
 	if (msg == MSG_COMMAND) {
@@ -326,13 +331,13 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
 
 	/* Print the exit message, if any, and exit. */
 	if (client_attached) {
-		if (client_exitreason != CLIENT_EXIT_NONE && !login_shell)
+		if (client_exitreason != CLIENT_EXIT_NONE)
 			printf("[%s]\n", client_exit_message());
 
 		ppid = getppid();
 		if (client_exittype == MSG_DETACHKILL && ppid > 1)
 			kill(ppid, SIGHUP);
-	} else if (flags & CLIENT_CONTROLCONTROL) {
+	} else if (client_flags & CLIENT_CONTROLCONTROL) {
 		if (client_exitreason != CLIENT_EXIT_NONE)
 			printf("%%exit %s\n", client_exit_message());
 		else
@@ -346,12 +351,12 @@ client_main(struct event_base *base, int argc, char **argv, int flags)
 
 /* Send identify messages to server. */
 void
-client_send_identify(int flags)
+client_send_identify(void)
 {
 	const char	 *s;
 	char		**ss;
 	size_t		  sslen;
-	int		  fd;
+	int		  fd, flags = client_flags;
 	pid_t		  pid;
 
 	client_write_one(MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
@@ -421,14 +426,13 @@ client_update_event(void)
 	events = EV_READ;
 	if (client_ibuf.w.queued > 0)
 		events |= EV_WRITE;
-	event_set(
-	    &client_event, client_ibuf.fd, events, client_callback, shell_cmd);
+	event_set(&client_event, client_ibuf.fd, events, client_callback, NULL);
 	event_add(&client_event, NULL);
 }
 
 /* Callback to handle signals in the client. */
 void
-client_signal(int sig, unused short events, unused void *data)
+client_signal(int sig, unused short events, unused void *arg)
 {
 	struct sigaction sigact;
 	int		 status;
@@ -470,7 +474,7 @@ client_signal(int sig, unused short events, unused void *data)
 
 /* Callback for client imsg read events. */
 void
-client_callback(unused int fd, short events, void *data)
+client_callback(unused int fd, short events, unused void *arg)
 {
 	ssize_t	n;
 	int	retval;
@@ -481,7 +485,7 @@ client_callback(unused int fd, short events, void *data)
 		if (client_attached)
 			retval = client_dispatch_attached();
 		else
-			retval = client_dispatch_wait(data);
+			retval = client_dispatch_wait();
 		if (retval != 0) {
 			event_loopexit(NULL);
 			return;
@@ -504,7 +508,7 @@ lost_server:
 
 /* Callback for client stdin read events. */
 void
-client_stdin_callback(unused int fd, unused short events, unused void *data1)
+client_stdin_callback(unused int fd, unused short events, unused void *arg)
 {
 	struct msg_stdin_data	data;
 
@@ -536,9 +540,38 @@ client_write(int fd, const char *data, size_t size)
 	}
 }
 
+/* Run command in shell; used for -c. */
+__dead void
+client_exec(const char *shell)
+{
+	const char	*name, *ptr;
+	char		*argv0;
+
+	log_debug("shell %s, command %s", shell, shell_cmd);
+
+	ptr = strrchr(shell, '/');
+	if (ptr != NULL && *(ptr + 1) != '\0')
+		name = ptr + 1;
+	else
+		name = shell;
+	if (client_flags & CLIENT_LOGIN)
+		xasprintf(&argv0, "-%s", name);
+	else
+		xasprintf(&argv0, "%s", name);
+	setenv("SHELL", shell, 1);
+
+	setblocking(STDIN_FILENO, 1);
+	setblocking(STDOUT_FILENO, 1);
+	setblocking(STDERR_FILENO, 1);
+	closefrom(STDERR_FILENO + 1);
+
+	execl(shell, argv0, "-c", shell_cmd, (char *) NULL);
+	fatal("execl failed");
+}
+
 /* Dispatch imsgs when in wait state (before MSG_READY). */
 int
-client_dispatch_wait(void *data0)
+client_dispatch_wait(void)
 {
 	struct imsg		 imsg;
 	char			*data;
@@ -614,7 +647,7 @@ client_dispatch_wait(void *data0)
 				fatalx("bad MSG_SHELL string");
 
 			clear_signals(0);
-			shell_exec(data, data0);
+			client_exec(data);
 			/* NOTREACHED */
 		case MSG_DETACH:
 		case MSG_DETACHKILL:
diff --git a/tmux.c b/tmux.c
index b984b903..1ef23915 100644
--- a/tmux.c
+++ b/tmux.c
@@ -46,7 +46,6 @@ char		*shell_cmd;
 int		 debug_level;
 time_t		 start_time;
 char		 socket_path[PATH_MAX];
-int		 login_shell;
 char		*environ_path;
 
 __dead void	 usage(void);
@@ -170,32 +169,6 @@ setblocking(int fd, int state)
 	}
 }
 
-__dead void
-shell_exec(const char *shell, const char *shellcmd)
-{
-	const char	*shellname, *ptr;
-	char		*argv0;
-
-	ptr = strrchr(shell, '/');
-	if (ptr != NULL && *(ptr + 1) != '\0')
-		shellname = ptr + 1;
-	else
-		shellname = shell;
-	if (login_shell)
-		xasprintf(&argv0, "-%s", shellname);
-	else
-		xasprintf(&argv0, "%s", shellname);
-	setenv("SHELL", shell, 1);
-
-	setblocking(STDIN_FILENO, 1);
-	setblocking(STDOUT_FILENO, 1);
-	setblocking(STDERR_FILENO, 1);
-	closefrom(STDERR_FILENO + 1);
-
-	execl(shell, argv0, "-c", shellcmd, (char *) NULL);
-	fatal("execl failed");
-}
-
 const char *
 find_home(void)
 {
@@ -229,9 +202,12 @@ main(int argc, char **argv)
 
 	setlocale(LC_TIME, "");
 
-	flags = 0;
+	if (**argv == '-')
+		flags = CLIENT_LOGIN;
+	else
+		flags = 0;
+
 	label = path = NULL;
-	login_shell = (**argv == '-');
 	while ((opt = getopt(argc, argv, "2c:Cdf:lL:qS:uUv")) != -1) {
 		switch (opt) {
 		case '2':
@@ -252,7 +228,7 @@ main(int argc, char **argv)
 			cfg_file = xstrdup(optarg);
 			break;
 		case 'l':
-			login_shell = 1;
+			flags |= CLIENT_LOGIN;
 			break;
 		case 'L':
 			free(label);
diff --git a/tmux.h b/tmux.h
index 3b67470f..528c3e71 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1203,7 +1203,7 @@ struct client {
 	struct screen	 status;
 
 #define CLIENT_TERMINAL 0x1
-/* 0x2 unused */
+#define CLIENT_LOGIN 0x2
 #define CLIENT_EXIT 0x4
 #define CLIENT_REDRAW 0x8
 #define CLIENT_STATUS 0x10
@@ -1412,14 +1412,12 @@ extern char	*shell_cmd;
 extern int	 debug_level;
 extern time_t	 start_time;
 extern char	 socket_path[PATH_MAX];
-extern int	 login_shell;
 extern char	*environ_path;
 void		 logfile(const char *);
 const char	*getshell(void);
 int		 checkshell(const char *);
 int		 areshell(const char *);
 void		 setblocking(int, int);
-__dead void	 shell_exec(const char *, const char *);
 const char	*find_home(void);
 
 /* cfg.c */