3 * Rob Zimmermann. All rights reserved.
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
13 static const char sccsid
[] = "$Id: ip_run.c,v 8.10 1996/12/17 14:51:09 bostic Exp $ (Berkeley) $Date: 1996/12/17 14:51:09 $";
16 #include <sys/types.h>
17 #include <sys/queue.h>
20 #include <bitstring.h>
28 #include "../common/common.h"
30 #include "ipc_extern.h"
31 #include "pathnames.h"
33 static void arg_format
__P((char *, int *, char **[], int, int));
34 static void fatal
__P((void));
36 static void attach
__P((void));
39 int vi_ofd
= -1; /* Global: output fd. */
40 char *vi_progname
= "vi"; /* Global: program name. */
46 * PUBLIC: int vi_run __P((int, char *[], int *, int *, pid_t *));
49 vi_run(argc
, argv
, ip
, op
, pidp
)
55 int pflag
, rpipe
[2], wpipe
[2];
56 char *execp
, *p
, **p_av
, **t_av
;
61 /* Strip out any arguments that vi isn't going to understand. */
62 for (p_av
= t_av
= argv
;;) {
67 if (!strcmp(*t_av
, "--")) {
68 while ((*p_av
++ = *++t_av
) != NULL
);
72 if (!memcmp(*t_av
, "-D", sizeof("-D") - 1)) {
81 if (!memcmp(*t_av
, "-T", sizeof("-T") - 1)) {
82 p
= &t_av
[0][sizeof("-T") - 1];
93 if (!memcmp(*t_av
, "-P", sizeof("-P") - 1)) {
94 if (t_av
[0][2] != '\0') {
101 if (t_av
[1] != NULL
) {
113 * Open the communications channels. The pipes are named from the
114 * parent's viewpoint, meaning the screen reads from rpipe[0] and
115 * writes to wpipe[1]. The vi process reads from wpipe[0], and it
116 * writes to rpipe[1].
118 if (pipe(rpipe
) == -1 || pipe(wpipe
) == -1)
124 * Reformat our arguments, adding a -I to the list. The first file
125 * descriptor for the -I argument is vi's input, and the second is
128 arg_format(execp
, &argc
, &argv
, wpipe
[0], rpipe
[1]);
131 switch (*pidp
= fork()) {
132 case -1: /* Error. */
135 case 0: /* Child: Vi. */
136 (void)close(rpipe
[0]);
137 (void)close(wpipe
[1]);
140 * If the user didn't override the path and there's a local
141 * (debugging) nvi, run it, otherwise run the user's path,
142 * if specified, else run the compiled in path.
144 if (!pflag
&& stat("vi", &sb
) == 0)
147 (void)fprintf(stderr
,
148 "%s: %s %s\n", vi_progname
, execp
, strerror(errno
));
149 (void)fprintf(stderr
,
151 "usage: %s [-D] [-P vi_program] [-T trace] [vi arguments]\n",
153 "usage: %s [-P vi_program] [vi arguments]\n",
157 default: /* Parent: Screen. */
158 (void)close(rpipe
[1]);
159 (void)close(wpipe
[0]);
172 (void)fprintf(stderr
, "%s: %s\n", vi_progname
, strerror(errno
));
178 * Reformat our arguments to add the -I argument for vi.
181 arg_format(execp
, argcp
, argvp
, i_fd
, o_fd
)
182 char *execp
, **argvp
[];
183 int *argcp
, i_fd
, o_fd
;
185 char *iarg
, **largv
, *p
, **p_av
, **t_av
;
187 /* Get space for the argument array and the -I argument. */
188 if ((iarg
= malloc(64)) == NULL
||
189 (largv
= malloc((*argcp
+ 3) * sizeof(char *))) == NULL
)
191 memcpy(largv
+ 2, *argvp
, *argcp
* sizeof(char *) + 1);
193 /* Reset argv[0] to be the exec'd program. */
194 if ((p
= strrchr(execp
, '/')) == NULL
)
199 /* Create the -I argument. */
200 (void)sprintf(iarg
, "-I%d%s%d", i_fd
, ".", o_fd
);
203 /* Copy any remaining arguments into the array. */
204 for (p_av
= (*argvp
) + 1, t_av
= largv
+ 2;;)
205 if ((*t_av
++ = *p_av
++) == NULL
)
208 /* Reset the argument array. */
215 * Pause and let the user attach a debugger.
223 (void)printf("process %lu waiting, enter <CR> to continue: ",
225 (void)fflush(stdout
);
227 if ((fd
= open(_PATH_TTY
, O_RDONLY
, 0)) < 0) {
228 (void)fprintf(stderr
,
229 "%s: %s, %s\n", vi_progname
, _PATH_TTY
, strerror(errno
));
233 if (read(fd
, &ch
, 1) != 1) {
237 } while (ch
!= '\n' && ch
!= '\r');