mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:44:18 +00:00 
			
		
		
		
	Merge branch 'obsd-master'
This commit is contained in:
		
							
								
								
									
										38
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								client.c
									
									
									
									
									
								
							@@ -35,7 +35,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static struct tmuxproc	*client_proc;
 | 
					static struct tmuxproc	*client_proc;
 | 
				
			||||||
static struct tmuxpeer	*client_peer;
 | 
					static struct tmuxpeer	*client_peer;
 | 
				
			||||||
static int		 client_flags;
 | 
					static uint64_t		 client_flags;
 | 
				
			||||||
static enum {
 | 
					static enum {
 | 
				
			||||||
	CLIENT_EXIT_NONE,
 | 
						CLIENT_EXIT_NONE,
 | 
				
			||||||
	CLIENT_EXIT_DETACHED,
 | 
						CLIENT_EXIT_DETACHED,
 | 
				
			||||||
@@ -247,7 +247,9 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat)
 | 
				
			|||||||
	pid_t			 ppid;
 | 
						pid_t			 ppid;
 | 
				
			||||||
	enum msgtype		 msg;
 | 
						enum msgtype		 msg;
 | 
				
			||||||
	struct termios		 tio, saved_tio;
 | 
						struct termios		 tio, saved_tio;
 | 
				
			||||||
	size_t			 size;
 | 
						size_t			 size, linesize = 0;
 | 
				
			||||||
 | 
						ssize_t			 linelen;
 | 
				
			||||||
 | 
						char			*line = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */
 | 
						/* Ignore SIGCHLD now or daemon() in the server will leave a zombie. */
 | 
				
			||||||
	signal(SIGCHLD, SIG_IGN);
 | 
						signal(SIGCHLD, SIG_IGN);
 | 
				
