Report better error from server when socket create fails, GitHub issue
authornicm <nicm@openbsd.org>
Tue, 19 Dec 2017 15:00:39 +0000 (15:00 +0000)
committernicm <nicm@openbsd.org>
Tue, 19 Dec 2017 15:00:39 +0000 (15:00 +0000)
1201.

usr.bin/tmux/client.c
usr.bin/tmux/server-client.c
usr.bin/tmux/server.c
usr.bin/tmux/tmux.h

index 152b9c8..bba7cfd 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: client.c,v 1.124 2017/12/18 22:13:36 nicm Exp $ */
+/* $OpenBSD: client.c,v 1.125 2017/12/19 15:00:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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) {
index 4db6fc3..6f90ae3 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server-client.c,v 1.245 2017/10/16 19:30:53 nicm Exp $ */
+/* $OpenBSD: server-client.c,v 1.246 2017/12/19 15:00:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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);
index 4bbb187..138c06f 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: server.c,v 1.177 2017/10/12 11:32:27 nicm Exp $ */
+/* $OpenBSD: server.c,v 1.178 2017/12/19 15:00:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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;
index 81fd52f..d175a44 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: tmux.h,v 1.814 2017/11/15 19:59:27 nicm Exp $ */
+/* $OpenBSD: tmux.h,v 1.815 2017/12/19 15:00:39 nicm Exp $ */
 
 /*
  * Copyright (c) 2007 Nicholas Marriott <nicholas.marriott@gmail.com>
@@ -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 *);