1*2f698edbSchristos /* $NetBSD: main.c,v 1.6 2014/01/26 21:43:45 christos Exp $ */
2dbd550edSchristos /*-
3dbd550edSchristos * Copyright (c) 1992, 1993, 1994
4dbd550edSchristos * The Regents of the University of California. All rights reserved.
5dbd550edSchristos * Copyright (c) 1992, 1993, 1994, 1995, 1996
6dbd550edSchristos * Keith Bostic. All rights reserved.
7dbd550edSchristos *
8dbd550edSchristos * See the LICENSE file for redistribution information.
9dbd550edSchristos */
10dbd550edSchristos
11dbd550edSchristos #include "config.h"
12dbd550edSchristos
13*2f698edbSchristos #include <sys/cdefs.h>
14*2f698edbSchristos #if 0
15dbd550edSchristos #ifndef lint
16dbd550edSchristos static const char copyright[] =
17dbd550edSchristos "%Z% Copyright (c) 1992, 1993, 1994\n\
18dbd550edSchristos The Regents of the University of California. All rights reserved.\n\
19dbd550edSchristos %Z% Copyright (c) 1992, 1993, 1994, 1995, 1996\n\
20dbd550edSchristos Keith Bostic. All rights reserved.\n";
21dbd550edSchristos #endif /* not lint */
22*2f698edbSchristos #else
23*2f698edbSchristos __RCSID("$NetBSD: main.c,v 1.6 2014/01/26 21:43:45 christos Exp $");
24*2f698edbSchristos #endif
25dbd550edSchristos
26*2f698edbSchristos #include <sys/cdefs.h>
27*2f698edbSchristos #if 0
28dbd550edSchristos #ifndef lint
29dbd550edSchristos static const char sccsid[] = "Id: main.c,v 10.63 2001/11/01 15:24:43 skimo Exp (Berkeley) Date: 2001/11/01 15:24:43 ";
30dbd550edSchristos #endif /* not lint */
31*2f698edbSchristos #else
32*2f698edbSchristos __RCSID("$NetBSD: main.c,v 1.6 2014/01/26 21:43:45 christos Exp $");
33*2f698edbSchristos #endif
34dbd550edSchristos
35dbd550edSchristos #include <sys/types.h>
36dbd550edSchristos #include <sys/queue.h>
37dbd550edSchristos #include <sys/stat.h>
38dbd550edSchristos #include <sys/time.h>
39dbd550edSchristos
40dbd550edSchristos #include <bitstring.h>
41dbd550edSchristos #include <errno.h>
42dbd550edSchristos #include <fcntl.h>
43dbd550edSchristos #include <limits.h>
44dbd550edSchristos #include <stdio.h>
45dbd550edSchristos #include <stdlib.h>
46dbd550edSchristos #include <string.h>
47dbd550edSchristos #include <unistd.h>
48dbd550edSchristos
49dbd550edSchristos #include "common.h"
50dbd550edSchristos #include "../vi/vi.h"
51dbd550edSchristos #include "pathnames.h"
52dbd550edSchristos
538d01a27eSchristos static void v_estr __P((const char *, int, const char *));
54dbd550edSchristos static int v_obsolete __P((char *, char *[]));
55dbd550edSchristos
56dbd550edSchristos /*
57dbd550edSchristos * editor --
58dbd550edSchristos * Main editor routine.
59dbd550edSchristos *
60dbd550edSchristos * PUBLIC: int editor __P((WIN *, int, char *[]));
61dbd550edSchristos */
62dbd550edSchristos int
editor(WIN * wp,int argc,char ** argv)63dbd550edSchristos editor(WIN *wp, int argc, char **argv)
64dbd550edSchristos {
65dbd550edSchristos extern int optind;
66dbd550edSchristos extern char *optarg;
67dbd550edSchristos const char *p;
68dbd550edSchristos EVENT ev;
69dbd550edSchristos FREF *frp;
70dbd550edSchristos SCR *sp;
71dbd550edSchristos GS *gp;
72dbd550edSchristos size_t len;
73dbd550edSchristos u_int flags;
74dbd550edSchristos int ch, flagchk, lflag, secure, startup, readonly, rval, silent;
758d01a27eSchristos #ifdef GTAGS
768d01a27eSchristos int gtags = 0;
778d01a27eSchristos #endif
78dbd550edSchristos char *tag_f, *wsizearg, path[256];
798d01a27eSchristos const CHAR_T *w;
80dbd550edSchristos size_t wlen;
81dbd550edSchristos
82dbd550edSchristos gp = wp->gp;
83dbd550edSchristos
84dbd550edSchristos /* Initialize the busy routine, if not defined by the screen. */
85dbd550edSchristos if (gp->scr_busy == NULL)
86dbd550edSchristos gp->scr_busy = vs_busy;
87dbd550edSchristos /* Initialize the message routine, if not defined by the screen. */
88dbd550edSchristos if (wp->scr_msg == NULL)
89dbd550edSchristos wp->scr_msg = vs_msg;
90dbd550edSchristos
91dbd550edSchristos /* Set initial screen type and mode based on the program name. */
92dbd550edSchristos readonly = 0;
93dbd550edSchristos if (!strcmp(gp->progname, "ex") || !strcmp(gp->progname, "nex"))
94dbd550edSchristos LF_INIT(SC_EX);
95dbd550edSchristos else {
96dbd550edSchristos /* Nview, view are readonly. */
97dbd550edSchristos if (!strcmp(gp->progname, "nview") ||
98dbd550edSchristos !strcmp(gp->progname, "view"))
99dbd550edSchristos readonly = 1;
100dbd550edSchristos
101dbd550edSchristos /* Vi is the default. */
102dbd550edSchristos LF_INIT(SC_VI);
103dbd550edSchristos }
104dbd550edSchristos
105dbd550edSchristos /* Convert old-style arguments into new-style ones. */
106dbd550edSchristos if (v_obsolete(gp->progname, argv))
107dbd550edSchristos return (1);
108dbd550edSchristos
109dbd550edSchristos /* Parse the arguments. */
110dbd550edSchristos flagchk = '\0';
111dbd550edSchristos tag_f = wsizearg = NULL;
112dbd550edSchristos lflag = secure = silent = 0;
113dbd550edSchristos startup = 1;
114dbd550edSchristos
115dbd550edSchristos /* Set the file snapshot flag. */
116dbd550edSchristos F_SET(gp, G_SNAPSHOT);
117dbd550edSchristos
1188d01a27eSchristos while ((ch = getopt(argc, argv, "c:"
119dbd550edSchristos #ifdef DEBUG
1208d01a27eSchristos "D:"
121dbd550edSchristos #endif
1228d01a27eSchristos "eF"
1238d01a27eSchristos #ifdef GTAGS
1248d01a27eSchristos "G"
1258d01a27eSchristos #endif
1268d01a27eSchristos "lRrSsT:t:vw:")) != EOF)
127dbd550edSchristos switch (ch) {
128dbd550edSchristos case 'c': /* Run the command. */
129dbd550edSchristos /*
130dbd550edSchristos * XXX
131dbd550edSchristos * We should support multiple -c options.
132dbd550edSchristos */
133dbd550edSchristos if (gp->c_option != NULL) {
134dbd550edSchristos v_estr(gp->progname, 0,
135dbd550edSchristos "only one -c command may be specified.");
136dbd550edSchristos return (1);
137dbd550edSchristos }
138dbd550edSchristos gp->c_option = optarg;
139dbd550edSchristos break;
140dbd550edSchristos #ifdef DEBUG
141dbd550edSchristos case 'D':
142dbd550edSchristos switch (optarg[0]) {
143dbd550edSchristos case 's':
144dbd550edSchristos startup = 0;
145dbd550edSchristos break;
146dbd550edSchristos case 'w':
147dbd550edSchristos attach(gp);
148dbd550edSchristos break;
149dbd550edSchristos default:
150dbd550edSchristos v_estr(gp->progname, 0,
151dbd550edSchristos "usage: -D requires s or w argument.");
152dbd550edSchristos return (1);
153dbd550edSchristos }
154dbd550edSchristos break;
155dbd550edSchristos #endif
156dbd550edSchristos case 'e': /* Ex mode. */
157dbd550edSchristos LF_CLR(SC_VI);
158dbd550edSchristos LF_SET(SC_EX);
159dbd550edSchristos break;
160dbd550edSchristos case 'F': /* No snapshot. */
161dbd550edSchristos v_estr(gp->progname, 0,
162dbd550edSchristos "-F option no longer supported.");
163dbd550edSchristos break;
164dbd550edSchristos case 'l': /* Set lisp, showmatch options. */
165dbd550edSchristos lflag = 1;
166dbd550edSchristos break;
1678d01a27eSchristos #ifdef GTAGS
1688d01a27eSchristos case 'G': /* gtags mode. */
1698d01a27eSchristos gtags = 1;
1708d01a27eSchristos break;
1718d01a27eSchristos #endif
172dbd550edSchristos case 'R': /* Readonly. */
173dbd550edSchristos readonly = 1;
174dbd550edSchristos break;
175dbd550edSchristos case 'r': /* Recover. */
176dbd550edSchristos if (flagchk == 't') {
177dbd550edSchristos v_estr(gp->progname, 0,
178dbd550edSchristos "only one of -r and -t may be specified.");
179dbd550edSchristos return (1);
180dbd550edSchristos }
181dbd550edSchristos flagchk = 'r';
182dbd550edSchristos break;
183dbd550edSchristos case 'S':
184dbd550edSchristos secure = 1;
185dbd550edSchristos break;
186dbd550edSchristos case 's':
187dbd550edSchristos silent = 1;
188dbd550edSchristos break;
189dbd550edSchristos #ifdef TRACE
190dbd550edSchristos case 'T': /* Trace. */
191dbd550edSchristos (void)vtrace_init(optarg);
192dbd550edSchristos break;
193dbd550edSchristos #endif
194dbd550edSchristos case 't': /* Tag. */
195dbd550edSchristos if (flagchk == 'r') {
196dbd550edSchristos v_estr(gp->progname, 0,
197dbd550edSchristos "only one of -r and -t may be specified.");
198dbd550edSchristos return (1);
199dbd550edSchristos }
200dbd550edSchristos if (flagchk == 't') {
201dbd550edSchristos v_estr(gp->progname, 0,
202dbd550edSchristos "only one tag file may be specified.");
203dbd550edSchristos return (1);
204dbd550edSchristos }
205dbd550edSchristos flagchk = 't';
206dbd550edSchristos tag_f = optarg;
207dbd550edSchristos break;
208dbd550edSchristos case 'v': /* Vi mode. */
209dbd550edSchristos LF_CLR(SC_EX);
210dbd550edSchristos LF_SET(SC_VI);
211dbd550edSchristos break;
212dbd550edSchristos case 'w':
213dbd550edSchristos wsizearg = optarg;
214dbd550edSchristos break;
215dbd550edSchristos case '?':
216dbd550edSchristos default:
217dbd550edSchristos (void)gp->scr_usage();
218dbd550edSchristos return (1);
219dbd550edSchristos }
220dbd550edSchristos argc -= optind;
221dbd550edSchristos argv += optind;
222dbd550edSchristos
223dbd550edSchristos /*
224dbd550edSchristos * -s option is only meaningful to ex.
225dbd550edSchristos *
226dbd550edSchristos * If not reading from a terminal, it's like -s was specified.
227dbd550edSchristos */
228dbd550edSchristos if (silent && !LF_ISSET(SC_EX)) {
229dbd550edSchristos v_estr(gp->progname, 0, "-s option is only applicable to ex.");
230dbd550edSchristos goto err;
231dbd550edSchristos }
232dbd550edSchristos if (LF_ISSET(SC_EX) && F_ISSET(gp, G_SCRIPTED))
233dbd550edSchristos silent = 1;
234dbd550edSchristos
235dbd550edSchristos /*
236dbd550edSchristos * Build and initialize the first/current screen. This is a bit
237dbd550edSchristos * tricky. If an error is returned, we may or may not have a
238dbd550edSchristos * screen structure. If we have a screen structure, put it on a
239dbd550edSchristos * display queue so that the error messages get displayed.
240dbd550edSchristos *
241dbd550edSchristos * !!!
242dbd550edSchristos * Everything we do until we go interactive is done in ex mode.
243dbd550edSchristos */
244dbd550edSchristos if (screen_init(gp, NULL, &sp)) {
245dbd550edSchristos if (sp != NULL) {
246d89691f9Schristos TAILQ_INSERT_HEAD(&wp->scrq, sp, q);
247dbd550edSchristos sp->wp = wp;
248dbd550edSchristos }
249dbd550edSchristos goto err;
250dbd550edSchristos }
251dbd550edSchristos F_SET(sp, SC_EX);
252d89691f9Schristos TAILQ_INSERT_HEAD(&wp->scrq, sp, q);
253dbd550edSchristos sp->wp = wp;
254dbd550edSchristos
255dbd550edSchristos if (v_key_init(sp)) /* Special key initialization. */
256dbd550edSchristos goto err;
257dbd550edSchristos
258dbd550edSchristos { int oargs[5], *oargp = oargs;
259dbd550edSchristos if (lflag) { /* Command-line options. */
260dbd550edSchristos *oargp++ = O_LISP;
261dbd550edSchristos *oargp++ = O_SHOWMATCH;
262dbd550edSchristos }
263dbd550edSchristos if (readonly)
264dbd550edSchristos *oargp++ = O_READONLY;
2658d01a27eSchristos #ifdef GTAGS
2668d01a27eSchristos if (gtags)
2678d01a27eSchristos *oargp++ = O_GTAGSMODE;
2688d01a27eSchristos #endif
269dbd550edSchristos if (secure)
270dbd550edSchristos *oargp++ = O_SECURE;
271dbd550edSchristos *oargp = -1; /* Options initialization. */
272dbd550edSchristos if (opts_init(sp, oargs))
273dbd550edSchristos goto err;
274dbd550edSchristos }
275dbd550edSchristos if (wsizearg != NULL) {
276dbd550edSchristos ARGS *av[2], a, b;
277dbd550edSchristos (void)snprintf(path, sizeof(path), "window=%s", wsizearg);
278dbd550edSchristos a.bp = (CHAR_T *)path;
279dbd550edSchristos a.len = strlen(path);
280dbd550edSchristos b.bp = NULL;
281dbd550edSchristos b.len = 0;
282dbd550edSchristos av[0] = &a;
283dbd550edSchristos av[1] = &b;
284dbd550edSchristos (void)opts_set(sp, av, NULL);
285dbd550edSchristos }
286dbd550edSchristos if (silent) { /* Ex batch mode option values. */
287dbd550edSchristos O_CLR(sp, O_AUTOPRINT);
288dbd550edSchristos O_CLR(sp, O_PROMPT);
289dbd550edSchristos O_CLR(sp, O_VERBOSE);
290dbd550edSchristos O_CLR(sp, O_WARN);
291dbd550edSchristos F_SET(sp, SC_EX_SILENT);
292dbd550edSchristos }
293dbd550edSchristos
294dbd550edSchristos sp->rows = O_VAL(sp, O_LINES); /* Make ex formatting work. */
295dbd550edSchristos sp->cols = O_VAL(sp, O_COLUMNS);
296dbd550edSchristos
297dbd550edSchristos if (!silent && startup) { /* Read EXINIT, exrc files. */
298dbd550edSchristos if (ex_exrc(sp))
299dbd550edSchristos goto err;
300dbd550edSchristos if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) {
301dbd550edSchristos if (screen_end(sp))
302dbd550edSchristos goto err;
303dbd550edSchristos goto done;
304dbd550edSchristos }
305dbd550edSchristos }
306dbd550edSchristos
307dbd550edSchristos /*
308dbd550edSchristos * List recovery files if -r specified without file arguments.
309dbd550edSchristos * Note, options must be initialized and startup information
310dbd550edSchristos * read before doing this.
311dbd550edSchristos */
312dbd550edSchristos if (flagchk == 'r' && argv[0] == NULL) {
313dbd550edSchristos if (rcv_list(sp))
314dbd550edSchristos goto err;
315dbd550edSchristos if (screen_end(sp))
316dbd550edSchristos goto err;
317dbd550edSchristos goto done;
318dbd550edSchristos }
319dbd550edSchristos
320dbd550edSchristos /*
321dbd550edSchristos * !!!
322dbd550edSchristos * Initialize the default ^D, ^U scrolling value here, after the
323dbd550edSchristos * user has had every opportunity to set the window option.
324dbd550edSchristos *
325dbd550edSchristos * It's historic practice that changing the value of the window
326dbd550edSchristos * option did not alter the default scrolling value, only giving
327dbd550edSchristos * a count to ^D/^U did that.
328dbd550edSchristos */
329dbd550edSchristos sp->defscroll = (O_VAL(sp, O_WINDOW) + 1) / 2;
330dbd550edSchristos
331dbd550edSchristos /*
332dbd550edSchristos * If we don't have a command-line option, switch into the right
333dbd550edSchristos * editor now, so that we position default files correctly, and
334dbd550edSchristos * so that any tags file file-already-locked messages are in the
335dbd550edSchristos * vi screen, not the ex screen.
336dbd550edSchristos *
337dbd550edSchristos * XXX
338dbd550edSchristos * If we have a command-line option, the error message can end
339dbd550edSchristos * up in the wrong place, but I think that the combination is
340dbd550edSchristos * unlikely.
341dbd550edSchristos */
342dbd550edSchristos if (gp->c_option == NULL) {
343dbd550edSchristos F_CLR(sp, SC_EX | SC_VI);
344dbd550edSchristos F_SET(sp, LF_ISSET(SC_EX | SC_VI));
345dbd550edSchristos }
346dbd550edSchristos
347dbd550edSchristos /* Open a tag file if specified. */
348dbd550edSchristos if (tag_f != NULL) {
349dbd550edSchristos CHAR2INT(sp, tag_f, strlen(tag_f) + 1, w, wlen);
350dbd550edSchristos if (ex_tag_first(sp, w))
351dbd550edSchristos goto err;
352dbd550edSchristos }
353dbd550edSchristos
354dbd550edSchristos /*
355dbd550edSchristos * Append any remaining arguments as file names. Files are recovery
356dbd550edSchristos * files if -r specified. If the tag option or ex startup commands
357dbd550edSchristos * loaded a file, then any file arguments are going to come after it.
358dbd550edSchristos */
359dbd550edSchristos if (*argv != NULL) {
360dbd550edSchristos if (sp->frp != NULL) {
361dbd550edSchristos /* Cheat -- we know we have an extra argv slot. */
362dbd550edSchristos MALLOC_NOMSG(sp,
363dbd550edSchristos *--argv, char *, strlen(sp->frp->name) + 1);
364dbd550edSchristos if (*argv == NULL) {
365dbd550edSchristos v_estr(gp->progname, errno, NULL);
366dbd550edSchristos goto err;
367dbd550edSchristos }
368dbd550edSchristos (void)strcpy(*argv, sp->frp->name);
369dbd550edSchristos }
370dbd550edSchristos sp->argv = sp->cargv = argv;
371dbd550edSchristos F_SET(sp, SC_ARGNOFREE);
372dbd550edSchristos if (flagchk == 'r')
373dbd550edSchristos F_SET(sp, SC_ARGRECOVER);
374dbd550edSchristos }
375dbd550edSchristos
376dbd550edSchristos /*
377dbd550edSchristos * If the ex startup commands and or/the tag option haven't already
378dbd550edSchristos * created a file, create one. If no command-line files were given,
379dbd550edSchristos * use a temporary file.
380dbd550edSchristos */
381dbd550edSchristos if (sp->frp == NULL) {
382dbd550edSchristos if (sp->argv == NULL) {
383dbd550edSchristos if ((frp = file_add(sp, NULL)) == NULL)
384dbd550edSchristos goto err;
385dbd550edSchristos } else {
386dbd550edSchristos if ((frp = file_add(sp, sp->argv[0])) == NULL)
387dbd550edSchristos goto err;
388dbd550edSchristos if (F_ISSET(sp, SC_ARGRECOVER))
389dbd550edSchristos F_SET(frp, FR_RECOVER);
390dbd550edSchristos }
391dbd550edSchristos
392dbd550edSchristos if (file_init(sp, frp, NULL, 0))
393dbd550edSchristos goto err;
394dbd550edSchristos if (EXCMD_RUNNING(wp)) {
395dbd550edSchristos (void)ex_cmd(sp);
396dbd550edSchristos if (F_ISSET(sp, SC_EXIT | SC_EXIT_FORCE)) {
397dbd550edSchristos if (screen_end(sp))
398dbd550edSchristos goto err;
399dbd550edSchristos goto done;
400dbd550edSchristos }
401dbd550edSchristos }
402dbd550edSchristos }
403dbd550edSchristos
404dbd550edSchristos /*
405dbd550edSchristos * Check to see if we need to wait for ex. If SC_SCR_EX is set, ex
406dbd550edSchristos * was forced to initialize the screen during startup. We'd like to
407dbd550edSchristos * wait for a single character from the user, but we can't because
408dbd550edSchristos * we're not in raw mode. We can't switch to raw mode because the
409dbd550edSchristos * vi initialization will switch to xterm's alternate screen, causing
410dbd550edSchristos * us to lose the messages we're pausing to make sure the user read.
411dbd550edSchristos * So, wait for a complete line.
412dbd550edSchristos */
413dbd550edSchristos if (F_ISSET(sp, SC_SCR_EX)) {
414dbd550edSchristos p = msg_cmsg(sp, CMSG_CONT_R, &len);
415dbd550edSchristos (void)write(STDOUT_FILENO, p, len);
416dbd550edSchristos for (;;) {
417dbd550edSchristos if (v_event_get(sp, &ev, 0, 0))
418dbd550edSchristos goto err;
419dbd550edSchristos if (ev.e_event == E_INTERRUPT ||
420dbd550edSchristos (ev.e_event == E_CHARACTER &&
421dbd550edSchristos (ev.e_value == K_CR || ev.e_value == K_NL)))
422dbd550edSchristos break;
423dbd550edSchristos (void)gp->scr_bell(sp);
424dbd550edSchristos }
425dbd550edSchristos }
426dbd550edSchristos
427dbd550edSchristos /* Switch into the right editor, regardless. */
428dbd550edSchristos F_CLR(sp, SC_EX | SC_VI);
429dbd550edSchristos F_SET(sp, LF_ISSET(SC_EX | SC_VI) | SC_STATUS_CNT);
430dbd550edSchristos
431dbd550edSchristos /*
432dbd550edSchristos * Main edit loop. Vi handles split screens itself, we only return
433dbd550edSchristos * here when switching editor modes or restarting the screen.
434dbd550edSchristos */
435dbd550edSchristos while (sp != NULL)
436dbd550edSchristos if (F_ISSET(sp, SC_EX) ? ex(&sp) : vi(&sp))
437dbd550edSchristos goto err;
438dbd550edSchristos
439dbd550edSchristos done: rval = 0;
440dbd550edSchristos if (0)
441dbd550edSchristos err: rval = 1;
442dbd550edSchristos
443dbd550edSchristos return (rval);
444dbd550edSchristos }
445dbd550edSchristos
446dbd550edSchristos /*
447dbd550edSchristos * v_obsolete --
448dbd550edSchristos * Convert historic arguments into something getopt(3) will like.
449dbd550edSchristos */
450dbd550edSchristos static int
v_obsolete(char * name,char ** argv)451dbd550edSchristos v_obsolete(char *name, char **argv)
452dbd550edSchristos {
453dbd550edSchristos size_t len;
454dbd550edSchristos char *p;
455dbd550edSchristos
456dbd550edSchristos /*
457dbd550edSchristos * Translate old style arguments into something getopt will like.
458dbd550edSchristos * Make sure it's not text space memory, because ex modifies the
459dbd550edSchristos * strings.
460dbd550edSchristos * Change "+" into "-c$".
461dbd550edSchristos * Change "+<anything else>" into "-c<anything else>".
462dbd550edSchristos * Change "-" into "-s"
463dbd550edSchristos * The c, T, t and w options take arguments so they can't be
464dbd550edSchristos * special arguments.
465dbd550edSchristos *
466dbd550edSchristos * Stop if we find "--" as an argument, the user may want to edit
467dbd550edSchristos * a file named "+foo".
468dbd550edSchristos */
469dbd550edSchristos while (*++argv && strcmp(argv[0], "--"))
470dbd550edSchristos if (argv[0][0] == '+') {
471dbd550edSchristos if (argv[0][1] == '\0') {
472dbd550edSchristos MALLOC_NOMSG(NULL, argv[0], char *, 4);
473dbd550edSchristos if (argv[0] == NULL)
474dbd550edSchristos goto nomem;
475dbd550edSchristos (void)strcpy(argv[0], "-c$");
476dbd550edSchristos } else {
477dbd550edSchristos p = argv[0];
478dbd550edSchristos len = strlen(argv[0]);
479dbd550edSchristos MALLOC_NOMSG(NULL, argv[0], char *, len + 2);
480dbd550edSchristos if (argv[0] == NULL)
481dbd550edSchristos goto nomem;
482dbd550edSchristos argv[0][0] = '-';
483dbd550edSchristos argv[0][1] = 'c';
484dbd550edSchristos (void)strcpy(argv[0] + 2, p + 1);
485dbd550edSchristos }
486dbd550edSchristos } else if (argv[0][0] == '-') {
487dbd550edSchristos if (argv[0][1] == '\0') {
488dbd550edSchristos MALLOC_NOMSG(NULL, argv[0], char *, 3);
489dbd550edSchristos if (argv[0] == NULL) {
490dbd550edSchristos nomem: v_estr(name, errno, NULL);
491dbd550edSchristos return (1);
492dbd550edSchristos }
493dbd550edSchristos (void)strcpy(argv[0], "-s");
494dbd550edSchristos } else
495dbd550edSchristos if ((argv[0][1] == 'c' || argv[0][1] == 'T' ||
496dbd550edSchristos argv[0][1] == 't' || argv[0][1] == 'w') &&
497dbd550edSchristos argv[0][2] == '\0')
498dbd550edSchristos ++argv;
499dbd550edSchristos }
500dbd550edSchristos return (0);
501dbd550edSchristos }
502dbd550edSchristos
503dbd550edSchristos #ifdef DEBUG
504dbd550edSchristos static void
attach(GS * gp)505dbd550edSchristos attach(GS *gp)
506dbd550edSchristos {
507dbd550edSchristos int fd;
508dbd550edSchristos char ch;
509dbd550edSchristos
510dbd550edSchristos if ((fd = open(_PATH_TTY, O_RDONLY, 0)) < 0) {
511dbd550edSchristos v_estr(gp->progname, errno, _PATH_TTY);
512dbd550edSchristos return;
513dbd550edSchristos }
514dbd550edSchristos
515dbd550edSchristos (void)printf("process %lu waiting, enter <CR> to continue: ",
516dbd550edSchristos (u_long)getpid());
517dbd550edSchristos (void)fflush(stdout);
518dbd550edSchristos
519dbd550edSchristos do {
520dbd550edSchristos if (read(fd, &ch, 1) != 1) {
521dbd550edSchristos (void)close(fd);
522dbd550edSchristos return;
523dbd550edSchristos }
524dbd550edSchristos } while (ch != '\n' && ch != '\r');
525dbd550edSchristos (void)close(fd);
526dbd550edSchristos }
527dbd550edSchristos #endif
528dbd550edSchristos
529dbd550edSchristos static void
v_estr(const char * name,int eno,const char * msg)5308d01a27eSchristos v_estr(const char *name, int eno, const char *msg)
531dbd550edSchristos {
532dbd550edSchristos (void)fprintf(stderr, "%s", name);
533dbd550edSchristos if (msg != NULL)
534dbd550edSchristos (void)fprintf(stderr, ": %s", msg);
535dbd550edSchristos if (eno)
536dbd550edSchristos (void)fprintf(stderr, ": %s", strerror(errno));
537dbd550edSchristos (void)fprintf(stderr, "\n");
538dbd550edSchristos }
539