mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Sync OpenBSD patchset 433:
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:
		
							
								
								
									
										90
									
								
								client-fn.c
									
									
									
									
									
								
							
							
						
						
									
										90
									
								
								client-fn.c
									
									
									
									
									
								
							@@ -1,90 +0,0 @@
 | 
			
		||||
/* $Id: client-fn.c,v 1.10 2009-08-14 21:04:04 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
 *
 | 
			
		||||
 * Permission to use, copy, modify, and distribute this software for any
 | 
			
		||||
 * purpose with or without fee is hereby granted, provided that the above
 | 
			
		||||
 * copyright notice and this permission notice appear in all copies.
 | 
			
		||||
 *
 | 
			
		||||
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 | 
			
		||||
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 | 
			
		||||
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 | 
			
		||||
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 | 
			
		||||
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
 | 
			
		||||
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
 | 
			
		||||
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/types.h>
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include "tmux.h"
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
client_fill_session(struct msg_command_data *data)
 | 
			
		||||
{
 | 
			
		||||
	char		*env, *ptr1, *ptr2, buf[256];
 | 
			
		||||
	size_t		 len;
 | 
			
		||||
	const char	*errstr;
 | 
			
		||||
	long long	 ll;
 | 
			
		||||
 | 
			
		||||
	data->pid = -1;
 | 
			
		||||
	if ((env = getenv("TMUX")) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((ptr2 = strrchr(env, ',')) == NULL || ptr2 == env)
 | 
			
		||||
		return;
 | 
			
		||||
	for (ptr1 = ptr2 - 1; ptr1 > env && *ptr1 != ','; ptr1--)
 | 
			
		||||
		;
 | 
			
		||||
	if (*ptr1 != ',')
 | 
			
		||||
		return;
 | 
			
		||||
	ptr1++;
 | 
			
		||||
	ptr2++;
 | 
			
		||||
 | 
			
		||||
	len = ptr2 - ptr1 - 1;
 | 
			
		||||
	if (len > (sizeof buf) - 1)
 | 
			
		||||
		return;
 | 
			
		||||
	memcpy(buf, ptr1, len);
 | 
			
		||||
	buf[len] = '\0';
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(buf, 0, LONG_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	data->pid = ll;
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(ptr2, 0, UINT_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	data->idx = ll;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
client_write_server(
 | 
			
		||||
    struct client_ctx *cctx, enum msgtype type, void *buf, size_t len)
 | 
			
		||||
{
 | 
			
		||||
	imsg_compose(&cctx->ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										150
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										150
									
								
								client.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: client.c,v 1.78 2009-10-15 01:51:09 tcunha Exp $ */
 | 
			
		||||
/* $Id: client.c,v 1.79 2009-10-23 17:32:26 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -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;
 | 
			
		||||
@@ -97,10 +103,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)");
 | 
			
		||||
@@ -118,23 +124,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;
 | 
			
		||||
@@ -142,12 +148,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;
 | 
			
		||||
@@ -162,29 +174,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) {
 | 
			
		||||
@@ -199,67 +213,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);
 | 
			
		||||
@@ -270,25 +258,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)
 | 
			
		||||
@@ -300,8 +278,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)
 | 
			
		||||
@@ -316,7 +294,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");
 | 
			
		||||
@@ -325,3 +303,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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										95
									
								
								tmux.c
									
									
									
									
									
								
							
							
						
						
									
										95
									
								
								tmux.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.c,v 1.178 2009-10-11 23:46:02 tcunha Exp $ */
 | 
			
		||||
