version 1.11, 2009/08/08 21:52:43 |
version 1.12, 2009/08/11 17:18:35 |
|
|
fatal("fcntl failed"); |
fatal("fcntl failed"); |
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) |
if (fcntl(fd, F_SETFL, mode|O_NONBLOCK) == -1) |
fatal("fcntl failed"); |
fatal("fcntl failed"); |
cctx->srv_fd = fd; |
imsg_init(&cctx->ibuf, fd); |
cctx->srv_in = buffer_create(BUFSIZ); |
|
cctx->srv_out = buffer_create(BUFSIZ); |
|
|
|
if (cmdflags & CMD_SENDENVIRON) |
if (cmdflags & CMD_SENDENVIRON) |
client_send_environ(cctx); |
client_send_environ(cctx); |
if (isatty(STDIN_FILENO)) { |
if (isatty(STDIN_FILENO)) { |
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) |
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) |
fatal("ioctl(TIOCGWINSZ)"); |
fatal("ioctl(TIOCGWINSZ)"); |
data.version = PROTOCOL_VERSION; |
|
data.flags = flags; |
data.flags = flags; |
data.sx = ws.ws_col; |
data.sx = ws.ws_col; |
data.sy = ws.ws_row; |
data.sy = ws.ws_row; |
|
|
client_main(struct client_ctx *cctx) |
client_main(struct client_ctx *cctx) |
{ |
{ |
struct pollfd pfd; |
struct pollfd pfd; |
|
int nfds; |
|
|
siginit(); |
siginit(); |
|
|
|
|
sigcont = 0; |
sigcont = 0; |
} |
} |
|
|
pfd.fd = cctx->srv_fd; |
pfd.fd = cctx->ibuf.fd; |
pfd.events = POLLIN; |
pfd.events = POLLIN; |
if (BUFFER_USED(cctx->srv_out) > 0) |
if (cctx->ibuf.w.queued > 0) |
pfd.events |= POLLOUT; |
pfd.events |= POLLOUT; |
|
|
if (poll(&pfd, 1, INFTIM) == -1) { |
if ((nfds = poll(&pfd, 1, INFTIM)) == -1) { |
if (errno == EAGAIN || errno == EINTR) |
if (errno == EAGAIN || errno == EINTR) |
continue; |
continue; |
fatal("poll failed"); |
fatal("poll failed"); |
} |
} |
|
if (nfds == 0) |
|
continue; |
|
|
if (buffer_poll(&pfd, cctx->srv_in, cctx->srv_out) != 0) { |
if (pfd.revents & (POLLERR|POLLHUP|POLLNVAL)) |
cctx->exittype = CCTX_DIED; |
fatalx("socket error"); |
break; |
|
|
if (pfd.revents & POLLIN) { |
|
if (client_msg_dispatch(cctx) != 0) |
|
break; |
} |
} |
|
|
if (client_msg_dispatch(cctx) != 0) |
if (pfd.revents & POLLOUT) { |
break; |
if (msgbuf_write(&cctx->ibuf.w) < 0) { |
|
cctx->exittype = CCTX_DIED; |
|
break; |
|
} |
|
} |
} |
} |
|
|
if (sigterm) { |
if (sigterm) { |
|
|
int |
int |
client_msg_dispatch(struct client_ctx *cctx) |
client_msg_dispatch(struct client_ctx *cctx) |
{ |
{ |
struct hdr hdr; |
struct imsg imsg; |
struct msg_print_data printdata; |
struct msg_print_data printdata; |
|
ssize_t n, datalen; |
|
|
|
if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) { |
|
cctx->exittype = CCTX_DIED; |
|
return (-1); |
|
} |
|
|
for (;;) { |
for (;;) { |
if (BUFFER_USED(cctx->srv_in) < sizeof hdr) |
if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1) |
|
fatalx("imsg_get failed"); |
|
if (n == 0) |
return (0); |
return (0); |
memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr); |
datalen = imsg.hdr.len - IMSG_HEADER_SIZE; |
if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size) |
|
return (0); |
|
buffer_remove(cctx->srv_in, sizeof hdr); |
|
|
|
switch (hdr.type) { |
switch (imsg.hdr.type) { |
case MSG_DETACH: |
case MSG_DETACH: |
if (hdr.size != 0) |
if (datalen != 0) |
fatalx("bad MSG_DETACH size"); |
fatalx("bad MSG_DETACH size"); |
|
|
client_write_server(cctx, MSG_EXITING, NULL, 0); |
client_write_server(cctx, MSG_EXITING, NULL, 0); |
cctx->exittype = CCTX_DETACH; |
cctx->exittype = CCTX_DETACH; |
break; |
break; |
case MSG_ERROR: |
case MSG_ERROR: |
if (hdr.size != sizeof printdata) |
if (datalen != sizeof printdata) |
fatalx("bad MSG_PRINT size"); |
fatalx("bad MSG_ERROR size"); |
buffer_read(cctx->srv_in, &printdata, sizeof printdata); |
memcpy(&printdata, imsg.data, sizeof printdata); |
|
|
printdata.msg[(sizeof printdata.msg) - 1] = '\0'; |
printdata.msg[(sizeof printdata.msg) - 1] = '\0'; |
cctx->errstr = xstrdup(printdata.msg); |
cctx->errstr = xstrdup(printdata.msg); |
|
imsg_free(&imsg); |
return (-1); |
return (-1); |
case MSG_EXIT: |
case MSG_EXIT: |
if (hdr.size != 0) |
if (datalen != 0) |
fatalx("bad MSG_EXIT size"); |
fatalx("bad MSG_EXIT size"); |
|
|
client_write_server(cctx, MSG_EXITING, NULL, 0); |
client_write_server(cctx, MSG_EXITING, NULL, 0); |
cctx->exittype = CCTX_EXIT; |
cctx->exittype = CCTX_EXIT; |
break; |
break; |
case MSG_EXITED: |
case MSG_EXITED: |
if (hdr.size != 0) |
if (datalen != 0) |
fatalx("bad MSG_EXITED size"); |
fatalx("bad MSG_EXITED size"); |
|
|
|
imsg_free(&imsg); |
return (-1); |
return (-1); |
case MSG_SHUTDOWN: |
case MSG_SHUTDOWN: |
if (hdr.size != 0) |
if (datalen != 0) |
fatalx("bad MSG_SHUTDOWN size"); |
fatalx("bad MSG_SHUTDOWN size"); |
|
|
client_write_server(cctx, MSG_EXITING, NULL, 0); |
client_write_server(cctx, MSG_EXITING, NULL, 0); |
cctx->exittype = CCTX_SHUTDOWN; |
cctx->exittype = CCTX_SHUTDOWN; |
break; |
break; |
case MSG_SUSPEND: |
case MSG_SUSPEND: |
if (hdr.size != 0) |
if (datalen != 0) |
fatalx("bad MSG_SUSPEND size"); |
fatalx("bad MSG_SUSPEND size"); |
|
|
client_suspend(); |
client_suspend(); |
|
|
default: |
default: |
fatalx("unexpected message"); |
fatalx("unexpected message"); |
} |
} |
|
|
|
imsg_free(&imsg); |
} |
} |
} |
} |