mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Client tidying: get rid of client_ctx struct in favour of two variables in
client.c, and move the functions in client-fn.c into other files.
This commit is contained in:
		
							
								
								
									
										148
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										148
									
								
								client.c
									
									
									
									
									
								
							@@ -33,10 +33,16 @@
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
void	client_send_environ(struct client_ctx *);
 | 
			
		||||
struct imsgbuf	client_ibuf;
 | 
			
		||||
const char     *client_exitmsg;
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags)
 | 
			
		||||
void	client_send_environ(void);
 | 
			
		||||
void	client_write_server(enum msgtype, void *, size_t);
 | 
			
		||||
int	client_dispatch(void);
 | 
			
		||||
void	client_suspend(void);
 | 
			
		||||
 | 
			
		||||
struct imsgbuf *
 | 
			
		||||
client_init(char *path, int cmdflags, int flags)
 | 
			
		||||
{
 | 
			
		||||
	struct sockaddr_un		sa;
 | 
			
		||||
	struct stat			sb;
 | 
			
		||||
@@ -93,10 +99,10 @@ server_started:
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	imsg_init(&cctx->ibuf, fd);
 | 
			
		||||
	imsg_init(&client_ibuf, fd);
 | 
			
		||||
 | 
			
		||||
	if (cmdflags & CMD_SENDENVIRON)
 | 
			
		||||
		client_send_environ(cctx);
 | 
			
		||||
		client_send_environ();
 | 
			
		||||
	if (isatty(STDIN_FILENO)) {
 | 
			
		||||
		if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1)
 | 
			
		||||
			fatal("ioctl(TIOCGWINSZ)");
 | 
			
		||||
@@ -114,23 +120,23 @@ server_started:
 | 
			
		||||
 | 
			
		||||
		if ((fd2 = dup(STDIN_FILENO)) == -1)
 | 
			
		||||
			fatal("dup failed");
 | 
			
		||||
		imsg_compose(&cctx->ibuf, MSG_IDENTIFY,
 | 
			
		||||
		imsg_compose(&client_ibuf, MSG_IDENTIFY,
 | 
			
		||||
		    PROTOCOL_VERSION, -1, fd2, &data, sizeof data);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
	return (&client_ibuf);
 | 
			
		||||
 | 
			
		||||
start_failed:
 | 
			
		||||
	log_warnx("server failed to start");
 | 
			
		||||
	return (1);
 | 
			
		||||
	return (NULL);
 | 
			
		||||
 | 
			
		||||
not_found:
 | 
			
		||||
	log_warn("server not found");
 | 
			
		||||
	return (1);
 | 
			
		||||
	return (NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
client_send_environ(struct client_ctx *cctx)
 | 
			
		||||
client_send_environ(void)
 | 
			
		||||
{
 | 
			
		||||
	char		      **var;
 | 
			
		||||
	struct msg_environ_data	data;
 | 
			
		||||
@@ -138,12 +144,18 @@ client_send_environ(struct client_ctx *cctx)
 | 
			
		||||
 	for (var = environ; *var != NULL; var++) {
 | 
			
		||||
		if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var)
 | 
			
		||||
			continue;
 | 
			
		||||
		client_write_server(cctx, MSG_ENVIRON, &data, sizeof data);
 | 
			
		||||
		client_write_server(MSG_ENVIRON, &data, sizeof data);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_main(struct client_ctx *cctx)
 | 
			
		||||
void
 | 
			
		||||
client_write_server(enum msgtype type, void *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
 	imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
__dead void
 | 
			
		||||
client_main(void)
 | 
			
		||||
{
 | 
			
		||||
	struct pollfd	 pfd;
 | 
			
		||||
	int		 n, nfds;
 | 
			
		||||
@@ -158,29 +170,31 @@ client_main(struct client_ctx *cctx)
 | 
			
		||||
	 * MSG_READY switched to here. Process anything outstanding now so poll
 | 
			
		||||
	 * doesn't hang waiting for messages that have already arrived.
 | 
			
		||||
	 */
 | 
			
		||||
	if (client_msg_dispatch(cctx) != 0)
 | 
			
		||||
	if (client_dispatch() != 0)
 | 
			
		||||
		goto out;
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		if (sigterm)
 | 
			
		||||
			client_write_server(cctx, MSG_EXITING, NULL, 0);
 | 
			
		||||
		if (sigterm) {
 | 
			
		||||
			client_exitmsg = "terminated";
 | 
			
		||||
			client_write_server(MSG_EXITING, NULL, 0);
 | 
			
		||||
		}
 | 
			
		||||
		if (sigchld) {
 | 
			
		||||
			waitpid(WAIT_ANY, NULL, WNOHANG);
 | 
			
		||||
			sigchld = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (sigwinch) {
 | 
			
		||||
			client_write_server(cctx, MSG_RESIZE, NULL, 0);
 | 
			
		||||
			client_write_server(MSG_RESIZE, NULL, 0);
 | 
			
		||||
 			sigwinch = 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (sigcont) {
 | 
			
		||||
			siginit();
 | 
			
		||||
			client_write_server(cctx, MSG_WAKEUP, NULL, 0);
 | 
			
		||||
			client_write_server(MSG_WAKEUP, NULL, 0);
 | 
			
		||||
			sigcont = 0;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pfd.fd = cctx->ibuf.fd;
 | 
			
		||||
		pfd.fd = client_ibuf.fd;
 | 
			
		||||
		pfd.events = POLLIN;
 | 
			
		||||
		if (cctx->ibuf.w.queued > 0)
 | 
			
		||||
		if (client_ibuf.w.queued > 0)
 | 
			
		||||
			pfd.events |= POLLOUT;
 | 
			
		||||
 | 
			
		||||
		if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
 | 
			
		||||
@@ -195,67 +209,41 @@ client_main(struct client_ctx *cctx)
 | 
			
		||||
			fatalx("socket error");
 | 
			
		||||
 | 
			
		||||
		if (pfd.revents & POLLIN) {
 | 
			
		||||
			if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) {
 | 
			
		||||
				cctx->exittype = CCTX_DIED;
 | 
			
		||||
			if ((n = imsg_read(&client_ibuf)) == -1 || n == 0) {
 | 
			
		||||
				client_exitmsg = "lost server";
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
			if (client_msg_dispatch(cctx) != 0)
 | 
			
		||||
			if (client_dispatch() != 0)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (pfd.revents & POLLOUT) {
 | 
			
		||||
			if (msgbuf_write(&cctx->ibuf.w) < 0) {
 | 
			
		||||
				cctx->exittype = CCTX_DIED;
 | 
			
		||||
			if (msgbuf_write(&client_ibuf.w) < 0) {
 | 
			
		||||
				client_exitmsg = "lost server";
 | 
			
		||||
				break;
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
	/*
 | 
			
		||||
	 * Print exit status message, unless running as a login shell where it
 | 
			
		||||
	 * would either be pointless or irritating.
 | 
			
		||||
	 */
 | 
			
		||||
	if (sigterm) {
 | 
			
		||||
		printf("[terminated]\n");
 | 
			
		||||
		return (1);
 | 
			
		||||
	}
 | 
			
		||||
	switch (cctx->exittype) {
 | 
			
		||||
	case CCTX_DIED:
 | 
			
		||||
		printf("[lost server]\n");
 | 
			
		||||
		return (0);
 | 
			
		||||
	case CCTX_SHUTDOWN:
 | 
			
		||||
 		if (!login_shell)
 | 
			
		||||
			printf("[server exited]\n");
 | 
			
		||||
		return (0);
 | 
			
		||||
	case CCTX_EXIT:
 | 
			
		||||
		if (cctx->errstr != NULL) {
 | 
			
		||||
			printf("[error: %s]\n", cctx->errstr);
 | 
			
		||||
			return (1);
 | 
			
		||||
		}
 | 
			
		||||
 		if (!login_shell)
 | 
			
		||||
			printf("[exited]\n");
 | 
			
		||||
		return (0);
 | 
			
		||||
	case CCTX_DETACH:
 | 
			
		||||
	/* Print the exit message, if any, and exit. */
 | 
			
		||||
	if (client_exitmsg != NULL) {
 | 
			
		||||
		if (!login_shell)
 | 
			
		||||
			printf("[detached]\n");
 | 
			
		||||
		return (0);
 | 
			
		||||
	default:
 | 
			
		||||
		printf("[unknown error]\n");
 | 
			
		||||
		return (1);
 | 
			
		||||
			printf("[%s]\n", client_exitmsg);
 | 
			
		||||
		exit(1);
 | 
			
		||||
	}
 | 
			
		||||
	exit(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
client_msg_dispatch(struct client_ctx *cctx)
 | 
			
		||||
client_dispatch(void)
 | 
			
		||||
{
 | 
			
		||||
	struct imsg		 imsg;
 | 
			
		||||
	struct msg_print_data	 printdata;
 | 
			
		||||
	struct msg_lock_data	 lockdata;
 | 
			
		||||
	ssize_t			 n, datalen;
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1)
 | 
			
		||||
		if ((n = imsg_get(&client_ibuf, &imsg)) == -1)
 | 
			
		||||
			fatalx("imsg_get failed");
 | 
			
		||||
		if (n == 0)
 | 
			
		||||
			return (0);
 | 
			
		||||
@@ -266,25 +254,15 @@ client_msg_dispatch(struct client_ctx *cctx)
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
				fatalx("bad MSG_DETACH size");
 | 
			
		||||
 | 
			
		||||
			client_write_server(cctx, MSG_EXITING, NULL, 0);
 | 
			
		||||
			cctx->exittype = CCTX_DETACH;
 | 
			
		||||
			client_write_server(MSG_EXITING, NULL, 0);
 | 
			
		||||
			client_exitmsg = "detached";
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_ERROR:
 | 
			
		||||
			if (datalen != sizeof printdata)
 | 
			
		||||
				fatalx("bad MSG_ERROR size");
 | 
			
		||||
			memcpy(&printdata, imsg.data, sizeof printdata);
 | 
			
		||||
 | 
			
		||||
			printdata.msg[(sizeof printdata.msg) - 1] = '\0';
 | 
			
		||||
			/* Error string used after exit message from server. */
 | 
			
		||||
			cctx->errstr = xstrdup(printdata.msg);
 | 
			
		||||
			imsg_free(&imsg);
 | 
			
		||||
			return (-1);
 | 
			
		||||
		case MSG_EXIT:
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
				fatalx("bad MSG_EXIT size");
 | 
			
		||||
 | 
			
		||||
			client_write_server(cctx, MSG_EXITING, NULL, 0);
 | 
			
		||||
			cctx->exittype = CCTX_EXIT;
 | 
			
		||||
			client_write_server(MSG_EXITING, NULL, 0);
 | 
			
		||||
			client_exitmsg = "exited";
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_EXITED:
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
@@ -296,8 +274,8 @@ client_msg_dispatch(struct client_ctx *cctx)
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
				fatalx("bad MSG_SHUTDOWN size");
 | 
			
		||||
 | 
			
		||||
			client_write_server(cctx, MSG_EXITING, NULL, 0);
 | 
			
		||||
			cctx->exittype = CCTX_SHUTDOWN;
 | 
			
		||||
			client_write_server(MSG_EXITING, NULL, 0);
 | 
			
		||||
			client_exitmsg = "server exited";
 | 
			
		||||
			break;
 | 
			
		||||
		case MSG_SUSPEND:
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
@@ -312,7 +290,7 @@ client_msg_dispatch(struct client_ctx *cctx)
 | 
			
		||||
			
 | 
			
		||||
			lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0';
 | 
			
		||||
			system(lockdata.cmd);
 | 
			
		||||
			client_write_server(cctx, MSG_UNLOCK, NULL, 0);
 | 
			
		||||
			client_write_server(MSG_UNLOCK, NULL, 0);
 | 
			
		||||
			break;
 | 
			
		||||
		default:
 | 
			
		||||
			fatalx("unexpected message");
 | 
			
		||||
@@ -321,3 +299,23 @@ client_msg_dispatch(struct client_ctx *cctx)
 | 
			
		||||
		imsg_free(&imsg);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
client_suspend(void)
 | 
			
		||||
{
 | 
			
		||||
	struct sigaction	 act;
 | 
			
		||||
 | 
			
		||||
	memset(&act, 0, sizeof act);
 | 
			
		||||
	sigemptyset(&act.sa_mask);
 | 
			
		||||
	act.sa_flags = SA_RESTART;
 | 
			
		||||
 | 
			
		||||
	act.sa_handler = SIG_DFL;
 | 
			
		||||
	if (sigaction(SIGTSTP, &act, NULL) != 0)
 | 
			
		||||
		fatal("sigaction failed");
 | 
			
		||||
 | 
			
		||||
	act.sa_handler = sighandler;
 | 
			
		||||
	if (sigaction(SIGCONT, &act, NULL) != 0)
 | 
			
		||||
		fatal("sigaction failed");
 | 
			
		||||
 | 
			
		||||
	kill(getpid(), SIGTSTP);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user