/* $Id: tmux.c,v 1.179 2009-10-23 17:32:26 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -58,9 +58,10 @@ char		*socket_path;
 | 
			
		||||
int		 login_shell;
 | 
			
		||||
 | 
			
		||||
__dead void	 usage(void);
 | 
			
		||||
void	 	 fill_session(struct msg_command_data *);
 | 
			
		||||
char 		*makesockpath(const char *);
 | 
			
		||||
int		 prepare_cmd(enum msgtype *, void **, size_t *, int, char **);
 | 
			
		||||
int		 dispatch_imsg(struct client_ctx *, const char *, int *);
 | 
			
		||||
int		 dispatch_imsg(struct imsgbuf *, const char *, int *);
 | 
			
		||||
__dead void	 shell_exec(const char *, const char *);
 | 
			
		||||
 | 
			
		||||
#ifndef HAVE_PROGNAME
 | 
			
		||||
@@ -224,6 +225,44 @@ areshell(const char *shell)
 | 
			
		||||
	return (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
fill_session(struct msg_command_data *data)
 | 
			
		||||
{
 | 
			
		||||
	char		*env, *ptr1, *ptr2, buf[256];
 | 
			
		||||
	size_t		 len;
 | 
			
		||||
	const char	*errstr;
 | 
			
		||||
	long long	 ll;
 | 
			
		||||
 | 
			
		||||
	data->pid = -1;
 | 
			
		||||
	if ((env = getenv("TMUX")) == NULL)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if ((ptr2 = strrchr(env, ',')) == NULL || ptr2 == env)
 | 
			
		||||
		return;
 | 
			
		||||
	for (ptr1 = ptr2 - 1; ptr1 > env && *ptr1 != ','; ptr1--)
 | 
			
		||||
		;
 | 
			
		||||
	if (*ptr1 != ',')
 | 
			
		||||
		return;
 | 
			
		||||
	ptr1++;
 | 
			
		||||
	ptr2++;
 | 
			
		||||
 | 
			
		||||
	len = ptr2 - ptr1 - 1;
 | 
			
		||||
	if (len > (sizeof buf) - 1)
 | 
			
		||||
		return;
 | 
			
		||||
	memcpy(buf, ptr1, len);
 | 
			
		||||
	buf[len] = '\0';
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(buf, 0, LONG_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	data->pid = ll;
 | 
			
		||||
 | 
			
		||||
	ll = strtonum(ptr2, 0, UINT_MAX, &errstr);
 | 
			
		||||
	if (errstr != NULL)
 | 
			
		||||
		return;
 | 
			
		||||
	data->idx = ll;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
char *
 | 
			
		||||
makesockpath(const char *label)
 | 
			
		||||
{
 | 
			
		||||
@@ -257,7 +296,7 @@ prepare_cmd(enum msgtype *msg, void **buf, size_t *len, int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	static struct msg_command_data	 cmddata;
 | 
			
		||||
 | 
			
		||||
	client_fill_session(&cmddata);
 | 
			
		||||
	fill_session(&cmddata);
 | 
			
		||||
	
 | 
			
		||||
	cmddata.argc = argc;
 | 
			
		||||
	if (cmd_pack_argv(argc, argv, cmddata.argv, sizeof cmddata.argv) != 0) {
 | 
			
		||||
@@ -275,20 +314,19 @@ prepare_cmd(enum msgtype *msg, void **buf, size_t *len, int argc, char **argv)
 | 
			
		||||
int
 | 
			
		||||
main(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
	struct client_ctx	 cctx;
 | 
			
		||||
	struct cmd_list		*cmdlist;
 | 
			
		||||
 	struct cmd		*cmd;
 | 
			
		||||
	struct pollfd	 	 pfd;
 | 
			
		||||
	enum msgtype		 msg;
 | 
			
		||||
	struct passwd		*pw;
 | 
			
		||||
	struct options		*so, *wo;
 | 
			
		||||
	struct keylist		*keylist;
 | 
			
		||||
	char			*s, *shellcmd, *path, *label, *home, *cause;
 | 
			
		||||
	char			 cwd[MAXPATHLEN], **var;
 | 
			
		||||
	void			*buf;
 | 
			
		||||
	size_t			 len;
 | 
			
		||||
	int	 		 retcode, opt, flags, cmdflags = 0;
 | 
			
		||||
	int			 nfds;
 | 
			
		||||
	struct cmd_list	*cmdlist;
 | 
			
		||||
 	struct cmd	*cmd;
 | 
			
		||||
	struct pollfd	 pfd;
 | 
			
		||||
	enum msgtype	 msg;
 | 
			
		||||
	struct passwd	*pw;
 | 
			
		||||
	struct options	*so, *wo;
 | 
			
		||||
	struct keylist	*keylist;
 | 
			
		||||
	struct imsgbuf	*ibuf;
 | 
			
		||||
	char		*s, *shellcmd, *path, *label, *home, *cause;
 | 
			
		||||
	char		 cwd[MAXPATHLEN], **var;
 | 
			
		||||
	void		*buf;
 | 
			
		||||
	size_t		 len;
 | 
			
		||||
	int	 	 nfds, retcode, opt, flags, cmdflags = 0;
 | 
			
		||||
 | 
			
		||||
	flags = 0;
 | 
			
		||||
	shellcmd = label = path = NULL;
 | 
			
		||||
@@ -527,19 +565,17 @@ main(int argc, char **argv)
 | 
			
		||||
		cmd_list_free(cmdlist);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 	memset(&cctx, 0, sizeof cctx);
 | 
			
		||||
	if (client_init(path, &cctx, cmdflags, flags) != 0)
 | 
			
		||||
	if ((ibuf = client_init(path, cmdflags, flags)) == NULL)
 | 
			
		||||
		exit(1);
 | 
			
		||||
	xfree(path);
 | 
			
		||||
 | 
			
		||||
	client_write_server(&cctx, msg, buf, len);
 | 
			
		||||
	memset(buf, 0, len);
 | 
			
		||||
 	imsg_compose(ibuf, msg, PROTOCOL_VERSION, -1, -1, buf, len);
 | 
			
		||||
 | 
			
		||||
	retcode = 0;
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		pfd.fd = cctx.ibuf.fd;
 | 
			
		||||
		pfd.fd = ibuf->fd;
 | 
			
		||||
		pfd.events = POLLIN;
 | 
			
		||||
		if (cctx.ibuf.w.queued != 0)
 | 
			
		||||
		if (ibuf->w.queued != 0)
 | 
			
		||||
			pfd.events |= POLLOUT;
 | 
			
		||||
 | 
			
		||||
		if ((nfds = poll(&pfd, 1, INFTIM)) == -1) {
 | 
			
		||||
@@ -554,12 +590,12 @@ main(int argc, char **argv)
 | 
			
		||||
			fatalx("socket error");
 | 
			
		||||
 | 
			
		||||
                if (pfd.revents & POLLIN) {
 | 
			
		||||
			if (dispatch_imsg(&cctx, shellcmd, &retcode) != 0)
 | 
			
		||||
			if (dispatch_imsg(ibuf, shellcmd, &retcode) != 0)
 | 
			
		||||
				break;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		if (pfd.revents & POLLOUT) {
 | 
			
		||||
			if (msgbuf_write(&cctx.ibuf.w) < 0)
 | 
			
		||||
			if (msgbuf_write(&ibuf->w) < 0)
 | 
			
		||||
				fatalx("msgbuf_write failed");
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@@ -571,18 +607,18 @@ main(int argc, char **argv)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
dispatch_imsg(struct client_ctx *cctx, const char *shellcmd, int *retcode)
 | 
			
		||||
dispatch_imsg(struct imsgbuf *ibuf, const char *shellcmd, int *retcode)
 | 
			
		||||
{
 | 
			
		||||
	struct imsg		imsg;
 | 
			
		||||
	ssize_t			n, datalen;
 | 
			
		||||
	struct msg_print_data	printdata;
 | 
			
		||||
	struct msg_shell_data	shelldata;
 | 
			
		||||
 | 
			
		||||
        if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0)
 | 
			
		||||
        if ((n = imsg_read(ibuf)) == -1 || n == 0)
 | 
			
		||||
		fatalx("imsg_read failed");
 | 
			
		||||
 | 
			
		||||
	for (;;) {
 | 
			
		||||
		if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1)
 | 
			
		||||
		if ((n = imsg_get(ibuf, &imsg)) == -1)
 | 
			
		||||
			fatalx("imsg_get failed");
 | 
			
		||||
		if (n == 0)
 | 
			
		||||
			return (0);
 | 
			
		||||
@@ -610,8 +646,7 @@ dispatch_imsg(struct client_ctx *cctx, const char *shellcmd, int *retcode)
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
				fatalx("bad MSG_READY size");
 | 
			
		||||
 | 
			
		||||
			*retcode = client_main(cctx);
 | 
			
		||||
			return (-1);
 | 
			
		||||
			client_main();	/* doesn't return */
 | 
			
		||||
		case MSG_VERSION:
 | 
			
		||||
			if (datalen != 0)
 | 
			
		||||
				fatalx("bad MSG_VERSION size");
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										25
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.h,v 1.482 2009-10-23 17:27:40 tcunha Exp $ */
 | 
			
		||||
