diff options
author | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-10-21 20:11:48 +0000 |
---|---|---|
committer | Nicholas Marriott <nicm@cvs.openbsd.org> | 2009-10-21 20:11:48 +0000 |
commit | 78dfafc8ede858a0b7f036e6c190607741072f08 (patch) | |
tree | 89afd3d35f93f0ef4634a8e9d272688d6a84a243 /usr.bin/tmux/client.c | |
parent | c01b1bf1af4f1e08f1051eec416981fc16dbb54c (diff) |
Client tidying: get rid of client_ctx struct in favour of two variables in
client.c, and move the functions in client-fn.c into other files.
Diffstat (limited to 'usr.bin/tmux/client.c')
-rw-r--r-- | usr.bin/tmux/client.c | 150 |
1 files changed, 74 insertions, 76 deletions
diff --git a/usr.bin/tmux/client.c b/usr.bin/tmux/client.c index 129832d23d9..c6e8ad5b5f4 100644 --- a/usr.bin/tmux/client.c +++ b/usr.bin/tmux/client.c @@ -1,4 +1,4 @@ -/* $OpenBSD: client.c,v 1.24 2009/10/13 13:15:26 nicm Exp $ */ +/* $OpenBSD: client.c,v 1.25 2009/10/21 20:11:47 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -33,10 +33,16 @@ #include "tmux.h" -void client_send_environ(struct client_ctx *); +struct imsgbuf client_ibuf; +const char *client_exitmsg; -int -client_init(char *path, struct client_ctx *cctx, int cmdflags, int flags) +void client_send_environ(void); +void client_write_server(enum msgtype, void *, size_t); +int client_dispatch(void); +void client_suspend(void); + +struct imsgbuf * +client_init(char *path, int cmdflags, int flags) { struct sockaddr_un sa; struct stat sb; @@ -93,10 +99,10 @@ server_started: fatal("fcntl failed"); if (fcntl(fd, F_SETFD, FD_CLOEXEC) == -1) fatal("fcntl failed"); - imsg_init(&cctx->ibuf, fd); + imsg_init(&client_ibuf, fd); if (cmdflags & CMD_SENDENVIRON) - client_send_environ(cctx); + client_send_environ(); if (isatty(STDIN_FILENO)) { if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) fatal("ioctl(TIOCGWINSZ)"); @@ -114,23 +120,23 @@ server_started: if ((fd2 = dup(STDIN_FILENO)) == -1) fatal("dup failed"); - imsg_compose(&cctx->ibuf, MSG_IDENTIFY, + imsg_compose(&client_ibuf, MSG_IDENTIFY, PROTOCOL_VERSION, -1, fd2, &data, sizeof data); } - return (0); + return (&client_ibuf); start_failed: log_warnx("server failed to start"); - return (1); + return (NULL); not_found: log_warn("server not found"); - return (1); + return (NULL); } void -client_send_environ(struct client_ctx *cctx) +client_send_environ(void) { char **var; struct msg_environ_data data; @@ -138,12 +144,18 @@ client_send_environ(struct client_ctx *cctx) for (var = environ; *var != NULL; var++) { if (strlcpy(data.var, *var, sizeof data.var) >= sizeof data.var) continue; - client_write_server(cctx, MSG_ENVIRON, &data, sizeof data); + client_write_server(MSG_ENVIRON, &data, sizeof data); } } -int -client_main(struct client_ctx *cctx) +void +client_write_server(enum msgtype type, void *buf, size_t len) +{ + imsg_compose(&client_ibuf, type, PROTOCOL_VERSION, -1, -1, buf, len); +} + +__dead void +client_main(void) { struct pollfd pfd; int n, nfds; @@ -158,29 +170,31 @@ client_main(struct client_ctx *cctx) * MSG_READY switched to here. Process anything outstanding now so poll * doesn't hang waiting for messages that have already arrived. */ - if (client_msg_dispatch(cctx) != 0) + if (client_dispatch() != 0) goto out; for (;;) { - if (sigterm) - client_write_server(cctx, MSG_EXITING, NULL, 0); + if (sigterm) { + client_exitmsg = "terminated"; + client_write_server(MSG_EXITING, NULL, 0); + } if (sigchld) { waitpid(WAIT_ANY, NULL, WNOHANG); sigchld = 0; } if (sigwinch) { - client_write_server(cctx, MSG_RESIZE, NULL, 0); + client_write_server(MSG_RESIZE, NULL, 0); sigwinch = 0; } if (sigcont) { siginit(); - client_write_server(cctx, MSG_WAKEUP, NULL, 0); + client_write_server(MSG_WAKEUP, NULL, 0); sigcont = 0; } - pfd.fd = cctx->ibuf.fd; + pfd.fd = client_ibuf.fd; pfd.events = POLLIN; - if (cctx->ibuf.w.queued > 0) + if (client_ibuf.w.queued > 0) pfd.events |= POLLOUT; if ((nfds = poll(&pfd, 1, INFTIM)) == -1) { @@ -195,67 +209,41 @@ client_main(struct client_ctx *cctx) fatalx("socket error"); if (pfd.revents & POLLIN) { - if ((n = imsg_read(&cctx->ibuf)) == -1 || n == 0) { - cctx->exittype = CCTX_DIED; + if ((n = imsg_read(&client_ibuf)) == -1 || n == 0) { + client_exitmsg = "lost server"; break; } - if (client_msg_dispatch(cctx) != 0) + if (client_dispatch() != 0) break; } if (pfd.revents & POLLOUT) { - if (msgbuf_write(&cctx->ibuf.w) < 0) { - cctx->exittype = CCTX_DIED; + if (msgbuf_write(&client_ibuf.w) < 0) { + client_exitmsg = "lost server"; break; } } } out: - /* - * Print exit status message, unless running as a login shell where it - * would either be pointless or irritating. - */ - if (sigterm) { - printf("[terminated]\n"); - return (1); - } - switch (cctx->exittype) { - case CCTX_DIED: - printf("[lost server]\n"); - return (0); - case CCTX_SHUTDOWN: - if (!login_shell) - printf("[server exited]\n"); - return (0); - case CCTX_EXIT: - if (cctx->errstr != NULL) { - printf("[error: %s]\n", cctx->errstr); - return (1); - } - if (!login_shell) - printf("[exited]\n"); - return (0); - case CCTX_DETACH: + /* Print the exit message, if any, and exit. */ + if (client_exitmsg != NULL) { if (!login_shell) - printf("[detached]\n"); - return (0); - default: - printf("[unknown error]\n"); - return (1); + printf("[%s]\n", client_exitmsg); + exit(1); } + exit(0); } int -client_msg_dispatch(struct client_ctx *cctx) +client_dispatch(void) { struct imsg imsg; - struct msg_print_data printdata; struct msg_lock_data lockdata; ssize_t n, datalen; for (;;) { - if ((n = imsg_get(&cctx->ibuf, &imsg)) == -1) + if ((n = imsg_get(&client_ibuf, &imsg)) == -1) fatalx("imsg_get failed"); if (n == 0) return (0); @@ -266,25 +254,15 @@ client_msg_dispatch(struct client_ctx *cctx) if (datalen != 0) fatalx("bad MSG_DETACH size"); - client_write_server(cctx, MSG_EXITING, NULL, 0); - cctx->exittype = CCTX_DETACH; + client_write_server(MSG_EXITING, NULL, 0); + client_exitmsg = "detached"; break; - case MSG_ERROR: - if (datalen != sizeof printdata) - fatalx("bad MSG_ERROR size"); - memcpy(&printdata, imsg.data, sizeof printdata); - - printdata.msg[(sizeof printdata.msg) - 1] = '\0'; - /* Error string used after exit message from server. */ - cctx->errstr = xstrdup(printdata.msg); - imsg_free(&imsg); - return (-1); case MSG_EXIT: if (datalen != 0) fatalx("bad MSG_EXIT size"); - client_write_server(cctx, MSG_EXITING, NULL, 0); - cctx->exittype = CCTX_EXIT; + client_write_server(MSG_EXITING, NULL, 0); + client_exitmsg = "exited"; break; case MSG_EXITED: if (datalen != 0) @@ -296,8 +274,8 @@ client_msg_dispatch(struct client_ctx *cctx) if (datalen != 0) fatalx("bad MSG_SHUTDOWN size"); - client_write_server(cctx, MSG_EXITING, NULL, 0); - cctx->exittype = CCTX_SHUTDOWN; + client_write_server(MSG_EXITING, NULL, 0); + client_exitmsg = "server exited"; break; case MSG_SUSPEND: if (datalen != 0) @@ -312,7 +290,7 @@ client_msg_dispatch(struct client_ctx *cctx) lockdata.cmd[(sizeof lockdata.cmd) - 1] = '\0'; system(lockdata.cmd); - client_write_server(cctx, MSG_UNLOCK, NULL, 0); + client_write_server(MSG_UNLOCK, NULL, 0); break; default: fatalx("unexpected message"); @@ -321,3 +299,23 @@ client_msg_dispatch(struct client_ctx *cctx) imsg_free(&imsg); } } + +void +client_suspend(void) +{ + struct sigaction act; + + memset(&act, 0, sizeof act); + sigemptyset(&act.sa_mask); + act.sa_flags = SA_RESTART; + + act.sa_handler = SIG_DFL; + if (sigaction(SIGTSTP, &act, NULL) != 0) + fatal("sigaction failed"); + + act.sa_handler = sighandler; + if (sigaction(SIGCONT, &act, NULL) != 0) + fatal("sigaction failed"); + + kill(getpid(), SIGTSTP); +} |