Home | History | Annotate | Line # | Download | only in ipc
ipc_method.c revision 1.2
      1 /*	$NetBSD: ipc_method.c,v 1.2 2013/11/22 15:52:05 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 	socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets);
     96 
     97 	mh.msg_namelen = 0;
     98 	mh.msg_iovlen = 1;
     99 	mh.msg_iov = &iov;
    100 	mh.msg_controllen = sizeof(ch);
    101 	mh.msg_control = (void *)&ch;
    102 
    103 	iov.iov_len = 1;
    104 	iov.iov_base = &dummy;
    105 
    106 	ch.header.cmsg_level = SOL_SOCKET;
    107 	ch.header.cmsg_type = SCM_RIGHTS;
    108 	ch.header.cmsg_len = sizeof(ch);
    109 
    110 	*(int *)CMSG_DATA(&ch.header) = sockets[1];
    111 	sendmsg(ipvi->ofd, &mh, 0);
    112 	dummy = (fd == -1) ? ' ' : 'F';
    113 	*(int *)CMSG_DATA(&ch.header) = sockets[1];
    114 	sendmsg(sockets[0], &mh, 0);
    115 	close(sockets[1]);
    116 
    117 	if (fd != -1) {
    118 		*(int *)CMSG_DATA(&ch.header) = fd;
    119 		sendmsg(sockets[0], &mh, 0);
    120 		close(fd);
    121 	}
    122 
    123 	ipviwin->ifd = sockets[0];
    124 	ipviwin->ofd = sockets[0];
    125 	}
    126 
    127 #define IPVISET(func) \
    128 	ipviwin->func = vi_##func;
    129 
    130 	IPVISET(c_bol);
    131 	IPVISET(c_bottom);
    132 	IPVISET(c_del);
    133 	IPVISET(c_eol);
    134 	IPVISET(c_insert);
    135 	IPVISET(c_left);
    136 	IPVISET(c_right);
    137 	IPVISET(c_top);
    138 	IPVISET(c_settop);
    139 	IPVISET(resize);
    140 	IPVISET(string);
    141 	IPVISET(quit);
    142 	IPVISET(wq);
    143 
    144 	IPVISET(input);
    145 	/*
    146 	IPVISET(close);
    147 	*/
    148 	ipviwin->close = vi_win_close;
    149 	IPVISET(set_ops);
    150 
    151 	*ipviwinp = ipviwin;
    152 
    153 	return 0;
    154 
    155 alloc_err:
    156 	return 1;
    157 }
    158 
    159 static int
    160 vi_set_ops(IPVIWIN *ipvi, IPSIOPS *ops)
    161 {
    162 	ipvi->si_ops = ops;
    163 	return 0;
    164 }
    165 
    166 static int  vi_close(IPVI *ipvi)
    167 {
    168 	memset(ipvi, 6, sizeof(IPVI));
    169 	free(ipvi);
    170 	return 0;
    171 }
    172 
    173 static int  vi_win_close(IPVIWIN *ipviwin)
    174 {
    175 	memset(ipviwin, 6, sizeof(IPVIWIN));
    176 	free(ipviwin);
    177 	return 0;
    178 }
    179 
    180 
    181 static int
    182 vi_send_(IPVIWIN *ipvi, int code)
    183 {
    184 	IP_BUF	ipb;
    185 	ipb.code = code;
    186 	return vi_send(ipvi->ofd, NULL, &ipb);
    187 }
    188 
    189 static int
    190 vi_send_1(IPVIWIN *ipvi, int code, u_int32_t val)
    191 {
    192 	IP_BUF	ipb;
    193 	ipb.code = code;
    194 	ipb.val1 = val;
    195 	return vi_send(ipvi->ofd, "1", &ipb);
    196 }
    197 
    198 static int
    199 vi_send_12(IPVIWIN *ipvi, int code, u_int32_t val1, u_int32_t val2)
    200 {
    201 	IP_BUF	ipb;
    202 
    203 	ipb.val1 = val1;
    204 	ipb.val2 = val2;
    205 	ipb.code = code;
    206 	return vi_send(ipvi->ofd, "12", &ipb);
    207 }
    208 
    209 static int
    210 vi_send_a(IPVIWIN *ipvi, int code, const char *str, u_int32_t len)
    211 {
    212 	IP_BUF	ipb;
    213 
    214 	ipb.str1 = str;
    215 	ipb.len1 = len;
    216 	ipb.code = code;
    217 	return vi_send(ipvi->ofd, "a", &ipb);
    218 }
    219 
    220 #if 0
    221 static int
    222 vi_send_a1(IPVIWIN *ipvi, int code, const char *str, u_int32_t len,
    223 	   u_int32_t val)
    224 {
    225 	IP_BUF	ipb;
    226 
    227 	ipb.str1 = str;
    228 	ipb.len1 = len;
    229 	ipb.val1 = val;
    230 	ipb.code = code;
    231 	return vi_send(ipvi->ofd, "a1", &ipb);
    232 }
    233 
    234 static int
    235 vi_send_ab1(IPVIWIN *ipvi, int code, const char *str1, u_int32_t len1,
    236 	    const char *str2, u_int32_t len2, u_int32_t val)
    237 {
    238 	IP_BUF	ipb;
    239 
    240 	ipb.str1 = str1;
    241 	ipb.len1 = len1;
    242 	ipb.str2 = str2;
    243 	ipb.len2 = len2;
    244 	ipb.val1 = val;
    245 	ipb.code = code;
    246 	return vi_send(ipvi->ofd, "ab1", &ipb);
    247 }
    248 #endif
    249