From 5f6a351df72f76f98ee1ed3494d025fe591fdb69 Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Mon, 19 Jan 2009 17:16:09 +0000 Subject: [PATCH] Start the first client with a special socketpair so it is already known to the server rather than playing silly games to get them synchronised before doing anything. Change attach-session to start the server. --- CHANGES | 8 +++- client.c | 36 +++++++------- cmd-attach-session.c | 10 ++-- server.c | 111 +++++++++++++++++++++---------------------- tmux.1 | 7 ++- tmux.h | 3 +- 6 files changed, 92 insertions(+), 83 deletions(-) diff --git a/CHANGES b/CHANGES index 3ae25c62..92cc08bf 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,9 @@ +19 January 2009 + +* attach-session now tries to start the server if it isn't already started - if + no sessions are created in .tmux.conf this will cause an error. +* Clean up starting server by making initial client get a special socketpair. + 18 January 2009 * Unbreak UTF-8. @@ -958,7 +964,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.220 2009-01-18 21:46:30 nicm Exp $ +$Id: CHANGES,v 1.221 2009-01-19 17:16:09 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms diff --git a/client.c b/client.c index e30e1841..fa51727c 100644 --- a/client.c +++ b/client.c @@ -1,4 +1,4 @@ -/* $Id: client.c,v 1.40 2009-01-18 12:09:42 nicm Exp $ */ +/* $Id: client.c,v 1.41 2009-01-19 17:16:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -44,23 +44,20 @@ client_init( struct winsize ws; size_t size; int mode; - u_int retries; struct buffer *b; char *name; - retries = 0; -retry: if (stat(path, &sb) != 0) { if (start_server && errno == ENOENT) { - if (server_start(path) != 0) - goto no_start; - goto retry; + if ((cctx->srv_fd = server_start(path)) == -1) + goto start_failed; + goto server_started; } - goto fail; + goto not_found; } if (!S_ISSOCK(sb.st_mode)) { errno = ENOTSOCK; - goto fail; + goto not_found; } memset(&sa, 0, sizeof sa); @@ -68,7 +65,7 @@ retry: size = strlcpy(sa.sun_path, path, sizeof sa.sun_path); if (size >= sizeof sa.sun_path) { errno = ENAMETOOLONG; - goto fail; + goto not_found; } if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) @@ -76,16 +73,17 @@ retry: if (connect( cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) { - if (start_server && errno == ECONNREFUSED && retries < 10) { - if (unlink(path) != 0) - goto fail; - if (server_start(path) != 0) - goto no_start; + if (errno == ECONNREFUSED) { + if (unlink(path) != 0 || !start_server) + goto not_found; + if ((cctx->srv_fd = server_start(path)) == -1) + goto start_failed; + goto server_started; } - retries++; - goto retry; + goto not_found; } +server_started: if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1) fatal("fcntl"); if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1) @@ -118,11 +116,11 @@ retry: return (0); -no_start: +start_failed: log_warnx("server failed to start"); return (1); -fail: +not_found: log_warn("server not found"); return (1); } diff --git a/cmd-attach-session.c b/cmd-attach-session.c index b622aaab..2686563a 100644 --- a/cmd-attach-session.c +++ b/cmd-attach-session.c @@ -1,4 +1,4 @@ -/* $Id: cmd-attach-session.c,v 1.21 2008-12-10 20:25:41 nicm Exp $ */ +/* $Id: cmd-attach-session.c,v 1.22 2009-01-19 17:16:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -29,7 +29,7 @@ void cmd_attach_session_exec(struct cmd *, struct cmd_ctx *); const struct cmd_entry cmd_attach_session_entry = { "attach-session", "attach", "[-d] " CMD_TARGET_SESSION_USAGE, - CMD_DFLAG|CMD_CANTNEST, + CMD_DFLAG|CMD_CANTNEST|CMD_STARTSERVER, cmd_target_init, cmd_target_parse, cmd_attach_session_exec, @@ -45,10 +45,14 @@ cmd_attach_session_exec(struct cmd *self, struct cmd_ctx *ctx) struct cmd_target_data *data = self->data; struct session *s; char *cause; - + if (ctx->curclient != NULL) return; + if (ARRAY_LENGTH(&sessions) == 0) { + ctx->error(ctx, "no sessions"); + return; + } if ((s = cmd_find_session(ctx, data->target)) == NULL) return; diff --git a/server.c b/server.c index 37a3986f..d60879cb 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.108 2009-01-18 14:40:48 nicm Exp $ */ +/* $Id: server.c,v 1.109 2009-01-19 17:16:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -58,6 +58,51 @@ void server_check_timers(struct client *); void server_second_timers(void); int server_update_socket(const char *); +/* Create a new client. */ +struct client * +server_create_client(int fd) +{ + struct client *c; + int mode; + u_int i; + + if ((mode = fcntl(fd, F_GETFL)) == -1) + fatal("fcntl failed"); + if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) + fatal("fcntl failed"); + + c = xcalloc(1, sizeof *c); + c->fd = fd; + c->in = buffer_create(BUFSIZ); + c->out = buffer_create(BUFSIZ); + + ARRAY_INIT(&c->prompt_hdata); + + c->tty.fd = -1; + c->title = NULL; + + c->session = NULL; + c->sx = 80; + c->sy = 25; + screen_init(&c->status, c->sx, 1, 0); + + c->message_string = NULL; + + c->prompt_string = NULL; + c->prompt_buffer = NULL; + c->prompt_index = 0; + + for (i = 0; i < ARRAY_LENGTH(&clients); i++) { + if (ARRAY_ITEM(&clients, i) == NULL) { + ARRAY_SET(&clients, i, c); + return (c); + } + } + ARRAY_ADD(&clients, c); + return (c); +} + +/* Find client index. */ int server_client_index(struct client *c) { @@ -79,9 +124,8 @@ server_start(const char *path) mode_t mask; int n, fd, pair[2], mode; char *cause; - u_char ch; - /* Make a little socketpair to wait for the server to be ready. */ + /* The first client is special and gets a socketpair; create it. */ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) fatal("socketpair failed"); @@ -92,17 +136,7 @@ server_start(const char *path) break; default: close(pair[1]); - - ch = 0x00; - if (read(pair[0], &ch, 1) == 1 && ch == 0xff) { - close(pair[0]); - return (0); - } - ch = 0x00; - if (write(pair[1], &ch, 1) != 1) - fatal("write failed"); - close(pair[0]); - return (1); + return (pair[0]); } close(pair[0]); @@ -166,11 +200,7 @@ server_start(const char *path) if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) fatal("fcntl failed"); - ch = 0xff; - if (write(pair[1], &ch, 1) != 1) - fatal("write failed"); - read(pair[1], &ch, 1); /* Ignore errors; just to wait before closing. */ - close(pair[1]); + server_create_client(pair[1]); n = server_main(path, fd); #ifdef DEBUG @@ -532,52 +562,17 @@ server_handle_clients(struct pollfd **pfd) struct client * server_accept_client(int srv_fd) { - struct client *c; struct sockaddr_storage sa; socklen_t slen = sizeof sa; - int client_fd, mode; - u_int i; + int fd; - client_fd = accept(srv_fd, (struct sockaddr *) &sa, &slen); - if (client_fd == -1) { + fd = accept(srv_fd, (struct sockaddr *) &sa, &slen); + if (fd == -1) { if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED) return (NULL); fatal("accept failed"); } - if ((mode = fcntl(client_fd, F_GETFL)) == -1) - fatal("fcntl failed"); - if (fcntl(client_fd, F_SETFL, mode|O_NONBLOCK) == -1) - fatal("fcntl failed"); - - c = xcalloc(1, sizeof *c); - c->fd = client_fd; - c->in = buffer_create(BUFSIZ); - c->out = buffer_create(BUFSIZ); - - ARRAY_INIT(&c->prompt_hdata); - - c->tty.fd = -1; - c->title = NULL; - - c->session = NULL; - c->sx = 80; - c->sy = 25; - screen_init(&c->status, c->sx, 1, 0); - - c->message_string = NULL; - - c->prompt_string = NULL; - c->prompt_buffer = NULL; - c->prompt_index = 0; - - for (i = 0; i < ARRAY_LENGTH(&clients); i++) { - if (ARRAY_ITEM(&clients, i) == NULL) { - ARRAY_SET(&clients, i, c); - return (c); - } - } - ARRAY_ADD(&clients, c); - return (c); + return (server_create_client(fd)); } /* Input data from client. */ diff --git a/tmux.1 b/tmux.1 index ec064be9..ff00a812 100644 --- a/tmux.1 +++ b/tmux.1 @@ -1,4 +1,4 @@ -.\" $Id: tmux.1,v 1.66 2009-01-17 17:16:31 nicm Exp $ +.\" $Id: tmux.1,v 1.67 2009-01-19 17:16:09 nicm Exp $ .\" .\" Copyright (c) 2007 Nicholas Marriott .\" @@ -345,6 +345,11 @@ Create a new client in the current terminal and attach it to a session. If .Fl d is specified, any other clients attached to the session are detached. +.Pp +If no server is started, +.It attach-session +will attempt to start it; this will fail unless sessions are created in the +configuration file. .It Xo Ic bind-key .Ar key Ar command Op Ar arguments .Xc diff --git a/tmux.h b/tmux.h index 8d99927e..4dff2bdd 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.241 2009-01-18 21:46:30 nicm Exp $ */ +/* $Id: tmux.h,v 1.242 2009-01-19 17:16:09 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -1253,6 +1253,7 @@ const char *key_string_lookup_key(int); /* server.c */ extern struct clients clients; +struct client *server_create_client(int); int server_client_index(struct client *); int server_start(const char *);