Remove building with NOCRYPTO option
[minix.git] / external / bsd / nvi / dist / ipc / ip_run.c
blob10ff5e7c0664249a776135dd6c6a8f7f7cb8482b
1 /* $NetBSD: ip_run.c,v 1.7 2014/01/26 21:43:45 christos Exp $ */
2 /*-
3 * Copyright (c) 1996
4 * Rob Zimmermann. All rights reserved.
5 * Copyright (c) 1996
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
9 */
11 #include "config.h"
13 #include <sys/cdefs.h>
14 #if 0
15 #ifndef lint
16 static const char sccsid[] = "Id: ip_run.c,v 8.17 2000/07/04 21:48:54 skimo Exp (Berkeley) Date: 2000/07/04 21:48:54 ";
17 #endif /* not lint */
18 #else
19 __RCSID("$NetBSD: ip_run.c,v 1.7 2014/01/26 21:43:45 christos Exp $");
20 #endif
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/stat.h>
26 #include <bitstring.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
34 #include <sys/socket.h>
36 #include "../common/common.h"
37 #include "ip.h"
38 #include "pathnames.h"
40 static void arg_format __P((char *, int *, char **[], int, int));
41 static void fatal __P((void)) __dead;
42 #ifdef DEBUG
43 static void attach __P((void));
44 #endif
45 static int channel(int rpipe[2], int wpipe[2]);
47 const char *vi_progname = "vi"; /* Global: program name. */
50 * vi_run --
51 * Run the vi program.
53 * PUBLIC: int vi_run __P((IPVI *, int, char *[]));
55 int
56 vi_run(ipvi, argc, argv)
57 IPVI *ipvi;
58 int argc;
59 char *argv[];
61 struct stat sb;
62 int pflag, rpipe[2], wpipe[2];
63 char *execp, **p_av, **t_av;
65 pflag = 0;
66 execp = __UNCONST(vi_progname);
68 /* Strip out any arguments that vi isn't going to understand. */
69 for (p_av = t_av = argv;;) {
70 if (*t_av == NULL) {
71 *p_av = NULL;
72 break;
74 if (!strcmp(*t_av, "--")) {
75 while ((*p_av++ = *++t_av) != NULL);
76 break;
78 #ifdef DEBUG
79 if (!memcmp(*t_av, "-D", sizeof("-D") - 1)) {
80 attach();
82 ++t_av;
83 --argc;
84 continue;
86 #endif
87 #ifdef TRACE
88 if (!memcmp(*t_av, "-T", sizeof("-T") - 1)) {
89 char *p = &t_av[0][sizeof("-T") - 1];
90 if (*p == '\0') {
91 --argc;
92 p = *++t_av;
94 vtrace_init(p);
95 ++t_av;
96 --argc;
97 continue;
99 #endif
100 if (!memcmp(*t_av, "-P", sizeof("-P") - 1)) {
101 if (t_av[0][2] != '\0') {
102 pflag = 1;
103 execp = t_av[0] + 2;
104 ++t_av;
105 --argc;
106 continue;
108 if (t_av[1] != NULL) {
109 pflag = 1;
110 execp = t_av[1];
111 t_av += 2;
112 argc -= 2;
113 continue;
116 *p_av++ = *t_av++;
120 * Open the communications channels. The pipes are named from the
121 * parent's viewpoint, meaning the screen reads from rpipe[0] and
122 * writes to wpipe[1]. The vi process reads from wpipe[0], and it
123 * writes to rpipe[1].
125 if (channel(rpipe, wpipe) == -1)
126 fatal();
127 ipvi->ifd = rpipe[0];
128 ipvi->ofd = wpipe[1];
131 * Reformat our arguments, adding a -I to the list. The first file
132 * descriptor for the -I argument is vi's input, and the second is
133 * vi's output.
135 arg_format(execp, &argc, &argv, wpipe[0], rpipe[1]);
137 /* Run vi. */
138 switch (ipvi->pid = fork()) {
139 case -1: /* Error. */
140 fatal();
141 /* NOTREACHED */
142 case 0: /* Child: Vi. */
143 (void)close(rpipe[0]);
144 (void)close(wpipe[1]);
147 * If the user didn't override the path and there's a local
148 * (debugging) nvi, run it, otherwise run the user's path,
149 * if specified, else run the compiled in path.
151 /* coverity[+toctou] */
152 if (!pflag && stat("vi-ipc", &sb) == 0)
153 execvp("vi-ipc", argv);
154 execvp(execp, argv);
155 (void)fprintf(stderr,
156 "%s: %s %s\n", vi_progname, execp, strerror(errno));
157 (void)fprintf(stderr,
158 #ifdef DEBUG
159 "usage: %s [-D] [-P vi_program] [-T trace] [vi arguments]\n",
160 #else
161 "usage: %s [-P vi_program] [vi arguments]\n",
162 #endif
163 vi_progname);
164 _exit (1);
165 default: /* Parent: Screen. */
166 (void)close(rpipe[1]);
167 (void)close(wpipe[0]);
168 break;
170 free(argv[1]);
171 free(argv);
172 return (0);
176 * fatal --
177 * Fatal error.
179 static void
180 fatal()
182 (void)fprintf(stderr, "%s: %s\n", vi_progname, strerror(errno));
183 exit (1);
186 static int
187 channel(int rpipe[2], int wpipe[2])
189 int x;
190 if ((x = pipe(rpipe) == -1) || pipe(wpipe) == -1) {
191 int sockets[2];
193 if (x != -1) {
194 close(rpipe[0]);
195 close(rpipe[1]);
198 if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sockets) == -1)
199 return -1;
201 rpipe[0] = sockets[0];
202 wpipe[0] = sockets[1];
203 if (((rpipe[1] = dup(sockets[1])) == -1) ||
204 ((wpipe[1] = dup(sockets[0])) == -1)) {
205 close(sockets[0]);
206 close(sockets[1]);
207 if (rpipe[1] != -1)
208 close(rpipe[1]);
209 return -1;
213 return 0;
217 * arg_format --
218 * Reformat our arguments to add the -I argument for vi.
220 static void
221 arg_format(char *execp, int *argcp, char **argvp[], int i_fd, int o_fd)
223 char *iarg, **largv = NULL /* XXX gcc */, *p, **p_av, **t_av;
225 /* Get space for the argument array and the -I argument. */
226 if ((iarg = malloc(64)) == NULL ||
227 (largv = malloc((*argcp + 3) * sizeof(char *))) == NULL)
228 fatal();
229 memcpy(largv + 2, *argvp, *argcp * sizeof(char *) + 1);
231 /* Reset argv[0] to be the exec'd program. */
232 if ((p = strrchr(execp, '/')) == NULL)
233 largv[0] = execp;
234 else
235 largv[0] = p + 1;
237 /* Create the -I argument. */
238 (void)sprintf(iarg, "-I%d%s%d", i_fd, ".", o_fd);
239 largv[1] = iarg;
241 /* Copy any remaining arguments into the array. */
242 for (p_av = (*argvp) + 1, t_av = largv + 2;;)
243 if ((*t_av++ = *p_av++) == NULL)
244 break;
246 /* Reset the argument array. */
247 *argvp = largv;
250 #ifdef DEBUG
252 * attach --
253 * Pause and let the user attach a debugger.
255 static void
256 attach()
258 int fd;
259 char ch;
261 (void)printf("process %lu waiting, enter <CR> to continue: ",
262 (u_long)getpid());
263 (void)fflush(stdout);
265 if ((fd = open(_PATH_TTY, O_RDONLY, 0)) < 0) {
266 (void)fprintf(stderr,
267 "%s: %s, %s\n", vi_progname, _PATH_TTY, strerror(errno));
268 exit (1);;
270 do {
271 if (read(fd, &ch, 1) != 1) {
272 (void)close(fd);
273 return;
275 } while (ch != '\n' && ch != '\r');
276 (void)close(fd);
278 #endif