version 1.1, 2009/06/01 22:58:49 |
version 1.2, 2009/06/25 06:05:47 |
|
|
|
|
#include "tmux.h" |
#include "tmux.h" |
|
|
/* Set up pollfd for buffers. */ |
|
void |
|
buffer_set( |
|
struct pollfd *pfd, int fd, unused struct buffer *in, struct buffer *out) |
|
{ |
|
pfd->fd = fd; |
|
pfd->events = POLLIN; |
|
if (BUFFER_USED(out) > 0) |
|
pfd->events |= POLLOUT; |
|
} |
|
|
|
/* Fill buffers from socket based on poll results. */ |
/* Fill buffers from socket based on poll results. */ |
int |
int |
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out) |
buffer_poll(struct pollfd *pfd, struct buffer *in, struct buffer *out) |
{ |
{ |
ssize_t n; |
ssize_t n; |
|
|
#if 0 |
|
log_debug("buffer_poll (%ld): fd=%d, revents=%d; out=%zu in=%zu", |
|
(long) getpid(), |
|
pfd->fd, pfd->revents, BUFFER_USED(out), BUFFER_USED(in)); |
|
#endif |
|
|
|
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)); |
#if 0 |
|
log_debug("buffer_poll: fd=%d, read=%zd", pfd->fd, n); |
|
#endif |
|
if (n == 0) |
if (n == 0) |
return (-1); |
return (-1); |
if (n == -1) { |
if (n == -1) { |
|
|
} |
} |
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)); |
#if 0 |
|
log_debug("buffer_poll: fd=%d, write=%zd", pfd->fd, n); |
|
#endif |
|
if (n == -1) { |
if (n == -1) { |
if (errno != EINTR && errno != EAGAIN) |
if (errno != EINTR && errno != EAGAIN) |
return (-1); |
return (-1); |
|
|
buffer_remove(out, n); |
buffer_remove(out, n); |
} |
} |
return (0); |
return (0); |
} |
|
|
|
/* Flush buffer output to socket. */ |
|
void |
|
buffer_flush(int fd, struct buffer *in, struct buffer *out) |
|
{ |
|
struct pollfd pfd; |
|
|
|
while (BUFFER_USED(out) > 0) { |
|
buffer_set(&pfd, fd, in, out); |
|
|
|
if (poll(&pfd, 1, INFTIM) == -1) { |
|
if (errno == EAGAIN || errno == EINTR) |
|
continue; |
|
fatal("poll failed"); |
|
} |
|
|
|
if (buffer_poll(&pfd, in, out) != 0) |
|
break; |
|
} |
|
} |
} |