mirror of
				https://github.com/tmux/tmux.git
				synced 2025-11-04 09:26:05 +00:00 
			
		
		
		
	Use a socketpair to synchronise server startup.
This commit is contained in:
		
							
								
								
									
										19
									
								
								client.c
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								client.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: client.c,v 1.28 2008-06-02 21:08:36 nicm Exp $ */
 | 
			
		||||
/* $Id: client.c,v 1.29 2008-06-07 07:27:28 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -51,11 +51,9 @@ client_init(const char *path, struct client_ctx *cctx, int start_server)
 | 
			
		||||
	retries = 0;
 | 
			
		||||
retry:
 | 
			
		||||
	if (stat(path, &sb) != 0) {
 | 
			
		||||
		if (start_server && errno == ENOENT && retries < 10) {
 | 
			
		||||
			if (pid == 0)
 | 
			
		||||
				pid = server_start(path);
 | 
			
		||||
			usleep(10000);
 | 
			
		||||
			retries++;
 | 
			
		||||
		if (start_server && errno == ENOENT) {
 | 
			
		||||
			if (server_start(path) != 0)
 | 
			
		||||
				goto no_start;
 | 
			
		||||
			goto retry;
 | 
			
		||||
		}
 | 
			
		||||
		goto fail;
 | 
			
		||||
@@ -81,9 +79,8 @@ retry:
 | 
			
		||||
		if (start_server && errno == ECONNREFUSED && retries < 10) {
 | 
			
		||||
			if (unlink(path) != 0)
 | 
			
		||||
				goto fail;
 | 
			
		||||
			usleep(10000);
 | 
			
		||||
			retries++;
 | 
			
		||||
			goto retry;
 | 
			
		||||
			if (server_start(path) != 0)
 | 
			
		||||
				goto no_start;
 | 
			
		||||
		}
 | 
			
		||||
		goto fail;
 | 
			
		||||
	}
 | 
			
		||||
@@ -112,6 +109,10 @@ retry:
 | 
			
		||||
 | 
			
		||||
	return (0);
 | 
			
		||||
 | 
			
		||||
no_start:
 | 
			
		||||
	log_warnx("server failed to start");
 | 
			
		||||
	return (1);
 | 
			
		||||
 | 
			
		||||
fail:
 | 
			
		||||
	log_warn("server not found");
 | 
			
		||||
	return (1);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								server.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								server.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: server.c,v 1.58 2008-06-07 07:13:08 nicm Exp $ */
 | 
			
		||||
/* $Id: server.c,v 1.59 2008-06-07 07:27:28 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -58,24 +58,37 @@ void		 server_check_redraw(struct client *);
 | 
			
		||||
void		 server_check_status(struct client *);
 | 
			
		||||
 | 
			
		||||
/* Fork new server. */
 | 
			
		||||
pid_t
 | 
			
		||||
int
 | 
			
		||||
server_start(const char *path)
 | 
			
		||||
{
 | 
			
		||||
	struct sockaddr_un	sa;
 | 
			
		||||
	size_t			size;
 | 
			
		||||
	mode_t			mask;
 | 
			
		||||
	int		   	n, fd, mode;
 | 
			
		||||
	pid_t			pid;
 | 
			
		||||
	int		   	n, fd, pair[2], mode;
 | 
			
		||||
	char		       *cause;
 | 
			
		||||
	u_char			ch;
 | 
			
		||||
 | 
			
		||||
	switch (pid = fork()) {
 | 
			
		||||
	/* Make a little socketpair to wait for the server to be ready. */
 | 
			
		||||
	if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
 | 
			
		||||
		fatal("socketpair failed");
 | 
			
		||||
 | 
			
		||||
	switch (fork()) {
 | 
			
		||||
	case -1:
 | 
			
		||||
		fatal("fork");
 | 
			
		||||
		fatal("fork failed");
 | 
			
		||||
	case 0:
 | 
			
		||||
		break;
 | 
			
		||||
	default:
 | 
			
		||||
		return (pid);
 | 
			
		||||
		close(pair[1]);
 | 
			
		||||
 | 
			
		||||
		ch = 0;
 | 
			
		||||
		if (read(pair[0], &ch, 1) == 1 && ch == 0xff) {
 | 
			
		||||
			close(pair[0]);
 | 
			
		||||
			return (0);
 | 
			
		||||
		}
 | 
			
		||||
		close(pair[0]);
 | 
			
		||||
		return (1);
 | 
			
		||||
	}
 | 
			
		||||
	close(pair[0]);
 | 
			
		||||
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
	xmalloc_clear();
 | 
			
		||||
@@ -130,6 +143,11 @@ server_start(const char *path)
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
	if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
 | 
			
		||||
		fatal("fcntl failed");
 | 
			
		||||
 | 
			
		||||
	ch = 0xff;
 | 
			
		||||
	if (write(pair[1], &ch, 1) != 1)
 | 
			
		||||
		fatal("write failed");
 | 
			
		||||
	/* Don't close the socketpair fd on success. */
 | 
			
		||||
	
 | 
			
		||||
	n = server_main(path, fd);
 | 
			
		||||
#ifdef DEBUG
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: session.c,v 1.36 2008-06-06 17:55:27 nicm Exp $ */
 | 
			
		||||
/* $Id: session.c,v 1.37 2008-06-07 07:27:28 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -116,7 +116,7 @@ session_create(const char *name, const char *cmd, u_int sx, u_int sy)
 | 
			
		||||
 | 
			
		||||
	s = xmalloc(sizeof *s);
 | 
			
		||||
	if (clock_gettime(CLOCK_REALTIME, &s->ts) != 0)
 | 
			
		||||
		fatal("clock_gettime");
 | 
			
		||||
		fatal("clock_gettime failed");
 | 
			
		||||
	s->curw = s->lastw = NULL;
 | 
			
		||||
	RB_INIT(&s->windows);
 | 
			
		||||
	TAILQ_INIT(&s->alerts);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								status.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								status.c
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: status.c,v 1.23 2008-06-07 06:13:21 nicm Exp $ */
 | 
			
		||||
/* $Id: status.c,v 1.24 2008-06-07 07:27:28 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -43,7 +43,7 @@ status_write_client(struct client *c)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (clock_gettime(CLOCK_REALTIME, &c->status_ts) != 0)
 | 
			
		||||
		fatal("clock_gettime");
 | 
			
		||||
		fatal("clock_gettime failed");
 | 
			
		||||
 | 
			
		||||
	left = options_get_string(&c->session->options, "status-left");
 | 
			
		||||
	strftime(lbuf, sizeof lbuf, left, localtime(&(c->status_ts.tv_sec)));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								tmux.h
									
									
									
									
									
								
							@@ -1,4 +1,4 @@
 | 
			
		||||
/* $Id: tmux.h,v 1.138 2008-06-07 07:13:08 nicm Exp $ */
 | 
			
		||||
/* $Id: tmux.h,v 1.139 2008-06-07 07:27:28 nicm Exp $ */
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
 | 
			
		||||
@@ -895,7 +895,7 @@ const char *key_string_lookup_key(int);
 | 
			
		||||
 | 
			
		||||
/* server.c */
 | 
			
		||||
extern struct clients clients;
 | 
			
		||||
pid_t	 server_start(const char *);
 | 
			
		||||
int	 server_start(const char *);
 | 
			
		||||
 | 
			
		||||
/* server-msg.c */
 | 
			
		||||
int	 server_msg_dispatch(struct client *);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user