1 /* $NetBSD: ip_run.c,v 1.7 2014/01/26 21:43:45 christos Exp $ */
4 * Rob Zimmermann. All rights reserved.
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
13 #include <sys/cdefs.h>
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 ";
19 __RCSID("$NetBSD: ip_run.c,v 1.7 2014/01/26 21:43:45 christos Exp $");
22 #include <sys/types.h>
23 #include <sys/queue.h>
26 #include <bitstring.h>
34 #include <sys/socket.h>
36 #include "../common/common.h"
38 #include "pathnames.h"
40 static void arg_format
__P((char *, int *, char **[], int, int));
41 static void fatal
__P((void)) __dead
;
43 static void attach
__P((void));
45 static int channel(int rpipe
[2], int wpipe
[2]);
47 const char *vi_progname
= "vi"; /* Global: program name. */
53 * PUBLIC: int vi_run __P((IPVI *, int, char *[]));
56 vi_run(ipvi
, argc
, argv
)
62 int pflag
, rpipe
[2], wpipe
[2];
63 char *execp
, **p_av
, **t_av
;
66 execp
= __UNCONST(vi_progname
);
68 /* Strip out any arguments that vi isn't going to understand. */
69 for (p_av
= t_av
= argv
;;) {
74 if (!strcmp(*t_av
, "--")) {
75 while ((*p_av
++ = *++t_av
) != NULL
);
79 if (!memcmp(*t_av
, "-D", sizeof("-D") - 1)) {
88 if (!memcmp(*t_av
, "-T", sizeof("-T") - 1)) {
89 char *p
= &t_av
[0][sizeof("-T") - 1];
100 if (!memcmp(*t_av
, "-P", sizeof("-P") - 1)) {
101 if (t_av
[0][2] != '\0') {
108 if (t_av
[1] != NULL
) {
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)
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
135 arg_format(execp
, &argc
, &argv
, wpipe
[0], rpipe
[1]);
138 switch (ipvi
->pid
= fork()) {
139 case -1: /* Error. */
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
);
155 (void)fprintf(stderr
,
156 "%s: %s %s\n", vi_progname
, execp
, strerror(errno
));
157 (void)fprintf(stderr
,
159 "usage: %s [-D] [-P vi_program] [-T trace] [vi arguments]\n",
161 "usage: %s [-P vi_program] [vi arguments]\n",
165 default: /* Parent: Screen. */
166 (void)close(rpipe
[1]);
167 (void)close(wpipe
[0]);
182 (void)fprintf(stderr
, "%s: %s\n", vi_progname
, strerror(errno
));
187 channel(int rpipe
[2], int wpipe
[2])
190 if ((x
= pipe(rpipe
) == -1) || pipe(wpipe
) == -1) {
198 if (socketpair(AF_LOCAL
, SOCK_STREAM
, 0, sockets
) == -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)) {
218 * Reformat our arguments to add the -I argument for vi.
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
)
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
)
237 /* Create the -I argument. */
238 (void)sprintf(iarg
, "-I%d%s%d", i_fd
, ".", o_fd
);
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
)
246 /* Reset the argument array. */
253 * Pause and let the user attach a debugger.
261 (void)printf("process %lu waiting, enter <CR> to continue: ",
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
));
271 if (read(fd
, &ch
, 1) != 1) {
275 } while (ch
!= '\n' && ch
!= '\r');