Annotation of src/usr.bin/tmux/client-msg.c, Revision 1.4
1.4 ! nicm 1: /* $OpenBSD: client-msg.c,v 1.3 2009/07/21 18:52:03 nicm Exp $ */
1.1 nicm 2:
3: /*
4: * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net>
5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15: * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16: * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
18:
19: #include <sys/types.h>
20:
21: #include <stdint.h>
22: #include <stdlib.h>
23: #include <string.h>
24: #include <unistd.h>
25:
26: #include "tmux.h"
27:
1.4 ! nicm 28: int client_msg_fn_detach(struct hdr *, struct client_ctx *);
! 29: int client_msg_fn_error(struct hdr *, struct client_ctx *);
! 30: int client_msg_fn_shutdown(struct hdr *, struct client_ctx *);
! 31: int client_msg_fn_exit(struct hdr *, struct client_ctx *);
! 32: int client_msg_fn_exited(struct hdr *, struct client_ctx *);
! 33: int client_msg_fn_suspend(struct hdr *, struct client_ctx *);
1.1 nicm 34:
35: struct client_msg {
36: enum hdrtype type;
1.4 ! nicm 37: int (*fn)(struct hdr *, struct client_ctx *);
1.1 nicm 38: };
39: struct client_msg client_msg_table[] = {
40: { MSG_DETACH, client_msg_fn_detach },
41: { MSG_ERROR, client_msg_fn_error },
42: { MSG_EXIT, client_msg_fn_exit },
43: { MSG_EXITED, client_msg_fn_exited },
44: { MSG_SHUTDOWN, client_msg_fn_shutdown },
45: { MSG_SUSPEND, client_msg_fn_suspend },
46: };
47:
48: int
1.4 ! nicm 49: client_msg_dispatch(struct client_ctx *cctx)
1.1 nicm 50: {
51: struct hdr hdr;
52: struct client_msg *msg;
53: u_int i;
54:
55: if (BUFFER_USED(cctx->srv_in) < sizeof hdr)
56: return (1);
57: memcpy(&hdr, BUFFER_OUT(cctx->srv_in), sizeof hdr);
58: if (BUFFER_USED(cctx->srv_in) < (sizeof hdr) + hdr.size)
59: return (1);
60: buffer_remove(cctx->srv_in, sizeof hdr);
61:
62: for (i = 0; i < nitems(client_msg_table); i++) {
63: msg = client_msg_table + i;
1.4 ! nicm 64: if (msg->type == hdr.type)
! 65: return (msg->fn(&hdr, cctx));
1.1 nicm 66: }
67: fatalx("unexpected message");
68: }
69:
70: int
1.4 ! nicm 71: client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx)
1.1 nicm 72: {
1.4 ! nicm 73: char *errstr;
! 74:
1.2 ray 75: if (hdr->size == SIZE_MAX)
1.1 nicm 76: fatalx("bad MSG_ERROR size");
77:
1.4 ! nicm 78: errstr = xmalloc(hdr->size + 1);
! 79: buffer_read(cctx->srv_in, errstr, hdr->size);
! 80: errstr[hdr->size] = '\0';
1.1 nicm 81:
1.4 ! nicm 82: cctx->errstr = errstr;
1.1 nicm 83: return (-1);
84: }
85:
86: int
1.4 ! nicm 87: client_msg_fn_detach(struct hdr *hdr, struct client_ctx *cctx)
1.1 nicm 88: {
89: if (hdr->size != 0)
90: fatalx("bad MSG_DETACH size");
91:
92: client_write_server(cctx, MSG_EXITING, NULL, 0);
1.4 ! nicm 93: cctx->exittype = CCTX_DETACH;
1.1 nicm 94:
95: return (0);
96: }
97:
98: int
99: client_msg_fn_shutdown(
1.4 ! nicm 100: struct hdr *hdr, struct client_ctx *cctx)
1.1 nicm 101: {
102: if (hdr->size != 0)
103: fatalx("bad MSG_SHUTDOWN size");
104:
105: client_write_server(cctx, MSG_EXITING, NULL, 0);
1.4 ! nicm 106: cctx->exittype = CCTX_SHUTDOWN;
1.1 nicm 107:
108: return (0);
109: }
110:
111: int
1.4 ! nicm 112: client_msg_fn_exit(struct hdr *hdr, struct client_ctx *cctx)
1.1 nicm 113: {
114: if (hdr->size != 0)
115: fatalx("bad MSG_EXIT size");
116:
117: client_write_server(cctx, MSG_EXITING, NULL, 0);
1.4 ! nicm 118: cctx->exittype = CCTX_EXIT;
1.1 nicm 119:
120: return (0);
121: }
122:
123: int
1.4 ! nicm 124: client_msg_fn_exited(struct hdr *hdr, unused struct client_ctx *cctx)
1.1 nicm 125: {
126: if (hdr->size != 0)
127: fatalx("bad MSG_EXITED size");
128:
129: return (-1);
130: }
131:
132: int
1.4 ! nicm 133: client_msg_fn_suspend(struct hdr *hdr, unused struct client_ctx *cctx)
1.1 nicm 134: {
135: struct sigaction act;
136:
137: if (hdr->size != 0)
138: fatalx("bad MSG_SUSPEND size");
139:
140: memset(&act, 0, sizeof act);
141: sigemptyset(&act.sa_mask);
142: act.sa_flags = SA_RESTART;
143:
144: act.sa_handler = SIG_DFL;
145: if (sigaction(SIGTSTP, &act, NULL) != 0)
146: fatal("sigaction failed");
147:
148: act.sa_handler = sighandler;
149: if (sigaction(SIGCONT, &act, NULL) != 0)
150: fatal("sigaction failed");
151:
152: kill(getpid(), SIGTSTP);
153:
154: return (0);
155: }