mirror of
				https://github.com/tmux/tmux.git
				synced 2025-10-26 12:27:15 +00:00 
			
		
		
		
	Sync OpenBSD patchset 350:
Support -c like sh(1) to execute a command, useful when tmux is a login shell. Suggested by halex@. This includes another protocol version increase (the last for now) so again restart the tmux server before upgrading.
This commit is contained in:
		
							
								
								
									
										4
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								client.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: client.c,v 1.74 2009-09-23 15:00:08 tcunha Exp $ */ | /* $Id: client.c,v 1.75 2009-09-23 15:18:56 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -95,6 +95,8 @@ server_started: | |||||||
| 		fatal("fcntl failed"); | 		fatal("fcntl failed"); | ||||||
| 	if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) | 	if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) | ||||||
| 		fatal("fcntl failed"); | 		fatal("fcntl failed"); | ||||||
|  | 	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) | ||||||
|  | 		fatal("fcntl failed"); | ||||||
| 	imsg_init(&cctx->ibuf, fd); | 	imsg_init(&cctx->ibuf, fd); | ||||||
|  |  | ||||||
| 	if (cmdflags & CMD_SENDENVIRON) | 	if (cmdflags & CMD_SENDENVIRON) | ||||||
|   | |||||||
							
								
								
									
										27
									
								
								server-msg.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								server-msg.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: server-msg.c,v 1.87 2009-09-23 15:00:08 tcunha Exp $ */ | /* $Id: server-msg.c,v 1.88 2009-09-23 15:18:56 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -20,6 +20,7 @@ | |||||||
| #include <sys/ioctl.h> | #include <sys/ioctl.h> | ||||||
|  |  | ||||||
| #include <errno.h> | #include <errno.h> | ||||||
|  | #include <paths.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <string.h> | #include <string.h> | ||||||
| #include <time.h> | #include <time.h> | ||||||
| @@ -29,6 +30,7 @@ | |||||||
|  |  | ||||||
| void	server_msg_command(struct client *, struct msg_command_data *); | void	server_msg_command(struct client *, struct msg_command_data *); | ||||||
| void	server_msg_identify(struct client *, struct msg_identify_data *, int); | void	server_msg_identify(struct client *, struct msg_identify_data *, int); | ||||||
|  | void	server_msg_shell(struct client *); | ||||||
|  |  | ||||||
| void printflike2 server_msg_command_error(struct cmd_ctx *, const char *, ...); | void printflike2 server_msg_command_error(struct cmd_ctx *, const char *, ...); | ||||||
| void printflike2 server_msg_command_print(struct cmd_ctx *, const char *, ...); | void printflike2 server_msg_command_print(struct cmd_ctx *, const char *, ...); | ||||||
| @@ -113,6 +115,12 @@ server_msg_dispatch(struct client *c) | |||||||
| 			if (strchr(environdata.var, '=') != NULL) | 			if (strchr(environdata.var, '=') != NULL) | ||||||
| 				environ_put(&c->environ, environdata.var); | 				environ_put(&c->environ, environdata.var); | ||||||
| 			break; | 			break; | ||||||
|  | 		case MSG_SHELL: | ||||||
|  | 			if (datalen != 0) | ||||||
|  | 				fatalx("bad MSG_SHELL size"); | ||||||
|  |  | ||||||
|  | 			server_msg_shell(c); | ||||||
|  | 			break; | ||||||
| 		default: | 		default: | ||||||
| 			fatalx("unexpected message"); | 			fatalx("unexpected message"); | ||||||
| 		} | 		} | ||||||
| @@ -248,3 +256,20 @@ server_msg_identify(struct client *c, struct msg_identify_data *data, int fd) | |||||||
|  |  | ||||||
| 	c->flags |= CLIENT_TERMINAL; | 	c->flags |= CLIENT_TERMINAL; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | server_msg_shell(struct client *c) | ||||||
|  | { | ||||||
|  | 	struct msg_shell_data	 data; | ||||||
|  | 	const char		*shell; | ||||||
|  | 	 | ||||||
|  | 	shell = options_get_string(&global_s_options, "default-shell"); | ||||||
|  |  | ||||||
|  | 	if (*shell == '\0' || areshell(shell)) | ||||||
|  | 		shell = _PATH_BSHELL; | ||||||
|  | 	if (strlcpy(data.shell, shell, sizeof data.shell) >= sizeof data.shell) | ||||||
|  | 		strlcpy(data.shell, _PATH_BSHELL, sizeof data.shell); | ||||||
|  | 	 | ||||||
|  | 	server_write_client(c, MSG_SHELL, &data, sizeof data); | ||||||
|  | 	c->flags |= CLIENT_BAD;	/* it will die after exec */ | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								tmux.1
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| .\" $Id: tmux.1,v 1.172 2009-09-23 15:00:09 tcunha Exp $ | .\" $Id: tmux.1,v 1.173 2009-09-23 15:18:56 tcunha Exp $ | ||||||
| .\" | .\" | ||||||
| .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | .\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| .\" | .\" | ||||||
| @@ -24,6 +24,7 @@ | |||||||
| .Nm tmux | .Nm tmux | ||||||
| .Bk -words | .Bk -words | ||||||
| .Op Fl 28dlquv | .Op Fl 28dlquv | ||||||
|  | .Op Fl c Ar shell-command | ||||||
| .Op Fl f Ar file | .Op Fl f Ar file | ||||||
| .Op Fl L Ar socket-name | .Op Fl L Ar socket-name | ||||||
| .Op Fl S Ar socket-path | .Op Fl S Ar socket-path | ||||||
| @@ -101,6 +102,15 @@ to assume the terminal supports 256 colours. | |||||||
| Like | Like | ||||||
| .Fl 2 , | .Fl 2 , | ||||||
| but indicates that the terminal supports 88 colours. | but indicates that the terminal supports 88 colours. | ||||||
|  | .It Fl c Ar shell-command | ||||||
|  | Execute | ||||||
|  | .Ar shell-command | ||||||
|  | using the default shell. | ||||||
|  | If necessary, the | ||||||
|  | .Nm | ||||||
|  | server will be started to retrieve the | ||||||
|  | .Ic default-shell | ||||||
|  | option. | ||||||
| .It Fl d | .It Fl d | ||||||
| Force | Force | ||||||
| .Nm | .Nm | ||||||
|   | |||||||
							
								
								
									
										68
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										68
									
								
								tmux.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: tmux.c,v 1.174 2009-09-23 15:00:09 tcunha Exp $ */ | /* $Id: tmux.c,v 1.175 2009-09-23 15:18:56 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -62,7 +62,8 @@ int		 login_shell; | |||||||
| __dead void	 usage(void); | __dead void	 usage(void); | ||||||
| char 		*makesockpath(const char *); | char 		*makesockpath(const char *); | ||||||
| int		 prepare_cmd(enum msgtype *, void **, size_t *, int, char **); | int		 prepare_cmd(enum msgtype *, void **, size_t *, int, char **); | ||||||
| int		 dispatch_imsg(struct client_ctx *, int *); | int		 dispatch_imsg(struct client_ctx *, const char *, int *); | ||||||
|  | __dead void	 shell_exec(const char *, const char *); | ||||||
|  |  | ||||||
| #ifndef HAVE_PROGNAME | #ifndef HAVE_PROGNAME | ||||||
| char      *__progname = (char *) "tmux"; | char      *__progname = (char *) "tmux"; | ||||||
| @@ -72,7 +73,7 @@ __dead void | |||||||
| usage(void) | usage(void) | ||||||
| { | { | ||||||
| 	fprintf(stderr, | 	fprintf(stderr, | ||||||
| 	    "usage: %s [-28dlquv] [-f file] [-L socket-name]\n" | 	    "usage: %s [-28dlquv] [-c shell-command] [-f file] [-L socket-name]\n" | ||||||
| 	    "            [-S socket-path] [command [flags]]\n", | 	    "            [-S socket-path] [command [flags]]\n", | ||||||
| 	    __progname); | 	    __progname); | ||||||
| 	exit(1); | 	exit(1); | ||||||
| @@ -284,17 +285,17 @@ main(int argc, char **argv) | |||||||
| 	struct passwd		*pw; | 	struct passwd		*pw; | ||||||
| 	struct options		*so, *wo; | 	struct options		*so, *wo; | ||||||
| 	struct keylist		*keylist; | 	struct keylist		*keylist; | ||||||
| 	char			*s, *path, *label, *home, *cause, **var; | 	char			*s, *shellcmd, *path, *label, *home, *cause; | ||||||
| 	char			 cwd[MAXPATHLEN]; | 	char			 cwd[MAXPATHLEN], **var; | ||||||
| 	void			*buf; | 	void			*buf; | ||||||
| 	size_t			 len; | 	size_t			 len; | ||||||
| 	int	 		 retcode, opt, flags, cmdflags = 0; | 	int	 		 retcode, opt, flags, cmdflags = 0; | ||||||
| 	int			 nfds; | 	int			 nfds; | ||||||
|  |  | ||||||
| 	flags = 0; | 	flags = 0; | ||||||
| 	label = path = NULL; | 	shellcmd = label = path = NULL; | ||||||
| 	login_shell = (**argv == '-'); | 	login_shell = (**argv == '-'); | ||||||
| 	while ((opt = getopt(argc, argv, "28df:lL:qS:uUv")) != -1) { | 	while ((opt = getopt(argc, argv, "28c:df:lL:qS:uUv")) != -1) { | ||||||
| 		switch (opt) { | 		switch (opt) { | ||||||
| 		case '2': | 		case '2': | ||||||
| 			flags |= IDENTIFY_256COLOURS; | 			flags |= IDENTIFY_256COLOURS; | ||||||
| @@ -304,6 +305,11 @@ main(int argc, char **argv) | |||||||
| 			flags |= IDENTIFY_88COLOURS; | 			flags |= IDENTIFY_88COLOURS; | ||||||
| 			flags &= ~IDENTIFY_256COLOURS; | 			flags &= ~IDENTIFY_256COLOURS; | ||||||
| 			break; | 			break; | ||||||
|  | 		case 'c': | ||||||
|  | 			if (shellcmd != NULL) | ||||||
|  | 				xfree(shellcmd); | ||||||
|  | 			shellcmd = xstrdup(optarg); | ||||||
|  | 			break; | ||||||
| 		case 'd': | 		case 'd': | ||||||
| 			flags |= IDENTIFY_HASDEFAULTS; | 			flags |= IDENTIFY_HASDEFAULTS; | ||||||
| 			break; | 			break; | ||||||
| @@ -341,6 +347,9 @@ main(int argc, char **argv) | |||||||
| 	argc -= optind; | 	argc -= optind; | ||||||
| 	argv += optind; | 	argv += optind; | ||||||
|  |  | ||||||
|  | 	if (shellcmd != NULL && argc != 0) | ||||||
|  | 		usage(); | ||||||
|  |  | ||||||
| 	log_open_tty(debug_level); | 	log_open_tty(debug_level); | ||||||
| 	siginit(); | 	siginit(); | ||||||
|  |  | ||||||
| @@ -486,10 +495,16 @@ main(int argc, char **argv) | |||||||
| 	} | 	} | ||||||
| 	xfree(label); | 	xfree(label); | ||||||
|  |  | ||||||
| 	if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0) | 	if (shellcmd != NULL) { | ||||||
|  | 		msg = MSG_SHELL; | ||||||
|  | 		buf = NULL; | ||||||
|  | 		len = 0; | ||||||
|  | 	} else if (prepare_cmd(&msg, &buf, &len, argc, argv) != 0) | ||||||
| 		exit(1); | 		exit(1); | ||||||
|  |  | ||||||
| 	if (argc == 0)	/* new-session is the default */ | 	if (shellcmd != NULL) | ||||||
|  | 		cmdflags |= CMD_STARTSERVER; | ||||||
|  | 	else if (argc == 0)	/* new-session is the default */ | ||||||
| 		cmdflags |= CMD_STARTSERVER|CMD_SENDENVIRON; | 		cmdflags |= CMD_STARTSERVER|CMD_SENDENVIRON; | ||||||
| 	else { | 	else { | ||||||
| 		/* | 		/* | ||||||
| @@ -538,7 +553,7 @@ main(int argc, char **argv) | |||||||
| 			fatalx("socket error"); | 			fatalx("socket error"); | ||||||
|  |  | ||||||
|                 if (pfd.revents & POLLIN) { |                 if (pfd.revents & POLLIN) { | ||||||
| 			if (dispatch_imsg(&cctx, &retcode) != 0) | 			if (dispatch_imsg(&cctx, shellcmd, &retcode) != 0) | ||||||
| 				break; | 				break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| @@ -555,11 +570,12 @@ main(int argc, char **argv) | |||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| dispatch_imsg(struct client_ctx *cctx, int *retcode) | dispatch_imsg(struct client_ctx *cctx, const char *shellcmd, int *retcode) | ||||||
| { | { | ||||||
| 	struct imsg		imsg; | 	struct imsg		imsg; | ||||||
| 	ssize_t			n, datalen; | 	ssize_t			n, datalen; | ||||||
| 	struct msg_print_data	printdata; | 	struct msg_print_data	printdata; | ||||||
|  | 	struct msg_shell_data	shelldata; | ||||||
|  |  | ||||||
|         if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) |         if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) | ||||||
| 		fatalx("imsg_read failed"); | 		fatalx("imsg_read failed"); | ||||||
| @@ -603,6 +619,13 @@ dispatch_imsg(struct client_ctx *cctx, int *retcode) | |||||||
| 			    "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid); | 			    "server %u)", PROTOCOL_VERSION, imsg.hdr.peerid); | ||||||
| 			*retcode = 1; | 			*retcode = 1; | ||||||
| 			return (-1); | 			return (-1); | ||||||
|  | 		case MSG_SHELL: | ||||||
|  | 			if (datalen != sizeof shelldata) | ||||||
|  | 				fatalx("bad MSG_SHELL size"); | ||||||
|  | 			memcpy(&shelldata, imsg.data, sizeof shelldata); | ||||||
|  | 			shelldata.shell[(sizeof shelldata.shell) - 1] = '\0'; | ||||||
|  | 			 | ||||||
|  | 			shell_exec(shelldata.shell, shellcmd); | ||||||
| 		default: | 		default: | ||||||
| 			fatalx("unexpected message"); | 			fatalx("unexpected message"); | ||||||
| 		} | 		} | ||||||
| @@ -610,3 +633,26 @@ dispatch_imsg(struct client_ctx *cctx, int *retcode) | |||||||
| 		imsg_free(&imsg); | 		imsg_free(&imsg); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | __dead void | ||||||
|  | shell_exec(const char *shell, const char *shellcmd) | ||||||
|  | { | ||||||
|  | 	const char	*shellname, *ptr; | ||||||
|  | 	char		*argv0; | ||||||
|  |  | ||||||
|  | 	sigreset(); | ||||||
|  | 				 | ||||||
|  | 	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); | ||||||
|  |  | ||||||
|  | 	execl(shell, argv0, "-c", shellcmd, (char *) NULL); | ||||||
|  | 	fatal("execl failed"); | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										12
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								tmux.h
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: tmux.h,v 1.453 2009-09-23 15:00:09 tcunha Exp $ */ | /* $Id: tmux.h,v 1.454 2009-09-23 15:18:56 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -21,7 +21,7 @@ | |||||||
|  |  | ||||||
| #include "config.h" | #include "config.h" | ||||||
|  |  | ||||||
| #define PROTOCOL_VERSION 4 | #define PROTOCOL_VERSION 5 | ||||||
|  |  | ||||||
| #include <sys/param.h> | #include <sys/param.h> | ||||||
| #include <sys/time.h> | #include <sys/time.h> | ||||||
| @@ -128,6 +128,7 @@ enum key_code { | |||||||
|  |  | ||||||
| 	/* Function keys. */ | 	/* Function keys. */ | ||||||
| 	KEYC_F1, | 	KEYC_F1, | ||||||
|  |  | ||||||
| 	KEYC_F2, | 	KEYC_F2, | ||||||
| 	KEYC_F3, | 	KEYC_F3, | ||||||
| 	KEYC_F4, | 	KEYC_F4, | ||||||
| @@ -306,7 +307,8 @@ enum msgtype { | |||||||
| 	MSG_WAKEUP, | 	MSG_WAKEUP, | ||||||
| 	MSG_ENVIRON, | 	MSG_ENVIRON, | ||||||
| 	MSG_UNLOCK, | 	MSG_UNLOCK, | ||||||
| 	MSG_LOCK | 	MSG_LOCK, | ||||||
|  | 	MSG_SHELL | ||||||
| }; | }; | ||||||
|  |  | ||||||
| /* | /* | ||||||
| @@ -346,6 +348,10 @@ struct msg_environ_data { | |||||||
| 	char	     	var[ENVIRON_LENGTH]; | 	char	     	var[ENVIRON_LENGTH]; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | struct msg_shell_data { | ||||||
|  | 	char	       	shell[MAXPATHLEN]; | ||||||
|  | }; | ||||||
|  |  | ||||||
| /* Mode key commands. */ | /* Mode key commands. */ | ||||||
| enum mode_key_cmd { | enum mode_key_cmd { | ||||||
| 	MODEKEY_NONE, | 	MODEKEY_NONE, | ||||||
|   | |||||||
							
								
								
									
										18
									
								
								tty.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								tty.c
									
									
									
									
									
								
							| @@ -1,4 +1,4 @@ | |||||||
| /* $Id: tty.c,v 1.137 2009-09-23 15:08:21 tcunha Exp $ */ | /* $Id: tty.c,v 1.138 2009-09-23 15:18:56 tcunha Exp $ */ | ||||||
|  |  | ||||||
| /* | /* | ||||||
|  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> |  * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> | ||||||
| @@ -44,7 +44,6 @@ void	tty_cell(struct tty *, | |||||||
| void | void | ||||||
| tty_init(struct tty *tty, int fd, char *term) | tty_init(struct tty *tty, int fd, char *term) | ||||||
| { | { | ||||||
| 	int	 mode; |  | ||||||
| 	char	*path; | 	char	*path; | ||||||
|  |  | ||||||
| 	memset(tty, 0, sizeof *tty); | 	memset(tty, 0, sizeof *tty); | ||||||
| @@ -55,10 +54,6 @@ tty_init(struct tty *tty, int fd, char *term) | |||||||
| 	else | 	else | ||||||
| 		tty->termname = xstrdup(term); | 		tty->termname = xstrdup(term); | ||||||
|  |  | ||||||
| 	if ((mode = fcntl(fd, F_GETFL)) == -1) |  | ||||||
| 		fatal("fcntl failed"); |  | ||||||
| 	if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) |  | ||||||
| 		fatal("fcntl failed"); |  | ||||||
| 	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) | 	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) | ||||||
| 		fatal("fcntl failed"); | 		fatal("fcntl failed"); | ||||||
| 	tty->fd = fd; | 	tty->fd = fd; | ||||||
| @@ -129,6 +124,7 @@ void | |||||||
| tty_start_tty(struct tty *tty) | tty_start_tty(struct tty *tty) | ||||||
| { | { | ||||||
| 	struct termios	 tio; | 	struct termios	 tio; | ||||||
|  | 	int		 mode; | ||||||
| #ifdef TIOCFLUSH | #ifdef TIOCFLUSH | ||||||
| 	int		 what; | 	int		 what; | ||||||
| #endif | #endif | ||||||
| @@ -136,6 +132,11 @@ tty_start_tty(struct tty *tty) | |||||||
| 	if (tty->fd == -1) | 	if (tty->fd == -1) | ||||||
| 		return; | 		return; | ||||||
|  |  | ||||||
|  | 	if ((mode = fcntl(tty->fd, F_GETFL)) == -1) | ||||||
|  | 		fatal("fcntl failed"); | ||||||
|  | 	if (fcntl(tty->fd, F_SETFL, mode|O_NONBLOCK) == -1) | ||||||
|  | 		fatal("fcntl failed"); | ||||||
|  |  | ||||||
| #if 0 | #if 0 | ||||||
| 	tty_detect_utf8(tty); | 	tty_detect_utf8(tty); | ||||||
| #endif | #endif | ||||||
| @@ -187,6 +188,7 @@ void | |||||||
| tty_stop_tty(struct tty *tty) | tty_stop_tty(struct tty *tty) | ||||||
| { | { | ||||||
| 	struct winsize	ws; | 	struct winsize	ws; | ||||||
|  | 	int		mode; | ||||||
|  |  | ||||||
| 	if (!(tty->flags & TTY_STARTED)) | 	if (!(tty->flags & TTY_STARTED)) | ||||||
| 		return; | 		return; | ||||||
| @@ -197,6 +199,10 @@ tty_stop_tty(struct tty *tty) | |||||||
| 	 * because the fd is invalid. Things like ssh -t can easily leave us | 	 * because the fd is invalid. Things like ssh -t can easily leave us | ||||||
| 	 * with a dead tty. | 	 * with a dead tty. | ||||||
| 	 */ | 	 */ | ||||||
|  | 	if ((mode = fcntl(tty->fd, F_GETFL)) == -1) | ||||||
|  | 		return; | ||||||
|  | 	if (fcntl(tty->fd, F_SETFL, mode & ~O_NONBLOCK) == -1) | ||||||
|  | 		return; | ||||||
| 	if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) | 	if (ioctl(tty->fd, TIOCGWINSZ, &ws) == -1) | ||||||
| 		return; | 		return; | ||||||
| 	if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) | 	if (tcsetattr(tty->fd, TCSANOW, &tty->tio) == -1) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Tiago Cunha
					Tiago Cunha