summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client.c1
-rw-r--r--server-client.c6
-rw-r--r--server.c56
-rw-r--r--tmux.h2
4 files changed, 49 insertions, 16 deletions
diff --git a/client.c b/client.c
index 0a5abf32..6feafc93 100644
--- a/client.c
+++ b/client.c
@@ -452,6 +452,7 @@ client_write(int fd, const char *data, size_t size)
{
ssize_t used;
+ log_debug("%s: %.*s", __func__, (int)size, data);
while (size != 0) {
used = write(fd, data, size);
if (used == -1) {
diff --git a/server-client.c b/server-client.c
index aa0f838e..87f40018 100644
--- a/server-client.c
+++ b/server-client.c
@@ -161,7 +161,7 @@ server_client_is_default_key_table(struct client *c, struct key_table *table)
}
/* Create a new client. */
-void
+struct client *
server_client_create(int fd)
{
struct client *c;
@@ -214,6 +214,7 @@ server_client_create(int fd)
TAILQ_INSERT_TAIL(&clients, c, entry);
log_debug("new client %p", c);
+ return (c);
}
/* Open client terminal if needed. */
@@ -1550,6 +1551,9 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
int argc;
char **argv, *cause;
+ if (c->flags & CLIENT_EXIT)
+ return;
+
if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data)
fatalx("bad MSG_COMMAND size");
memcpy(&data, imsg->data, sizeof data);
diff --git a/server.c b/server.c
index 82b5a6b8..77ee9c36 100644
--- a/server.c
+++ b/server.c
@@ -50,7 +50,6 @@ static struct event server_ev_accept;
struct cmd_find_state marked_pane;
-static int server_create_socket(void);
static int server_loop(void);
static void server_send_exit(void);
static void server_accept(int, short, void *);
@@ -99,39 +98,62 @@ server_check_marked(void)
/* Create server socket. */
static int
-server_create_socket(void)
+server_create_socket(char **cause)
{
struct sockaddr_un sa;
size_t size;
mode_t mask;
- int fd;
+ int fd, saved_errno;
memset(&sa, 0, sizeof sa);
sa.sun_family = AF_UNIX;
size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
if (size >= sizeof sa.sun_path) {
errno = ENAMETOOLONG;
- return (-1);
+ goto fail;
}
unlink(sa.sun_path);
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
- return (-1);
+ goto fail;
mask = umask(S_IXUSR|S_IXGRP|S_IRWXO);
- if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) == -1) {
+ if (bind(fd, (struct sockaddr *)&sa, sizeof sa) == -1) {
+ saved_errno = errno;
close(fd);
- return (-1);
+ errno = saved_errno;
+ goto fail;
}
umask(mask);
if (listen(fd, 128) == -1) {
+ saved_errno = errno;
close(fd);
- return (-1);
+ errno = saved_errno;
+ goto fail;
}
setblocking(fd, 0);
return (fd);
+
+fail:
+ if (cause != NULL) {
+ xasprintf(cause, "error creating %s (%s)", socket_path,
+ strerror(errno));
+ }
+ return (-1);
+}
+
+/* Server error callback. */
+static enum cmd_retval
+server_start_error(struct cmdq_item *item, void *data)
+{
+ char *error = data;
+
+ cmdq_error(item, "%s", error);
+ free(error);
+
+ return (CMD_RETURN_NORMAL);
}
/* Fork new server. */
@@ -142,6 +164,8 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
int pair[2];
struct job *job;
sigset_t set, oldset;
+ struct client *c;
+ char *cause = NULL;
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
fatal("socketpair failed");
@@ -183,11 +207,10 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
gettimeofday(&start_time, NULL);
- server_fd = server_create_socket();
- if (server_fd == -1)
- fatal("couldn't create socket");
- server_update_socket();
- server_client_create(pair[1]);
+ server_fd = server_create_socket(&cause);
+ if (server_fd != -1)
+ server_update_socket();
+ c = server_client_create(pair[1]);
if (lockfd >= 0) {
unlink(lockfile);
@@ -195,6 +218,11 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
close(lockfd);
}
+ if (cause != NULL) {
+ cmdq_append(c, cmdq_get_callback(server_start_error, cause));
+ c->flags |= CLIENT_EXIT;
+ }
+
start_cfg();
server_add_accept(0);
@@ -375,7 +403,7 @@ server_signal(int sig)
break;
case SIGUSR1:
event_del(&server_ev_accept);
- fd = server_create_socket();
+ fd = server_create_socket(NULL);
if (fd != -1) {
close(server_fd);
server_fd = fd;
diff --git a/tmux.h b/tmux.h
index 43d9d846..71fadb08 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1885,7 +1885,7 @@ void server_client_set_key_table(struct client *, const char *);
const char *server_client_get_key_table(struct client *);
int server_client_check_nested(struct client *);
void server_client_handle_key(struct client *, key_code);
-void server_client_create(int);
+struct client *server_client_create(int);
int server_client_open(struct client *, char **);
void server_client_unref(struct client *);
void server_client_lost(struct client *);