mirror of
https://github.com/tmux/tmux.git
synced 2024-12-13 01:48:47 +00:00
Don't hang when window closes early; also add lots more debugging.
This commit is contained in:
parent
abe745f991
commit
5569ff9723
9
CHANGES
9
CHANGES
@ -1,3 +1,10 @@
|
|||||||
|
31 May 2008
|
||||||
|
|
||||||
|
* Fix so tmux doesn't hang if the initial window fails for some reason. This
|
||||||
|
was highlighted by problems on Darwin, thanks to Elias Pipping for the report
|
||||||
|
and access to a test account. (tmux still won't work on Darwin since its
|
||||||
|
poll(2) is broken.)
|
||||||
|
|
||||||
02 January 2008
|
02 January 2008
|
||||||
|
|
||||||
* Don't attempt to reset the tty on exit if it has been closed externally.
|
* Don't attempt to reset the tty on exit if it has been closed externally.
|
||||||
@ -303,4 +310,4 @@
|
|||||||
(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.93 2008-05-10 12:50:25 nicm Exp $
|
$Id: CHANGES,v 1.94 2008-05-31 20:04:15 nicm Exp $
|
||||||
|
9
NOTES
9
NOTES
@ -47,7 +47,7 @@ TERM=screen (tmux in screen), xterm, xterm-color and rxvt. Note that tmux
|
|||||||
(and screen) relies on an AX term capability to detect if the terminal
|
(and screen) relies on an AX term capability to detect if the terminal
|
||||||
supports "default" (transparent) foreground and background colours. On OpenBSD,
|
supports "default" (transparent) foreground and background colours. On OpenBSD,
|
||||||
TERM=xterm and TERM=xterm-color lack this; TERM=rxvt does have it and works fine
|
TERM=xterm and TERM=xterm-color lack this; TERM=rxvt does have it and works fine
|
||||||
at least with the aterm and (naturally) rxvt terminal emulators.
|
at least with the aterm and rxvt terminal emulators.
|
||||||
|
|
||||||
For debugging, running tmux with -v or -vv will generate server and client log
|
For debugging, running tmux with -v or -vv will generate server and client log
|
||||||
files in the current directory.
|
files in the current directory.
|
||||||
@ -57,9 +57,6 @@ welcome. Please email:
|
|||||||
|
|
||||||
nicm@users.sf.net
|
nicm@users.sf.net
|
||||||
|
|
||||||
Or contact me during UK daytime hours (0900 to 2300 UTC or so) as "NicM" on
|
|
||||||
freenode or efnet IRC. I sometimes ignore private msgs from people I don't
|
|
||||||
know, so please mention tmux initially (rather than just saying "hi" ;-).
|
|
||||||
|
|
||||||
-- Nicholas Marriott <nicm@users.sf.net>
|
-- Nicholas Marriott <nicm@users.sf.net>
|
||||||
$Id: NOTES,v 1.31 2007-11-26 20:50:31 nicm Exp $
|
|
||||||
|
$Id: NOTES,v 1.32 2008-05-31 20:04:15 nicm Exp $
|
||||||
|
4
TODO
4
TODO
@ -71,8 +71,10 @@
|
|||||||
-- it's not kkeypad/kcursor
|
-- it's not kkeypad/kcursor
|
||||||
- fix kkeypad/kcursor
|
- fix kkeypad/kcursor
|
||||||
- c/p is still borken in some ways
|
- c/p is still borken in some ways
|
||||||
|
- tobiasu says it is borken on Linux with aterm + TERM=rxvt
|
||||||
|
|
||||||
-- For 0.2 --------------------------------------------------------------------
|
-- For 0.3 --------------------------------------------------------------------
|
||||||
- anything which uses cmd_{send,recv}_string will break if the string is
|
- anything which uses cmd_{send,recv}_string will break if the string is
|
||||||
split. string length should be part of the command size
|
split. string length should be part of the command size
|
||||||
- chmod +x socket when any client is attached (upd in lost/accept)
|
- chmod +x socket when any client is attached (upd in lost/accept)
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $Id: buffer-poll.c,v 1.4 2007-11-30 11:08:34 nicm Exp $ */
|
/* $Id: buffer-poll.c,v 1.5 2008-05-31 20:04:15 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -41,11 +41,15 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
|
|||||||
{
|
{
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
|
log_debug("buffer_poll (%d): fd=%d, revents=%d; out=%zu in=%zu",
|
||||||
|
getpid(), pfd->fd, pfd->revents, BUFFER_USED(out), BUFFER_USED(in));
|
||||||
|
|
||||||
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
|
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
|
||||||
return (-1);
|
return (-1);
|
||||||
if (pfd->revents & POLLIN) {
|
if (pfd->revents & POLLIN) {
|
||||||
buffer_ensure(in, BUFSIZ);
|
buffer_ensure(in, BUFSIZ);
|
||||||
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
|
n = read(pfd->fd, BUFFER_IN(in), BUFFER_FREE(in));
|
||||||
|
log_debug("buffer_poll: fd=%d, read=%zd", pfd->fd, n);
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return (-1);
|
return (-1);
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
@ -55,7 +59,8 @@ buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out)
|
|||||||
buffer_add(in, n);
|
buffer_add(in, n);
|
||||||
}
|
}
|
||||||
if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
|
if (BUFFER_USED(out) > 0 && pfd->revents & POLLOUT) {
|
||||||
n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
|
n = write(pfd->fd, BUFFER_OUT(out), BUFFER_USED(out));
|
||||||
|
log_debug("buffer_poll: fd=%d, write=%zd", pfd->fd, n);
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
if (errno != EINTR && errno != EAGAIN)
|
if (errno != EINTR && errno != EAGAIN)
|
||||||
return (-1);
|
return (-1);
|
||||||
|
28
client.c
28
client.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: client.c,v 1.25 2007-12-06 09:46:21 nicm Exp $ */
|
/* $Id: client.c,v 1.26 2008-05-31 20:04:15 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -130,6 +130,19 @@ client_main(struct client_ctx *cctx)
|
|||||||
if (sigwinch)
|
if (sigwinch)
|
||||||
client_handle_winch(cctx);
|
client_handle_winch(cctx);
|
||||||
|
|
||||||
|
switch (client_msg_dispatch(cctx, &error)) {
|
||||||
|
case -1:
|
||||||
|
goto out;
|
||||||
|
case 0:
|
||||||
|
/* May be more in buffer, don't let poll block. */
|
||||||
|
timeout = 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* Out of data, poll may block. */
|
||||||
|
timeout = INFTIM;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
pfd.fd = cctx->srv_fd;
|
pfd.fd = cctx->srv_fd;
|
||||||
pfd.events = POLLIN;
|
pfd.events = POLLIN;
|
||||||
if (BUFFER_USED(cctx->srv_out) > 0)
|
if (BUFFER_USED(cctx->srv_out) > 0)
|
||||||
@ -143,19 +156,6 @@ client_main(struct client_ctx *cctx)
|
|||||||
|
|
||||||
if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
|
if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0)
|
||||||
goto server_dead;
|
goto server_dead;
|
||||||
|
|
||||||
switch (client_msg_dispatch(cctx, &error)) {
|
|
||||||
case -1:
|
|
||||||
goto out;
|
|
||||||
case 0:
|
|
||||||
/* May be more in buffer, don't let poll block. */
|
|
||||||
timeout = 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/* Out of data, poll may block. */
|
|
||||||
timeout = INFTIM;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
14
server.c
14
server.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: server.c,v 1.44 2007-12-06 09:46:23 nicm Exp $ */
|
/* $Id: server.c,v 1.45 2008-05-31 20:04:15 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -153,12 +153,14 @@ server_main(const char *srv_path, int srv_fd)
|
|||||||
server_fill_clients(&pfd);
|
server_fill_clients(&pfd);
|
||||||
|
|
||||||
/* Do the poll. */
|
/* Do the poll. */
|
||||||
if (poll(pfds, nfds, INFTIM) == -1) {
|
log_debug("polling %d fds", nfds);
|
||||||
|
if ((nfds = poll(pfds, nfds, INFTIM)) == -1) {
|
||||||
if (errno == EAGAIN || errno == EINTR)
|
if (errno == EAGAIN || errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
fatal("poll failed");
|
fatal("poll failed");
|
||||||
}
|
}
|
||||||
pfd = pfds;
|
pfd = pfds;
|
||||||
|
log_debug("poll returned %d", nfds);
|
||||||
|
|
||||||
/* Handle server socket. */
|
/* Handle server socket. */
|
||||||
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
|
if (pfd->revents & (POLLERR|POLLNVAL|POLLHUP))
|
||||||
@ -215,6 +217,7 @@ server_fill_windows(struct pollfd **pfd)
|
|||||||
(*pfd)->events = POLLIN;
|
(*pfd)->events = POLLIN;
|
||||||
if (BUFFER_USED(w->out) > 0)
|
if (BUFFER_USED(w->out) > 0)
|
||||||
(*pfd)->events |= POLLOUT;
|
(*pfd)->events |= POLLOUT;
|
||||||
|
log_debug("adding window %d (%d)", (*pfd)->fd, w->fd);
|
||||||
}
|
}
|
||||||
(*pfd)++;
|
(*pfd)++;
|
||||||
}
|
}
|
||||||
@ -229,6 +232,7 @@ server_handle_windows(struct pollfd **pfd)
|
|||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
|
for (i = 0; i < ARRAY_LENGTH(&windows); i++) {
|
||||||
if ((w = ARRAY_ITEM(&windows, i)) != NULL) {
|
if ((w = ARRAY_ITEM(&windows, i)) != NULL) {
|
||||||
|
log_debug("testing window %d (%d)", (*pfd)->fd, w->fd);
|
||||||
if (buffer_poll(*pfd, w->in, w->out) != 0)
|
if (buffer_poll(*pfd, w->in, w->out) != 0)
|
||||||
server_lost_window(w);
|
server_lost_window(w);
|
||||||
else
|
else
|
||||||
@ -255,16 +259,18 @@ server_fill_clients(struct pollfd **pfd)
|
|||||||
(*pfd)->events = POLLIN;
|
(*pfd)->events = POLLIN;
|
||||||
if (BUFFER_USED(c->out) > 0)
|
if (BUFFER_USED(c->out) > 0)
|
||||||
(*pfd)->events |= POLLOUT;
|
(*pfd)->events |= POLLOUT;
|
||||||
|
log_debug("adding client %d (%d)", (*pfd)->fd, c->fd);
|
||||||
}
|
}
|
||||||
(*pfd)++;
|
(*pfd)++;
|
||||||
|
|
||||||
if (c == NULL || c->tty.fd == -1)
|
if (c == NULL || c->tty.fd == -1 || c->session == NULL)
|
||||||
(*pfd)->fd = -1;
|
(*pfd)->fd = -1;
|
||||||
else {
|
else {
|
||||||
(*pfd)->fd = c->tty.fd;
|
(*pfd)->fd = c->tty.fd;
|
||||||
(*pfd)->events = POLLIN;
|
(*pfd)->events = POLLIN;
|
||||||
if (BUFFER_USED(c->tty.out) > 0)
|
if (BUFFER_USED(c->tty.out) > 0)
|
||||||
(*pfd)->events |= POLLOUT;
|
(*pfd)->events |= POLLOUT;
|
||||||
|
log_debug("adding tty %d (%d)", (*pfd)->fd, c->tty.fd);
|
||||||
}
|
}
|
||||||
(*pfd)++;
|
(*pfd)++;
|
||||||
}
|
}
|
||||||
@ -281,6 +287,7 @@ server_handle_clients(struct pollfd **pfd)
|
|||||||
c = ARRAY_ITEM(&clients, i);
|
c = ARRAY_ITEM(&clients, i);
|
||||||
|
|
||||||
if (c != NULL) {
|
if (c != NULL) {
|
||||||
|
log_debug("testing client %d (%d)", (*pfd)->fd, c->fd);
|
||||||
if (buffer_poll(*pfd, c->in, c->out) != 0) {
|
if (buffer_poll(*pfd, c->in, c->out) != 0) {
|
||||||
server_lost_client(c);
|
server_lost_client(c);
|
||||||
(*pfd) += 2;
|
(*pfd) += 2;
|
||||||
@ -291,6 +298,7 @@ server_handle_clients(struct pollfd **pfd)
|
|||||||
(*pfd)++;
|
(*pfd)++;
|
||||||
|
|
||||||
if (c != NULL && c->tty.fd != -1 && c->session != NULL) {
|
if (c != NULL && c->tty.fd != -1 && c->session != NULL) {
|
||||||
|
log_debug("testing tty %d (%d)", (*pfd)->fd, c->tty.fd);
|
||||||
if (buffer_poll(*pfd, c->tty.in, c->tty.out) != 0)
|
if (buffer_poll(*pfd, c->tty.in, c->tty.out) != 0)
|
||||||
server_lost_client(c);
|
server_lost_client(c);
|
||||||
else
|
else
|
||||||
|
7
window.c
7
window.c
@ -1,4 +1,4 @@
|
|||||||
/* $Id: window.c,v 1.35 2008-01-02 19:22:21 nicm Exp $ */
|
/* $Id: window.c,v 1.36 2008-05-31 20:04:15 nicm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
* Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
|
||||||
@ -169,7 +169,7 @@ window_create(
|
|||||||
ws.ws_col = sx;
|
ws.ws_col = sx;
|
||||||
ws.ws_row = sy;
|
ws.ws_row = sy;
|
||||||
|
|
||||||
switch (forkpty(&fd, NULL, NULL, &ws)) {
|
switch (forkpty(&fd, NULL, NULL, &ws)) {
|
||||||
case -1:
|
case -1:
|
||||||
return (NULL);
|
return (NULL);
|
||||||
case 0:
|
case 0:
|
||||||
@ -178,8 +178,9 @@ window_create(
|
|||||||
fatal("putenv failed");
|
fatal("putenv failed");
|
||||||
}
|
}
|
||||||
sigreset();
|
sigreset();
|
||||||
|
log_debug("started child: cmd=%s; pid=%d", cmd, getpid());
|
||||||
log_close();
|
log_close();
|
||||||
|
|
||||||
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
|
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
|
||||||
fatal("execl failed");
|
fatal("execl failed");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user