Don't hang when window closes early; also add lots more debugging.

This commit is contained in:
Nicholas Marriott 2008-05-31 20:04:15 +00:00
parent abe745f991
commit 5569ff9723
7 changed files with 50 additions and 30 deletions

View File

@ -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
View File

@ -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
View File

@ -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)

View File

@ -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);

View File

@ -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:

View File

@ -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

View File

@ -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");
} }