=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/tmux/server.c,v retrieving revision 1.177 retrieving revision 1.178 diff -u -r1.177 -r1.178 --- src/usr.bin/tmux/server.c 2017/10/12 11:32:27 1.177 +++ src/usr.bin/tmux/server.c 2017/12/19 15:00:39 1.178 @@ -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 @@ -50,7 +50,6 @@ 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,41 +98,64 @@ /* 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. */ int server_start(struct tmuxproc *client, struct event_base *base, int lockfd, @@ -142,6 +164,8 @@ 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 @@ 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 @@ 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 @@ 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;