Annotation of src/usr.bin/tmux/client-msg.c, Revision 1.1
1.1 ! nicm 1: /* $OpenBSD$ */
! 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: {
! 76: if (hdr->size > SIZE_MAX - 1)
! 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(
! 88: struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
! 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(
! 101: struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
! 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(
! 114: struct hdr *hdr, unused struct client_ctx *cctx, unused char **error)
! 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: }