1 1.6 christos /* $NetBSD: ipc_method.c,v 1.6 2013/11/27 20:52:24 christos Exp $ */ 2 1.1 christos /*- 3 1.1 christos * Copyright (c) 1996 4 1.1 christos * Rob Zimmermann. All rights reserved. 5 1.1 christos * Copyright (c) 1996 6 1.1 christos * Keith Bostic. All rights reserved. 7 1.1 christos * 8 1.1 christos * See the LICENSE file for redistribution information. 9 1.1 christos */ 10 1.1 christos 11 1.1 christos #include "config.h" 12 1.1 christos 13 1.1 christos #include <sys/types.h> 14 1.1 christos #include <sys/queue.h> 15 1.1 christos #include <sys/stat.h> 16 1.1 christos 17 1.1 christos #include <bitstring.h> 18 1.1 christos #include <errno.h> 19 1.1 christos #include <fcntl.h> 20 1.1 christos #include <stdio.h> 21 1.1 christos #include <stdlib.h> 22 1.1 christos #include <string.h> 23 1.1 christos #include <unistd.h> 24 1.1 christos 25 1.1 christos #include <sys/uio.h> 26 1.1 christos 27 1.1 christos #include "../common/common.h" 28 1.1 christos #include "ip.h" 29 1.1 christos 30 1.1 christos static int vi_send_ __P((IPVIWIN *, int)); 31 1.1 christos static int vi_send_1 __P((IPVIWIN *, int, u_int32_t )); 32 1.1 christos static int vi_send_12 __P((IPVIWIN *ipvi, int code, u_int32_t val1, u_int32_t val2)); 33 1.2 christos #if 0 34 1.1 christos static int vi_send_ab1 __P((IPVIWIN *ipvi, int code, 35 1.1 christos const char *str1, u_int32_t len1, 36 1.1 christos const char *str2, u_int32_t len2, u_int32_t val)); 37 1.1 christos static int vi_send_a1 __P((IPVIWIN *ipvi, int code, const char *str, u_int32_t len, 38 1.1 christos u_int32_t val)); 39 1.2 christos #endif 40 1.1 christos static int vi_send_a __P((IPVIWIN *ipvi, int code, const char *str, u_int32_t len)); 41 1.1 christos 42 1.1 christos #include "ipc_gen.c" 43 1.1 christos 44 1.1 christos static int vi_set_ops __P((IPVIWIN *, IPSIOPS *)); 45 1.1 christos static int vi_win_close __P((IPVIWIN *)); 46 1.1 christos 47 1.1 christos static int vi_close __P((IPVI *)); 48 1.1 christos static int vi_new_window __P((IPVI *, IPVIWIN **, int)); 49 1.1 christos 50 1.1 christos /* 51 1.1 christos * vi_create 52 1.1 christos * 53 1.1 christos * PUBLIC: int vi_create __P((IPVI **, u_int32_t)); 54 1.1 christos */ 55 1.1 christos int 56 1.1 christos vi_create(IPVI **ipvip, u_int32_t flags) 57 1.1 christos { 58 1.1 christos IPVI *ipvi; 59 1.1 christos 60 1.1 christos MALLOC_GOTO(NULL, ipvi, IPVI*, sizeof(IPVI)); 61 1.1 christos memset(ipvi, 0, sizeof(IPVI)); 62 1.1 christos 63 1.1 christos ipvi->flags = flags; 64 1.1 christos 65 1.1 christos ipvi->run = vi_run; 66 1.1 christos ipvi->new_window = vi_new_window; 67 1.1 christos ipvi->close = vi_close; 68 1.1 christos 69 1.1 christos *ipvip = ipvi; 70 1.1 christos 71 1.1 christos return 0; 72 1.1 christos 73 1.1 christos alloc_err: 74 1.1 christos return 1; 75 1.1 christos } 76 1.1 christos 77 1.1 christos static int 78 1.1 christos vi_new_window (IPVI *ipvi, IPVIWIN **ipviwinp, int fd) 79 1.1 christos { 80 1.1 christos IPVIWIN *ipviwin; 81 1.1 christos 82 1.1 christos MALLOC_GOTO(NULL, ipviwin, IPVIWIN*, sizeof(IPVIWIN)); 83 1.1 christos memset(ipviwin, 0, sizeof(IPVIWIN)); 84 1.1 christos 85 1.1 christos if (0) { 86 1.1 christos ipviwin->ifd = ipvi->ifd; 87 1.1 christos ipviwin->ofd = ipvi->ofd; 88 1.1 christos } else { 89 1.1 christos int sockets[2]; 90 1.1 christos struct msghdr mh; 91 1.1 christos IPCMSGHDR ch; 92 1.1 christos char dummy; 93 1.1 christos struct iovec iov; 94 1.1 christos 95 1.5 christos if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets) == -1) 96 1.5 christos goto alloc_err; 97 1.1 christos 98 1.4 christos memset(&mh, 0, sizeof(mh)); 99 1.1 christos mh.msg_namelen = 0; 100 1.1 christos mh.msg_iovlen = 1; 101 1.1 christos mh.msg_iov = &iov; 102 1.1 christos mh.msg_controllen = sizeof(ch); 103 1.1 christos mh.msg_control = (void *)&ch; 104 1.1 christos 105 1.1 christos iov.iov_len = 1; 106 1.1 christos iov.iov_base = &dummy; 107 1.1 christos 108 1.1 christos ch.header.cmsg_level = SOL_SOCKET; 109 1.1 christos ch.header.cmsg_type = SCM_RIGHTS; 110 1.1 christos ch.header.cmsg_len = sizeof(ch); 111 1.1 christos 112 1.1 christos *(int *)CMSG_DATA(&ch.header) = sockets[1]; 113 1.6 christos if (sendmsg(ipvi->ofd, &mh, 0) == -1) 114 1.6 christos goto alloc_err; 115 1.1 christos dummy = (fd == -1) ? ' ' : 'F'; 116 1.1 christos *(int *)CMSG_DATA(&ch.header) = sockets[1]; 117 1.1 christos sendmsg(sockets[0], &mh, 0); 118 1.1 christos close(sockets[1]); 119 1.1 christos 120 1.1 christos if (fd != -1) { 121 1.1 christos *(int *)CMSG_DATA(&ch.header) = fd; 122 1.6 christos if (sendmsg(sockets[0], &mh, 0) == -1) 123 1.6 christos goto alloc_err; 124 1.1 christos close(fd); 125 1.1 christos } 126 1.1 christos 127 1.1 christos ipviwin->ifd = sockets[0]; 128 1.1 christos ipviwin->ofd = sockets[0]; 129 1.1 christos } 130 1.1 christos 131 1.1 christos #define IPVISET(func) \ 132 1.1 christos ipviwin->func = vi_##func; 133 1.1 christos 134 1.1 christos IPVISET(c_bol); 135 1.1 christos IPVISET(c_bottom); 136 1.1 christos IPVISET(c_del); 137 1.1 christos IPVISET(c_eol); 138 1.1 christos IPVISET(c_insert); 139 1.1 christos IPVISET(c_left); 140 1.1 christos IPVISET(c_right); 141 1.1 christos IPVISET(c_top); 142 1.1 christos IPVISET(c_settop); 143 1.1 christos IPVISET(resize); 144 1.1 christos IPVISET(string); 145 1.1 christos IPVISET(quit); 146 1.1 christos IPVISET(wq); 147 1.1 christos 148 1.1 christos IPVISET(input); 149 1.1 christos /* 150 1.1 christos IPVISET(close); 151 1.1 christos */ 152 1.1 christos ipviwin->close = vi_win_close; 153 1.1 christos IPVISET(set_ops); 154 1.1 christos 155 1.1 christos *ipviwinp = ipviwin; 156 1.1 christos 157 1.1 christos return 0; 158 1.1 christos 159 1.1 christos alloc_err: 160 1.6 christos if (fd != -1) 161 1.6 christos close(fd); 162 1.1 christos return 1; 163 1.1 christos } 164 1.1 christos 165 1.1 christos static int 166 1.1 christos vi_set_ops(IPVIWIN *ipvi, IPSIOPS *ops) 167 1.1 christos { 168 1.1 christos ipvi->si_ops = ops; 169 1.1 christos return 0; 170 1.1 christos } 171 1.1 christos 172 1.1 christos static int vi_close(IPVI *ipvi) 173 1.1 christos { 174 1.1 christos memset(ipvi, 6, sizeof(IPVI)); 175 1.1 christos free(ipvi); 176 1.1 christos return 0; 177 1.1 christos } 178 1.1 christos 179 1.1 christos static int vi_win_close(IPVIWIN *ipviwin) 180 1.1 christos { 181 1.1 christos memset(ipviwin, 6, sizeof(IPVIWIN)); 182 1.1 christos free(ipviwin); 183 1.1 christos return 0; 184 1.1 christos } 185 1.1 christos 186 1.1 christos 187 1.1 christos static int 188 1.1 christos vi_send_(IPVIWIN *ipvi, int code) 189 1.1 christos { 190 1.1 christos IP_BUF ipb; 191 1.3 christos 192 1.3 christos memset(&ipb, 0, sizeof(ipb)); 193 1.1 christos ipb.code = code; 194 1.1 christos return vi_send(ipvi->ofd, NULL, &ipb); 195 1.1 christos } 196 1.1 christos 197 1.1 christos static int 198 1.1 christos vi_send_1(IPVIWIN *ipvi, int code, u_int32_t val) 199 1.1 christos { 200 1.1 christos IP_BUF ipb; 201 1.3 christos 202 1.3 christos memset(&ipb, 0, sizeof(ipb)); 203 1.1 christos ipb.code = code; 204 1.1 christos ipb.val1 = val; 205 1.1 christos return vi_send(ipvi->ofd, "1", &ipb); 206 1.1 christos } 207 1.1 christos 208 1.1 christos static int 209 1.1 christos vi_send_12(IPVIWIN *ipvi, int code, u_int32_t val1, u_int32_t val2) 210 1.1 christos { 211 1.1 christos IP_BUF ipb; 212 1.1 christos 213 1.3 christos memset(&ipb, 0, sizeof(ipb)); 214 1.1 christos ipb.val1 = val1; 215 1.1 christos ipb.val2 = val2; 216 1.1 christos ipb.code = code; 217 1.1 christos return vi_send(ipvi->ofd, "12", &ipb); 218 1.1 christos } 219 1.1 christos 220 1.1 christos static int 221 1.1 christos vi_send_a(IPVIWIN *ipvi, int code, const char *str, u_int32_t len) 222 1.1 christos { 223 1.1 christos IP_BUF ipb; 224 1.1 christos 225 1.3 christos memset(&ipb, 0, sizeof(ipb)); 226 1.1 christos ipb.str1 = str; 227 1.1 christos ipb.len1 = len; 228 1.1 christos ipb.code = code; 229 1.1 christos return vi_send(ipvi->ofd, "a", &ipb); 230 1.1 christos } 231 1.1 christos 232 1.2 christos #if 0 233 1.1 christos static int 234 1.1 christos vi_send_a1(IPVIWIN *ipvi, int code, const char *str, u_int32_t len, 235 1.1 christos u_int32_t val) 236 1.1 christos { 237 1.1 christos IP_BUF ipb; 238 1.1 christos 239 1.3 christos memset(&ipb, 0, sizeof(ipb)); 240 1.1 christos ipb.str1 = str; 241 1.1 christos ipb.len1 = len; 242 1.1 christos ipb.val1 = val; 243 1.1 christos ipb.code = code; 244 1.1 christos return vi_send(ipvi->ofd, "a1", &ipb); 245 1.1 christos } 246 1.1 christos 247 1.1 christos static int 248 1.1 christos vi_send_ab1(IPVIWIN *ipvi, int code, const char *str1, u_int32_t len1, 249 1.1 christos const char *str2, u_int32_t len2, u_int32_t val) 250 1.1 christos { 251 1.1 christos IP_BUF ipb; 252 1.1 christos 253 1.3 christos memset(&ipb, 0, sizeof(ipb)); 254 1.1 christos ipb.str1 = str1; 255 1.1 christos ipb.len1 = len1; 256 1.1 christos ipb.str2 = str2; 257 1.1 christos ipb.len2 = len2; 258 1.1 christos ipb.val1 = val; 259 1.1 christos ipb.code = code; 260 1.1 christos return vi_send(ipvi->ofd, "ab1", &ipb); 261 1.1 christos } 262 1.2 christos #endif 263