mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
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.
This commit is contained in:
parent
95323a6a36
commit
5f6a351df7
8
CHANGES
8
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
|
18 January 2009
|
||||||
|
|
||||||
* Unbreak UTF-8.
|
* Unbreak UTF-8.
|
||||||
@ -958,7 +964,7 @@
|
|||||||
(including mutt, emacs). No status bar yet and no key remapping or other
|
(including mutt, emacs). No status bar yet and no key remapping or other
|
||||||
customisation.
|
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: 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
|
LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms
|
||||||
|
36
client.c
36
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 <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -44,23 +44,20 @@ client_init(
|
|||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
size_t size;
|
size_t size;
|
||||||
int mode;
|
int mode;
|
||||||
u_int retries;
|
|
||||||
struct buffer *b;
|
struct buffer *b;
|
||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
retries = 0;
|
|
||||||
retry:
|
|
||||||
if (stat(path, &sb) != 0) {
|
if (stat(path, &sb) != 0) {
|
||||||
if (start_server && errno == ENOENT) {
|
if (start_server && errno == ENOENT) {
|
||||||
if (server_start(path) != 0)
|
if ((cctx->srv_fd = server_start(path)) == -1)
|
||||||
goto no_start;
|
goto start_failed;
|
||||||
goto retry;
|
goto server_started;
|
||||||
}
|
}
|
||||||
goto fail;
|
goto not_found;
|
||||||
}
|
}
|
||||||
if (!S_ISSOCK(sb.st_mode)) {
|
if (!S_ISSOCK(sb.st_mode)) {
|
||||||
errno = ENOTSOCK;
|
errno = ENOTSOCK;
|
||||||
goto fail;
|
goto not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&sa, 0, sizeof sa);
|
memset(&sa, 0, sizeof sa);
|
||||||
@ -68,7 +65,7 @@ retry:
|
|||||||
size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
|
size = strlcpy(sa.sun_path, path, sizeof sa.sun_path);
|
||||||
if (size >= sizeof sa.sun_path) {
|
if (size >= sizeof sa.sun_path) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
goto fail;
|
goto not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
if ((cctx->srv_fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
|
||||||
@ -76,16 +73,17 @@ retry:
|
|||||||
|
|
||||||
if (connect(
|
if (connect(
|
||||||
cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
|
cctx->srv_fd, (struct sockaddr *) &sa, SUN_LEN(&sa)) == -1) {
|
||||||
if (start_server && errno == ECONNREFUSED && retries < 10) {
|
if (errno == ECONNREFUSED) {
|
||||||
if (unlink(path) != 0)
|
if (unlink(path) != 0 || !start_server)
|
||||||
goto fail;
|
goto not_found;
|
||||||
if (server_start(path) != 0)
|
if ((cctx->srv_fd = server_start(path)) == -1)
|
||||||
goto no_start;
|
goto start_failed;
|
||||||
|
goto server_started;
|
||||||
}
|
}
|
||||||
retries++;
|
goto not_found;
|
||||||
goto retry;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
server_started:
|
||||||
if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
|
if ((mode = fcntl(cctx->srv_fd, F_GETFL)) == -1)
|
||||||
fatal("fcntl");
|
fatal("fcntl");
|
||||||
if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
if (fcntl(cctx->srv_fd, F_SETFL, mode|O_NONBLOCK) == -1)
|
||||||
@ -118,11 +116,11 @@ retry:
|
|||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
no_start:
|
start_failed:
|
||||||
log_warnx("server failed to start");
|
log_warnx("server failed to start");
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
fail:
|
not_found:
|
||||||
log_warn("server not found");
|
log_warn("server not found");
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
@ -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 <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -29,7 +29,7 @@ void cmd_attach_session_exec(struct cmd *, struct cmd_ctx *);
|
|||||||
const struct cmd_entry cmd_attach_session_entry = {
|
const struct cmd_entry cmd_attach_session_entry = {
|
||||||
"attach-session", "attach",
|
"attach-session", "attach",
|
||||||
"[-d] " CMD_TARGET_SESSION_USAGE,
|
"[-d] " CMD_TARGET_SESSION_USAGE,
|
||||||
CMD_DFLAG|CMD_CANTNEST,
|
CMD_DFLAG|CMD_CANTNEST|CMD_STARTSERVER,
|
||||||
cmd_target_init,
|
cmd_target_init,
|
||||||
cmd_target_parse,
|
cmd_target_parse,
|
||||||
cmd_attach_session_exec,
|
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 cmd_target_data *data = self->data;
|
||||||
struct session *s;
|
struct session *s;
|
||||||
char *cause;
|
char *cause;
|
||||||
|
|
||||||
if (ctx->curclient != NULL)
|
if (ctx->curclient != NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (ARRAY_LENGTH(&sessions) == 0) {
|
||||||
|
ctx->error(ctx, "no sessions");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if ((s = cmd_find_session(ctx, data->target)) == NULL)
|
if ((s = cmd_find_session(ctx, data->target)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
111
server.c
111
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 <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -58,6 +58,51 @@ void server_check_timers(struct client *);
|
|||||||
void server_second_timers(void);
|
void server_second_timers(void);
|
||||||
int server_update_socket(const char *);
|
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
|
int
|
||||||
server_client_index(struct client *c)
|
server_client_index(struct client *c)
|
||||||
{
|
{
|
||||||
@ -79,9 +124,8 @@ server_start(const char *path)
|
|||||||
mode_t mask;
|
mode_t mask;
|
||||||
int n, fd, pair[2], mode;
|
int n, fd, pair[2], mode;
|
||||||
char *cause;
|
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)
|
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0)
|
||||||
fatal("socketpair failed");
|
fatal("socketpair failed");
|
||||||
|
|
||||||
@ -92,17 +136,7 @@ server_start(const char *path)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
close(pair[1]);
|
close(pair[1]);
|
||||||
|
return (pair[0]);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
close(pair[0]);
|
close(pair[0]);
|
||||||
|
|
||||||
@ -166,11 +200,7 @@ server_start(const char *path)
|
|||||||
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
|
if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
|
||||||
fatal("fcntl failed");
|
fatal("fcntl failed");
|
||||||
|
|
||||||
ch = 0xff;
|
server_create_client(pair[1]);
|
||||||
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]);
|
|
||||||
|
|
||||||
n = server_main(path, fd);
|
n = server_main(path, fd);
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -532,52 +562,17 @@ server_handle_clients(struct pollfd **pfd)
|
|||||||
struct client *
|
struct client *
|
||||||
server_accept_client(int srv_fd)
|
server_accept_client(int srv_fd)
|
||||||
{
|
{
|
||||||
struct client *c;
|
|
||||||
struct sockaddr_storage sa;
|
struct sockaddr_storage sa;
|
||||||
socklen_t slen = sizeof sa;
|
socklen_t slen = sizeof sa;
|
||||||
int client_fd, mode;
|
int fd;
|
||||||
u_int i;
|
|
||||||
|
|
||||||
client_fd = accept(srv_fd, (struct sockaddr *) &sa, &slen);
|
fd = accept(srv_fd, (struct sockaddr *) &sa, &slen);
|
||||||
if (client_fd == -1) {
|
if (fd == -1) {
|
||||||
if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
|
if (errno == EAGAIN || errno == EINTR || errno == ECONNABORTED)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
fatal("accept failed");
|
fatal("accept failed");
|
||||||
}
|
}
|
||||||
if ((mode = fcntl(client_fd, F_GETFL)) == -1)
|
return (server_create_client(fd));
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Input data from client. */
|
/* Input data from client. */
|
||||||
|
7
tmux.1
7
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 <nicm@users.sourceforge.net>
|
.\" Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
.\"
|
.\"
|
||||||
@ -345,6 +345,11 @@ Create a new client in the current terminal and attach it to a session.
|
|||||||
If
|
If
|
||||||
.Fl d
|
.Fl d
|
||||||
is specified, any other clients attached to the session are detached.
|
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
|
.It Xo Ic bind-key
|
||||||
.Ar key Ar command Op Ar arguments
|
.Ar key Ar command Op Ar arguments
|
||||||
.Xc
|
.Xc
|
||||||
|
3
tmux.h
3
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 <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -1253,6 +1253,7 @@ const char *key_string_lookup_key(int);
|
|||||||
|
|
||||||
/* server.c */
|
/* server.c */
|
||||||
extern struct clients clients;
|
extern struct clients clients;
|
||||||
|
struct client *server_create_client(int);
|
||||||
int server_client_index(struct client *);
|
int server_client_index(struct client *);
|
||||||
int server_start(const char *);
|
int server_start(const char *);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user