Annotation of src/usr.bin/tmux/client-msg.c, Revision 1.3
1.3 ! nicm 1: /* $OpenBSD: client-msg.c,v 1.2 2009/06/02 11:17:03 ray 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:
28: int client_msg_fn_detach(struct hdr *, struct client_ctx *, char **);
29: int client_msg_fn_error(struct hdr *, struct client_ctx *, char **);
30: int client_msg_fn_shutdown(struct hdr *, struct client_ctx *, char **);
31: int client_msg_fn_exit(struct hdr *, struct client_ctx *, char **);
32: int client_msg_fn_exited(struct hdr *, struct client_ctx *, char **);
33: int client_msg_fn_suspend(struct hdr *, struct client_ctx *, char **);
34:
35: struct client_msg {
36: enum hdrtype type;
37: int (*fn)(struct hdr *, struct client_ctx *, char **);
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
49: client_msg_dispatch(struct client_ctx *cctx, char **error)
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;
64: if (msg->type == hdr.type) {
65: if (msg->fn(&hdr, cctx, error) != 0)
66: return (-1);
67: return (0);
68: }
69: }
70: fatalx("unexpected message");
71: }
72:
73: int
74: client_msg_fn_error(struct hdr *hdr, struct client_ctx *cctx, char **error)
75: {
1.2 ray 76: if (hdr->size == SIZE_MAX)
1.1 nicm 77: fatalx("bad MSG_ERROR size");
78:
79: *error = xmalloc(hdr->size + 1);
80: buffer_read(cctx->srv_in, *error, hdr->size);
81: (*error)[hdr->size] = '\0';
82:
83: return (-1);
84: }
85:
86: int
87: client_msg_fn_detach(
1.3 ! nicm 88: struct hdr *hdr, struct client_ctx *cctx, unused char **error)
1.1 nicm 89: {
90: if (hdr->size != 0)
91: fatalx("bad MSG_DETACH size");
92:
93: client_write_server(cctx, MSG_EXITING, NULL, 0);
94: cctx->flags |= CCTX_DETACH;
95:
96: return (0);
97: }
98:
99: int
100: client_msg_fn_shutdown(
1.3 ! nicm 101: struct hdr *hdr, struct client_ctx *cctx, unused char **error)
1.1 nicm 102: {
103: if (hdr->size != 0)
104: fatalx("bad MSG_SHUTDOWN size");
105:
106: client_write_server(cctx, MSG_EXITING, NULL, 0);
107: cctx->flags |= CCTX_SHUTDOWN;
108:
109: return (0);
110: }
111:
112: int
113: client_msg_fn_exit(
1.3 ! nicm 114: struct hdr *hdr, struct client_ctx *cctx, unused char **error)
1.1 nicm 115: {
116: if (hdr->size != 0)
117: fatalx("bad MSG_EXIT size");
118:
119: client_write_server(cctx, MSG_EXITING, NULL, 0);
120: cctx->flags |= CCTX_EXIT;
121:
122: return (0);
123: }
124:
125: int
126: client_msg_fn_exited(
127: struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
128: {
129: if (hdr->size != 0)
130: fatalx("bad MSG_EXITED size");
131:
132: return (-1);
133: }
134:
135: int
136: client_msg_fn_suspend(
137: struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
138: {
139: struct sigaction act;
140:
141: if (hdr->size != 0)
142: fatalx("bad MSG_SUSPEND size");
143:
144: memset(&act, 0, sizeof act);
145: sigemptyset(&act.sa_mask);
146: act.sa_flags = SA_RESTART;
147:
148: act.sa_handler = SIG_DFL;
149: if (sigaction(SIGTSTP, &act, NULL) != 0)
150: fatal("sigaction failed");
151:
152: act.sa_handler = sighandler;
153: if (sigaction(SIGCONT, &act, NULL) != 0)
154: fatal("sigaction failed");
155:
156: kill(getpid(), SIGTSTP);
157:
158: return (0);
159: }