mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
Report better error from server when socket create fails, GitHub issue
1201.
This commit is contained in:
parent
62144b9f57
commit
b20a00f93e
1
client.c
1
client.c
@ -452,6 +452,7 @@ client_write(int fd, const char *data, size_t size)
|
|||||||
{
|
{
|
||||||
ssize_t used;
|
ssize_t used;
|
||||||
|
|
||||||
|
log_debug("%s: %.*s", __func__, (int)size, data);
|
||||||
while (size != 0) {
|
while (size != 0) {
|
||||||
used = write(fd, data, size);
|
used = write(fd, data, size);
|
||||||
if (used == -1) {
|
if (used == -1) {
|
||||||
|
@ -161,7 +161,7 @@ server_client_is_default_key_table(struct client *c, struct key_table *table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new client. */
|
/* Create a new client. */
|
||||||
void
|
struct client *
|
||||||
server_client_create(int fd)
|
server_client_create(int fd)
|
||||||
{
|
{
|
||||||
struct client *c;
|
struct client *c;
|
||||||
@ -214,6 +214,7 @@ server_client_create(int fd)
|
|||||||
|
|
||||||
TAILQ_INSERT_TAIL(&clients, c, entry);
|
TAILQ_INSERT_TAIL(&clients, c, entry);
|
||||||
log_debug("new client %p", c);
|
log_debug("new client %p", c);
|
||||||
|
return (c);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Open client terminal if needed. */
|
/* Open client terminal if needed. */
|
||||||
@ -1550,6 +1551,9 @@ server_client_dispatch_command(struct client *c, struct imsg *imsg)
|
|||||||
int argc;
|
int argc;
|
||||||
char **argv, *cause;
|
char **argv, *cause;
|
||||||
|
|
||||||
|
if (c->flags & CLIENT_EXIT)
|
||||||
|
return;
|
||||||
|
|
||||||
if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data)
|
if (imsg->hdr.len - IMSG_HEADER_SIZE < sizeof data)
|
||||||
fatalx("bad MSG_COMMAND size");
|
fatalx("bad MSG_COMMAND size");
|
||||||
memcpy(&data, imsg->data, sizeof data);
|
memcpy(&data, imsg->data, sizeof data);
|
||||||
|
54
server.c
54
server.c
@ -50,7 +50,6 @@ static struct event server_ev_accept;
|
|||||||
|
|
||||||
struct cmd_find_state marked_pane;
|
struct cmd_find_state marked_pane;
|
||||||
|
|
||||||
static int server_create_socket(void);
|
|
||||||
static int server_loop(void);
|
static int server_loop(void);
|
||||||
static void server_send_exit(void);
|
static void server_send_exit(void);
|
||||||
static void server_accept(int, short, void *);
|
static void server_accept(int, short, void *);
|
||||||
@ -99,39 +98,62 @@ server_check_marked(void)
|
|||||||
|
|
||||||
/* Create server socket. */
|
/* Create server socket. */
|
||||||
static int
|
static int
|
||||||
server_create_socket(void)
|
server_create_socket(char **cause)
|
||||||
{
|
{
|
||||||
struct sockaddr_un sa;
|
struct sockaddr_un sa;
|
||||||
size_t size;
|
size_t size;
|
||||||
mode_t mask;
|
mode_t mask;
|
||||||
int fd;
|
int fd, saved_errno;
|
||||||
|
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&sa, 0, sizeof sa);
|
||||||
sa.sun_family = AF_UNIX;
|
sa.sun_family = AF_UNIX;
|
||||||
size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
|
size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path);
|
||||||
if (size >= sizeof sa.sun_path) {
|
if (size >= sizeof sa.sun_path) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
return (-1);
|
goto fail;
|
||||||
}
|
}
|
||||||
unlink(sa.sun_path);
|
unlink(sa.sun_path);
|
||||||
|
|
||||||
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||||
return (-1);
|
goto fail;
|
||||||
|
|
||||||
mask = umask(S_IXUSR|S_IXGRP|S_IRWXO);
|
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);
|
close(fd);
|
||||||
return (-1);
|
errno = saved_errno;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
umask(mask);
|
umask(mask);
|
||||||
|
|
||||||
if (listen(fd, 128) == -1) {
|
if (listen(fd, 128) == -1) {
|
||||||
|
saved_errno = errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
return (-1);
|
errno = saved_errno;
|
||||||
|
goto fail;
|
||||||
}
|
}
|
||||||
setblocking(fd, 0);
|
setblocking(fd, 0);
|
||||||
|
|
||||||
return (fd);
|
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. */
|
/* Fork new server. */
|
||||||
@ -142,6 +164,8 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
|
|||||||
int pair[2];
|
int pair[2];
|
||||||
struct job *job;
|
struct job *job;
|
||||||
sigset_t set, oldset;
|
sigset_t set, oldset;
|
||||||
|
struct client *c;
|
||||||
|
char *cause = NULL;
|
||||||
|
|
||||||
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
|
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
|
||||||
fatal("socketpair failed");
|
fatal("socketpair failed");
|
||||||
@ -183,11 +207,10 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
|
|||||||
|
|
||||||
gettimeofday(&start_time, NULL);
|
gettimeofday(&start_time, NULL);
|
||||||
|
|
||||||
server_fd = server_create_socket();
|
server_fd = server_create_socket(&cause);
|
||||||
if (server_fd == -1)
|
if (server_fd != -1)
|
||||||
fatal("couldn't create socket");
|
|
||||||
server_update_socket();
|
server_update_socket();
|
||||||
server_client_create(pair[1]);
|
c = server_client_create(pair[1]);
|
||||||
|
|
||||||
if (lockfd >= 0) {
|
if (lockfd >= 0) {
|
||||||
unlink(lockfile);
|
unlink(lockfile);
|
||||||
@ -195,6 +218,11 @@ server_start(struct tmuxproc *client, struct event_base *base, int lockfd,
|
|||||||
close(lockfd);
|
close(lockfd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cause != NULL) {
|
||||||
|
cmdq_append(c, cmdq_get_callback(server_start_error, cause));
|
||||||
|
c->flags |= CLIENT_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
start_cfg();
|
start_cfg();
|
||||||
|
|
||||||
server_add_accept(0);
|
server_add_accept(0);
|
||||||
@ -375,7 +403,7 @@ server_signal(int sig)
|
|||||||
break;
|
break;
|
||||||
case SIGUSR1:
|
case SIGUSR1:
|
||||||
event_del(&server_ev_accept);
|
event_del(&server_ev_accept);
|
||||||
fd = server_create_socket();
|
fd = server_create_socket(NULL);
|
||||||
if (fd != -1) {
|
if (fd != -1) {
|
||||||
close(server_fd);
|
close(server_fd);
|
||||||
server_fd = fd;
|
server_fd = fd;
|
||||||
|
2
tmux.h
2
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 *);
|
const char *server_client_get_key_table(struct client *);
|
||||||
int server_client_check_nested(struct client *);
|
int server_client_check_nested(struct client *);
|
||||||
void server_client_handle_key(struct client *, key_code);
|
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 **);
|
int server_client_open(struct client *, char **);
|
||||||
void server_client_unref(struct client *);
|
void server_client_unref(struct client *);
|
||||||
void server_client_lost(struct client *);
|
void server_client_lost(struct client *);
|
||||||
|
Loading…
Reference in New Issue
Block a user