			||||||
@@ -276,13 +278,14 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat)
 | 
				
			|||||||
			free(pr->error);
 | 
								free(pr->error);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Save the flags. */
 | 
					 | 
				
			||||||
	client_flags = flags;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Create client process structure (starts logging). */
 | 
						/* Create client process structure (starts logging). */
 | 
				
			||||||
	client_proc = proc_start("client");
 | 
						client_proc = proc_start("client");
 | 
				
			||||||
	proc_set_signals(client_proc, client_signal);
 | 
						proc_set_signals(client_proc, client_signal);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Save the flags. */
 | 
				
			||||||
 | 
						client_flags = flags;
 | 
				
			||||||
 | 
						log_debug("flags are %#llx", client_flags);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Initialize the client socket and start the server. */
 | 
						/* Initialize the client socket and start the server. */
 | 
				
			||||||
	fd = client_connect(base, socket_path, client_flags);
 | 
						fd = client_connect(base, socket_path, client_flags);
 | 
				
			||||||
	if (fd == -1) {
 | 
						if (fd == -1) {
 | 
				
			||||||
@@ -408,8 +411,19 @@ client_main(struct event_base *base, int argc, char **argv, int flags, int feat)
 | 
				
			|||||||
			printf("%%exit %s\n", client_exit_message());
 | 
								printf("%%exit %s\n", client_exit_message());
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			printf("%%exit\n");
 | 
								printf("%%exit\n");
 | 
				
			||||||
 | 
							fflush(stdout);
 | 
				
			||||||
 | 
							if (client_flags & CLIENT_CONTROL_WAITEXIT) {
 | 
				
			||||||
 | 
								setvbuf(stdin, NULL, _IOLBF, 0);
 | 
				
			||||||
 | 
								for (;;) {
 | 
				
			||||||
 | 
									linelen = getline(&line, &linesize, stdin);
 | 
				
			||||||
 | 
									if (linelen <= 1)
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								free(line);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		if (client_flags & CLIENT_CONTROLCONTROL) {
 | 
							if (client_flags & CLIENT_CONTROLCONTROL) {
 | 
				
			||||||
			printf("\033\\");
 | 
								printf("\033\\");
 | 
				
			||||||
 | 
								fflush(stdout);
 | 
				
			||||||
			tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
 | 
								tcsetattr(STDOUT_FILENO, TCSAFLUSH, &saved_tio);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (client_exitreason != CLIENT_EXIT_NONE)
 | 
						} else if (client_exitreason != CLIENT_EXIT_NONE)
 | 
				
			||||||
@@ -872,6 +886,13 @@ client_dispatch_wait(struct imsg *imsg)
 | 
				
			|||||||
		client_exitval = 1;
 | 
							client_exitval = 1;
 | 
				
			||||||
		proc_exit(client_proc);
 | 
							proc_exit(client_proc);
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case MSG_FLAGS:
 | 
				
			||||||
 | 
							if (datalen != sizeof client_flags)
 | 
				
			||||||
 | 
								fatalx("bad MSG_FLAGS string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							memcpy(&client_flags, data, sizeof client_flags);
 | 
				
			||||||
 | 
							log_debug("new flags are %#llx", client_flags);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case MSG_SHELL:
 | 
						case MSG_SHELL:
 | 
				
			||||||
		if (datalen == 0 || data[datalen - 1] != '\0')
 | 
							if (datalen == 0 || data[datalen - 1] != '\0')
 | 
				
			||||||
			fatalx("bad MSG_SHELL string");
 | 
								fatalx("bad MSG_SHELL string");
 | 
				
			||||||
@@ -918,6 +939,13 @@ client_dispatch_attached(struct imsg *imsg)
 | 
				
			|||||||
	datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
 | 
						datalen = imsg->hdr.len - IMSG_HEADER_SIZE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (imsg->hdr.type) {
 | 
						switch (imsg->hdr.type) {
 | 
				
			||||||
 | 
						case MSG_FLAGS:
 | 
				
			||||||
 | 
							if (datalen != sizeof client_flags)
 | 
				
			||||||
 | 
								fatalx("bad MSG_FLAGS string");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							memcpy(&client_flags, data, sizeof client_flags);
 | 
				
			||||||
 | 
							log_debug("new flags are %#llx", client_flags);
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	case MSG_DETACH:
 | 
						case MSG_DETACH:
 | 
				
			||||||
	case MSG_DETACHKILL:
 | 
						case MSG_DETACHKILL:
 | 
				
			||||||
		if (datalen == 0 || data[datalen - 1] != '\0')
 | 
							if (datalen == 0 || data[datalen - 1] != '\0')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -695,6 +695,7 @@ control_discard(struct client *c)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	RB_FOREACH(cp, control_panes, &cs->panes)
 | 
						RB_FOREACH(cp, control_panes, &cs->panes)
 | 
				
			||||||
		control_discard_pane(c, cp);
 | 
							control_discard_pane(c, cp);
 | 
				
			||||||
 | 
						bufferevent_disable(cs->read_event, EV_READ);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Stop control mode. */
 | 
					/* Stop control mode. */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,7 +103,8 @@ screen_write_redraw_cb(const struct tty_ctx *ttyctx)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
	struct window_pane	*wp = ttyctx->arg;
 | 
						struct window_pane	*wp = ttyctx->arg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wp->flags |= PANE_REDRAW;
 | 
						if (wp != NULL)
 | 
				
			||||||
 | 
							wp->flags |= PANE_REDRAW;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Update context for client. */
 | 
					/* Update context for client. */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2372,6 +2372,8 @@ server_client_control_flags(struct client *c, const char *next)
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	if (strcmp(next, "no-output") == 0)
 | 
						if (strcmp(next, "no-output") == 0)
 | 
				
			||||||
		return (CLIENT_CONTROL_NOOUTPUT);
 | 
							return (CLIENT_CONTROL_NOOUTPUT);
 | 
				
			||||||
 | 
						if (strcmp(next, "wait-exit") == 0)
 | 
				
			||||||
 | 
							return (CLIENT_CONTROL_WAITEXIT);
 | 
				
			||||||
	return (0);
 | 
						return (0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2411,6 +2413,7 @@ server_client_set_flags(struct client *c, const char *flags)
 | 
				
			|||||||
			control_reset_offsets(c);
 | 
								control_reset_offsets(c);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	free(copy);
 | 
						free(copy);
 | 
				
			||||||
 | 
						proc_send(c->peer, MSG_FLAGS, -1, &c->flags, sizeof c->flags);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get client flags. This is only flags useful to show to users. */
 | 
					/* Get client flags. This is only flags useful to show to users. */
 | 
				
			||||||
@@ -2429,6 +2432,8 @@ server_client_get_flags(struct client *c)
 | 
				
			|||||||
		strlcat(s, "ignore-size,", sizeof s);
 | 
							strlcat(s, "ignore-size,", sizeof s);
 | 
				
			||||||
	if (c->flags & CLIENT_CONTROL_NOOUTPUT)
 | 
						if (c->flags & CLIENT_CONTROL_NOOUTPUT)
 | 
				
			||||||
		strlcat(s, "no-output,", sizeof s);
 | 
							strlcat(s, "no-output,", sizeof s);
 | 
				
			||||||
 | 
						if (c->flags & CLIENT_CONTROL_WAITEXIT)
 | 
				
			||||||
 | 
							strlcat(s, "wait-exit,", sizeof s);
 | 
				
			||||||
	if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
 | 
						if (c->flags & CLIENT_CONTROL_PAUSEAFTER) {
 | 
				
			||||||
		xsnprintf(tmp, sizeof tmp, "pause-after=%u,",
 | 
							xsnprintf(tmp, sizeof tmp, "pause-after=%u,",
 | 
				
			||||||
		    c->pause_age / 1000);
 | 
							    c->pause_age / 1000);
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								server.c
									
									
									
									
									
								
							@@ -44,7 +44,7 @@ struct clients		 clients;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
struct tmuxproc		*server_proc;
 | 
					struct tmuxproc		*server_proc;
 | 
				
			||||||
static int		 server_fd = -1;
 | 
					static int		 server_fd = -1;
 | 
				
			||||||
static int		 server_client_flags;
 | 
					static uint64_t		 server_client_flags;
 | 
				
			||||||
static int		 server_exit;
 | 
					static int		 server_exit;
 | 
				
			||||||
static struct event	 server_ev_accept;
 | 
					static struct event	 server_ev_accept;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								tmux.1
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.1
									
									
									
									
									
								
							@@ -989,6 +989,8 @@ output is paused once the pane is
 | 
				
			|||||||
behind in control mode
 | 
					behind in control mode
 | 
				
			||||||
.It read-only
 | 
					.It read-only
 | 
				
			||||||
the client is read-only
 | 
					the client is read-only
 | 
				
			||||||
 | 
					.It wait-exit
 | 
				
			||||||
 | 
					wait for an empty line input before exiting in control mode
 | 
				
			||||||
.El
 | 
					.El
 | 
				
			||||||
.Pp
 | 
					.Pp
 | 
				
			||||||
A leading
 | 
					A leading
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								tmux.h
									
									
									
									
									
								
							@@ -517,6 +517,7 @@ enum msgtype {
 | 
				
			|||||||
	MSG_UNLOCK,
 | 
						MSG_UNLOCK,
 | 
				
			||||||
	MSG_WAKEUP,
 | 
						MSG_WAKEUP,
 | 
				
			||||||
	MSG_EXEC,
 | 
						MSG_EXEC,
 | 
				
			||||||
 | 
						MSG_FLAGS,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	MSG_READ_OPEN = 300,
 | 
						MSG_READ_OPEN = 300,
 | 
				
			||||||
	MSG_READ,
 | 
						MSG_READ,
 | 
				
			||||||
@@ -1646,6 +1647,7 @@ struct client {
 | 
				
			|||||||
#define CLIENT_NOFORK 0x40000000
 | 
					#define CLIENT_NOFORK 0x40000000
 | 
				
			||||||
#define CLIENT_ACTIVEPANE 0x80000000ULL
 | 
					#define CLIENT_ACTIVEPANE 0x80000000ULL
 | 
				
			||||||
#define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL
 | 
					#define CLIENT_CONTROL_PAUSEAFTER 0x100000000ULL
 | 
				
			||||||
 | 
					#define CLIENT_CONTROL_WAITEXIT 0x200000000ULL
 | 
				
			||||||
#define CLIENT_ALLREDRAWFLAGS		\
 | 
					#define CLIENT_ALLREDRAWFLAGS		\
 | 
				
			||||||
	(CLIENT_REDRAWWINDOW|		\
 | 
						(CLIENT_REDRAWWINDOW|		\
 | 
				
			||||||
	 CLIENT_REDRAWSTATUS|		\
 | 
						 CLIENT_REDRAWSTATUS|		\
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user