/* $Id: tmux.h,v 1.483 2009-10-23 17:32:26 tcunha Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -1050,19 +1050,6 @@ struct client {
 | 
			
		||||
};
 | 
			
		||||
ARRAY_DECL(clients, struct client *);
 | 
			
		||||
 | 
			
		||||
/* Client context. */
 | 
			
		||||
struct client_ctx {
 | 
			
		||||
	struct imsgbuf	 ibuf;
 | 
			
		||||
 | 
			
		||||
	enum {
 | 
			
		||||
		CCTX_DETACH,
 | 
			
		||||
		CCTX_EXIT,
 | 
			
		||||
		CCTX_DIED,
 | 
			
		||||
		CCTX_SHUTDOWN
 | 
			
		||||
	} exittype;
 | 
			
		||||
	const char	*errstr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Key/command line command. */
 | 
			
		||||
struct cmd_ctx {
 | 
			
		||||
	/*
 | 
			
		||||
@@ -1501,14 +1488,8 @@ void	cmd_buffer_free(struct cmd *);
 | 
			
		||||
size_t	cmd_buffer_print(struct cmd *, char *, size_t);
 | 
			
		||||
 | 
			
		||||
/* client.c */
 | 
			
		||||
int	 client_init(char *, struct client_ctx *, int, int);
 | 
			
		||||
int	 client_main(struct client_ctx *);
 | 
			
		||||
int	 client_msg_dispatch(struct client_ctx *);
 | 
			
		||||
 | 
			
		||||
/* client-fn.c */
 | 
			
		||||
void	 client_write_server(struct client_ctx *, enum msgtype, void *, size_t);
 | 
			
		||||
void	 client_fill_session(struct msg_command_data *);
 | 
			
		||||
void	 client_suspend(void);
 | 
			
		||||
struct imsgbuf *client_init(char *, int, int);
 | 
			
		||||
__dead void	client_main(void);
 | 
			
		||||
 | 
			
		||||
/* key-bindings.c */
 | 
			
		||||
extern struct key_bindings key_bindings;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user