summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Marriott <nicholas.marriott@gmail.com>2008-06-07 07:27:28 +0000
committerNicholas Marriott <nicholas.marriott@gmail.com>2008-06-07 07:27:28 +0000
commitd51f075a4e71cbde5f25cd22cf07d0b7691d4c6c (patch)
tree0ca61a4abde7bd4d524dee67ed15dee37fe9f5f8
parent958069575dc663595d37a37a8273db73a4e99aa1 (diff)
Use a socketpair to synchronise server startup.
-rw-r--r--client.c19
-rw-r--r--server.c32
-rw-r--r--session.c4
-rw-r--r--status.c4
-rw-r--r--tmux.h4
5 files changed, 41 insertions, 22 deletions
diff --git a/client.c b/client.c
index 59e69875..49041461 100644
--- a/client.c
+++ b/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);
diff --git a/server.c b/server.c
index 12f12d53..b43f107c 100644
--- a/server.c
+++ b/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;
+
+ /* 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 (pid = fork()) {
+ 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
diff --git a/session.c b/session.c
index 8ab0c819..9ee9941e 100644
--- a/session.c
+++ b/session.c
@@ -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);
diff --git a/status.c b/status.c
index 4e950d76..e897b6bd 100644
--- a/status.c
+++ b/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)));
diff --git a/tmux.h b/tmux.h
index b4d285db..84e0b14e 100644
--- a/tmux.h
+++ b/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 *);