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