xref: /csrg-svn/contrib/ed/main.c (revision 58315)
157694Sbostic /*-
257694Sbostic  * Copyright (c) 1992 The Regents of the University of California.
357694Sbostic  * All rights reserved.
457694Sbostic  *
557694Sbostic  * This code is derived from software contributed to Berkeley by
657694Sbostic  * Rodney Ruddock of the University of Guelph.
757694Sbostic  *
857694Sbostic  * %sccs.include.redist.c%
957694Sbostic  */
1057694Sbostic 
1157694Sbostic #ifndef lint
12*58315Sbostic static char sccsid[] = "@(#)main.c	5.3 (Berkeley) 02/28/93";
1357694Sbostic #endif /* not lint */
1457694Sbostic 
1557710Sbostic #include <sys/types.h>
16*58315Sbostic #include <sys/ioctl.h>
1757710Sbostic 
18*58315Sbostic #include <limits.h>
1957710Sbostic #include <regex.h>
2057710Sbostic #include <setjmp.h>
2157710Sbostic #include <signal.h>
2257710Sbostic #include <stdio.h>
2357710Sbostic #include <stdlib.h>
2457710Sbostic #include <string.h>
2557710Sbostic 
26*58315Sbostic #ifdef DBI
27*58315Sbostic #include <db.h>
28*58315Sbostic #endif
29*58315Sbostic 
3057694Sbostic #include "ed.h"
3157710Sbostic #include "extern.h"
3257694Sbostic 
3357694Sbostic /*
3457694Sbostic  * This is where all of the "global" variables are declared. They are
3557694Sbostic  * set for extern in the ed.h header file (so everyone can get them).
3657694Sbostic  */
3757694Sbostic 
3857694Sbostic int nn_max, nn_max_flag, start_default, End_default, address_flag;
39*58315Sbostic int zsnum, filename_flag, add_flag=0, join_flag=0;
4057694Sbostic int help_flag=0;
41*58315Sbostic #ifdef STDIO
42*58315Sbostic FILE *fhtmp;
43*58315Sbostic int file_seek;
44*58315Sbostic #endif
4557694Sbostic 
46*58315Sbostic #ifdef DBI
4757694Sbostic DB *dbhtmp;
48*58315Sbostic #endif
4957694Sbostic 
5057694Sbostic LINE *nn_max_start, *nn_max_end;
5157694Sbostic 
5257694Sbostic struct MARK mark_matrix[26]; /* in init set all to null */
5357694Sbostic 
5457694Sbostic char *text;
5557694Sbostic char *filename_current, *prompt_string=NULL, help_msg[130];
5657694Sbostic char *template=NULL;
5757694Sbostic int prompt_str_flg=0, start_up_flag=0, name_set=0;
5857694Sbostic 
5957694Sbostic LINE *top, *current, *bottom, *start, *End;
6057694Sbostic struct u_layer *u_stk;
6157694Sbostic struct d_layer *d_stk;
6257694Sbostic LINE *u_current, *u_top, *u_bottom;
6357694Sbostic int u_set;
6457694Sbostic regex_t RE_comp;
6557694Sbostic regmatch_t RE_match[RE_SEC];
6657694Sbostic int RE_sol=0, RE_flag=0;
6757694Sbostic char *RE_patt=NULL;
6857694Sbostic 
6957694Sbostic int ss; /* for the getc() */
7057694Sbostic int explain_flag=1, g_flag=0, GV_flag=0, printsfx=0;
7157694Sbostic long change_flag=0L;
7257694Sbostic int line_length;
73*58315Sbostic jmp_buf ctrl_position, ctrl_position2; /* For SIGnal handling. */
74*58315Sbostic int sigint_flag, sighup_flag, sigspecial=0, sigspecial2=0;
7557694Sbostic 
7657710Sbostic static void sigint_handler __P((int));
7757710Sbostic static void sighup_handler __P((int));
7857710Sbostic 
7957710Sbostic /*
8057710Sbostic  * Starts the whole show going. Set things up as the arguments spec
8157710Sbostic  * in the shell and set a couple of the global variables.
8257710Sbostic  *
8357710Sbostic  * Note naming viol'n with errnum for consistancy.
8457694Sbostic  */
8557710Sbostic int
8657710Sbostic main(argc, argv)
8757710Sbostic 	int argc;
8857710Sbostic 	char *argv[];
8957694Sbostic {
90*58315Sbostic 	int l_num, errnum = 0, l_err = 0;
91*58315Sbostic 	char *l_fnametmp, *l_col;
92*58315Sbostic 	struct winsize win;
9357694Sbostic 
94*58315Sbostic 	line_length = ((l_col = getenv("COLUMNS")) == NULL ? 0 : atoi(l_col));
95*58315Sbostic 	if (line_length == 0 && isatty(STDOUT_FILENO) &&
96*58315Sbostic 		ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1)
97*58315Sbostic 		line_length = win.ws_col;
98*58315Sbostic 	if (line_length == 0)
99*58315Sbostic 		line_length = 78;
10057694Sbostic 
10157710Sbostic 	start = End = NULL;
10257710Sbostic 	top = bottom = NULL;
10357710Sbostic 	current = NULL;
10457710Sbostic 	nn_max_flag = 0;
10557710Sbostic 	nn_max_start = nn_max_end = NULL;
10657710Sbostic 	l_fnametmp = calloc(FILENAME_LEN, sizeof(char));
10757710Sbostic 	if (l_fnametmp == NULL)
10857710Sbostic 		ed_exit(4);
10957710Sbostic 	text = calloc(NN_MAX_START + 2, sizeof(char));
11057710Sbostic 	if (text == NULL)
11157710Sbostic 		ed_exit(4);
11257710Sbostic 	start_default = End_default = 0;
11357710Sbostic 	zsnum = 22;		/* for the 'z' command */
11457710Sbostic 	u_stk = NULL;
11557710Sbostic 	d_stk = NULL;
11657710Sbostic 	u_current = u_top = u_bottom = NULL;
11757710Sbostic 	u_set = 0;		/* for in d after a j */
11857710Sbostic 	filename_flag = 0;
11957710Sbostic 	filename_current = NULL;
12057694Sbostic 
12157710Sbostic 	l_num = 1;
12257710Sbostic 	for (;;) {
12357710Sbostic 		/* Process the command line options */
12457710Sbostic 		if (l_num >= argc)
12557710Sbostic 			break;
12657710Sbostic 		switch (argv[l_num][0]) {
12757710Sbostic 		case '-':
12857710Sbostic 			switch (argv[l_num][1]) {
12957710Sbostic 			case '\0':	/* this is why 'getopt' not used */
13057710Sbostic 			case 's':
13157710Sbostic 				explain_flag = 0;
13257710Sbostic 				break;
13357710Sbostic 			case 'p':
13457710Sbostic 				if (++l_num < argc) {
13557710Sbostic 					prompt_string =
13657710Sbostic 					    calloc(strlen(argv[l_num]),
13757710Sbostic 					    sizeof(char));
13857710Sbostic 					if (prompt_string == NULL)
13957710Sbostic 						ed_exit(4);
14057710Sbostic 					strcpy(prompt_string, argv[l_num]);
14157710Sbostic 					prompt_str_flg = 1;
14257710Sbostic 					break;
14357710Sbostic 				}
14457710Sbostic 				l_err = 1;
14557710Sbostic 			default:
14657710Sbostic 				l_err++;
14757710Sbostic 				ed_exit(l_err);
14857710Sbostic 			}
14957710Sbostic 			break;
15057710Sbostic 		default:
15157710Sbostic 			if (name_set)
15257710Sbostic 				ed_exit(3);
15357710Sbostic 			strcpy(l_fnametmp, argv[l_num]);
15457710Sbostic 			filename_current = l_fnametmp;
15557710Sbostic 			name_set = 1;
15657710Sbostic 			if (prompt_str_flg)
15757710Sbostic 				break;
15857710Sbostic 			/* default ed prompt */
15957710Sbostic 			prompt_string = (char *) calloc(3, sizeof(char));
16057710Sbostic 			strcpy(prompt_string, "*");
16157710Sbostic 			break;
16257710Sbostic 		}
16357710Sbostic 		l_num++;
16457710Sbostic 	}
16557710Sbostic 
16657710Sbostic 	start_up_flag = 1;
16757710Sbostic 	cmd_loop(stdin, &errnum);
16857710Sbostic 	/* NOTREACHED */
16957710Sbostic }
17057710Sbostic 
17157694Sbostic /*
17257710Sbostic  * The command loop. What the command is that the user has specified
17357694Sbostic  * is determined here. This is not just for commands coming from
17457694Sbostic  * the terminal but any standard i/o stream; see the global commands.
17557694Sbostic  * Some of the commands are handled within here (i.e. 'H') while most
17657694Sbostic  * are handled in their own functions (as called).
17757694Sbostic  */
17857694Sbostic void
17957694Sbostic cmd_loop(inputt, errnum)
18057710Sbostic 	FILE *inputt;
18157710Sbostic 	int *errnum;
18257694Sbostic {
18357710Sbostic 	LINE *l_tempp;
18457710Sbostic 	int l_last, l_jmp_flag;
18557694Sbostic 
186*58315Sbostic 	l_last = 0; /* value in l_last may be clobbered (reset to = 0) by longjump, but that's okay */
18757694Sbostic 
18857710Sbostic 	if (g_flag == 0) {	/* big, BIG trouble if we don't check! think. */
18957710Sbostic 		/* set the jump point for the signals */
19057710Sbostic 		l_jmp_flag = setjmp(ctrl_position);
19157710Sbostic 		signal(SIGINT, sigint_handler);
19257710Sbostic 		signal(SIGHUP, sighup_handler);
19357710Sbostic 		switch (l_jmp_flag) {
19457710Sbostic 		case JMP_SET:
19557710Sbostic 			break;
19657710Sbostic 		/* Some general cleanup not specific to the jmp pt. */
19757710Sbostic 		case INTERUPT:
19857710Sbostic 			sigint_flag = 0;
19957710Sbostic 			GV_flag = 0;	/* safest place to do these flags */
20057710Sbostic 			g_flag = 0;
201*58315Sbostic 			printf("\n?\n");
20257710Sbostic 			break;
20357710Sbostic 		case HANGUP:		/* shouldn't get here. */
20457710Sbostic 			break;
20557710Sbostic 		default:
20657710Sbostic 			(void)fprintf(stderr, "Signal jump problem\n");
20757710Sbostic 		}
20857710Sbostic 		/* Only do this once! */
20957710Sbostic 		if (start_up_flag) {
21057710Sbostic 			start_up_flag = 0;
21157710Sbostic 			/* simulate the 'e' at startup */
21257710Sbostic 			e2(inputt, errnum);
21357710Sbostic 		}
21457710Sbostic 	}
21557710Sbostic 	for (;;) {
21657710Sbostic 		if (prompt_str_flg == 1)
21757710Sbostic 			(void)printf("%s", prompt_string);
21857710Sbostic 		ss = getc(inputt);
21957710Sbostic 		*errnum = 0;
22057710Sbostic 		l_tempp = start = End = NULL;
22157710Sbostic 		start_default = End_default = 1;
22257694Sbostic 
22357710Sbostic 		/*
22457710Sbostic 		 * This isn't nice and alphabetical mainly because of
22557710Sbostic 		 * restrictions with 'G' and 'V' (see ed(1)).
22657710Sbostic 		 */
22757710Sbostic 		for (;;) {
22857710Sbostic 			switch (ss) {
22957710Sbostic 			case 'd':
23057710Sbostic 				d(inputt, errnum);
23157710Sbostic 				break;
23257710Sbostic 			case 'e':
23357710Sbostic 			case 'E':
23457710Sbostic 				e(inputt, errnum);
23557710Sbostic 				break;
23657710Sbostic 			case 'f':
23757710Sbostic 				f(inputt, errnum);
23857710Sbostic 				break;
23957710Sbostic 			case 'a':
24057710Sbostic 			case 'c':
24157710Sbostic 			case 'i':
24257710Sbostic 			case 'g':
24357710Sbostic 			case 'G':
24457710Sbostic 			case 'v':
24557710Sbostic 			case 'V':
24657710Sbostic 				if (GV_flag == 1) {
24757710Sbostic 					(void)sprintf(help_msg,
24857710Sbostic 					    "command `%c' illegal in G/V", ss);
24957710Sbostic 					*errnum = -1;
25057710Sbostic 					break;
25157710Sbostic 				}
25257710Sbostic 				switch (ss) {
25357710Sbostic 				case 'a':
25457710Sbostic 					a(inputt, errnum);
25557710Sbostic 					break;
25657710Sbostic 				case 'c':
25757710Sbostic 					c(inputt, errnum);
25857710Sbostic 					break;
25957710Sbostic 				case 'i':
26057710Sbostic 					i(inputt, errnum);
26157710Sbostic 					break;
26257710Sbostic 				default:
26357710Sbostic 					g(inputt, errnum);
26457710Sbostic 				}
26557710Sbostic 				break;
26657710Sbostic 			case 'h':
26757710Sbostic 				if (rol(inputt, errnum))
26857710Sbostic 					break;
26957710Sbostic 				(void)printf("%s\n", help_msg);
27057710Sbostic 				*errnum = 1;
27157710Sbostic 				break;
27257710Sbostic 			case 'H':
27357710Sbostic 				if (rol(inputt, errnum))
27457710Sbostic 					break;
27557710Sbostic 				if (help_flag == 0) {
27657710Sbostic 					help_flag = 1;
27757710Sbostic 					printf("%?: %s\n", help_msg);
27857710Sbostic 				} else
27957710Sbostic 					help_flag = 0;
28057710Sbostic 				*errnum = 1;
28157710Sbostic 				break;
28257710Sbostic 			case 'j':
28357710Sbostic 				j(inputt, errnum);
28457710Sbostic 				break;
28557710Sbostic 			case 'k':
28657710Sbostic 				set_mark(inputt, errnum);
28757710Sbostic 				break;
28857710Sbostic 			case 'l':
28957710Sbostic 				l(inputt, errnum);
29057710Sbostic 				break;
29157710Sbostic 			case 'm':
29257710Sbostic 				m(inputt, errnum);
29357710Sbostic 				break;
29457694Sbostic #ifdef POSIX
29557710Sbostic 				/* In POSIX-land 'P' toggles the prompt. */
29657710Sbostic 			case 'P':
29757710Sbostic 				if (rol(inputt, errnum))
29857710Sbostic 					break;
29957710Sbostic 				prompt_str_flg = prompt_str_flg ? 0 : 1;
30057710Sbostic 				*errnum = 1;
30157710Sbostic 				break;
30257694Sbostic #endif
30357710Sbostic 			case '\n':
30457710Sbostic 				if (GV_flag == 1)
30557710Sbostic 					return;
30657710Sbostic 				/* For 'p' to consume. */
30757710Sbostic 				ungetc(ss, inputt);
30857710Sbostic 				if ((current == bottom) && (End == NULL)) {
30957710Sbostic 					strcpy(help_msg, "at end of buffer");
31057710Sbostic 					*errnum = -1;
31157710Sbostic 					break;
31257710Sbostic 				}
31357710Sbostic 				current = current->below;
31457694Sbostic #ifdef BSD
31557710Sbostic 				/* In BSD 'P'=='p'. */
31657710Sbostic 			case 'P':
31757694Sbostic #endif
31857710Sbostic 			case 'p':
31957710Sbostic 				p(inputt, errnum, 0);
32057710Sbostic 				break;
32157710Sbostic 			case 'n':
32257710Sbostic 				p(inputt, errnum, 1);
32357710Sbostic 				break;
32457710Sbostic 			/*
32557710Sbostic 			 * An EOF means 'q' unless we're still in the middle
32657710Sbostic 			 * of a global command, in which case it was just the
32757710Sbostic 			 * end of the command list found.
32857710Sbostic 			 */
32957710Sbostic 			case EOF:
33057710Sbostic 				clearerr(inputt);
33157710Sbostic 				if (g_flag > 0)
33257710Sbostic 					return;
33357710Sbostic 				ss = 'q';
33457710Sbostic 			case 'q':
33557710Sbostic 			case 'Q':
33657710Sbostic 				q(inputt, errnum);
33757710Sbostic 				break;
33857710Sbostic 			case 'r':
33957710Sbostic 				r(inputt, errnum);
34057710Sbostic 				break;
34157710Sbostic 			case 's':
34257710Sbostic 				s(inputt, errnum);
34357710Sbostic 				break;
34457710Sbostic 			case 't':
34557710Sbostic 				t(inputt, errnum);
34657710Sbostic 				break;
34757710Sbostic 			case 'u':
34857710Sbostic 				u(inputt, errnum);
34957710Sbostic 				break;
35057710Sbostic 			case 'w':
35157710Sbostic 			case 'W':
35257710Sbostic 				w(inputt, errnum);
35357710Sbostic 				break;
35457710Sbostic 			case 'z':
35557710Sbostic 				z(inputt, errnum);
35657710Sbostic 				break;
35757710Sbostic 			case '!':
35857710Sbostic 				bang(inputt, errnum);
35957710Sbostic 				break;
36057710Sbostic 			case '=':
36157710Sbostic 				equal(inputt, errnum);
36257710Sbostic 				break;
36357710Sbostic 			/*
36457710Sbostic 			 * Control of address forms from here down.
36557710Sbostic 			 *
36657710Sbostic 			 * It's a head-game to understand why ";" and "," look
36757710Sbostic 			 * as they do below, but a lot of it has to do with ";"
36857710Sbostic 			 * and "," being special address pair forms themselves
36957710Sbostic 			 * and the compatibility for address "chains".
37057710Sbostic 			 */
37157710Sbostic 			case ';':
37257710Sbostic 				if (End_default == 1 && start_default == 1) {
37357710Sbostic 					start = current;
37457710Sbostic 					End = bottom;
37557710Sbostic 					start_default = End_default = 0;
37657710Sbostic 				} else {
37757710Sbostic 					start = current = End;
37857710Sbostic 					start_default = 0;
37957710Sbostic 					End_default = 1;
38057710Sbostic 				}
38157710Sbostic 				l_tempp = NULL;
38257710Sbostic 				break;
38357710Sbostic 			/*
38457710Sbostic 			 * Note address ".,x" where x is a cmd is legal; not a
38557710Sbostic 			 * bug - for backward compatability.
38657710Sbostic 			 */
38757710Sbostic 			case ',':
38857710Sbostic 				if (End_default == 1 && start_default == 1) {
38957710Sbostic 					start = top;
39057710Sbostic 					End = bottom;
39157710Sbostic 					start_default = End_default = 0;
39257710Sbostic 				} else {
39357710Sbostic 					start = End;
39457710Sbostic 					start_default = 0;
39557710Sbostic 					End_default = 1;
39657710Sbostic 				}
39757710Sbostic 				l_tempp = NULL;
39857710Sbostic 				break;
39957710Sbostic 			case '%':
40057710Sbostic 				if (End_default == 0) {
40157710Sbostic 					strcpy(help_msg,
40257710Sbostic 					    "'%' is an address pair");
40357710Sbostic 					*errnum = -1;
40457710Sbostic 					break;
40557710Sbostic 				}
40657710Sbostic 				start = top;
40757710Sbostic 				End = bottom;
40857710Sbostic 				start_default = End_default = 0;
40957710Sbostic 				l_tempp = NULL;
41057710Sbostic 				break;
41157710Sbostic 			/*
41257710Sbostic 			 * Within address_conv => l_last = '+', foobar, but
41357710Sbostic 			 * historical and now POSIX...
41457710Sbostic 			 */
41557710Sbostic 			case ' ':
41657710Sbostic 				break;
41757710Sbostic 			case '0':
41857710Sbostic 			case '1':
41957710Sbostic 			case '2':
42057710Sbostic 			case '3':
42157710Sbostic 			case '4':
42257710Sbostic 			case '5':
42357710Sbostic 			case '6':
42457710Sbostic 			case '7':
42557710Sbostic 			case '8':
42657710Sbostic 			case '9':
42757710Sbostic 			case '-':
42857710Sbostic 			case '^':
42957710Sbostic 			case '+':
43057710Sbostic 			case '\'':
43157710Sbostic 			case '$':
43257710Sbostic 			case '?':
43357710Sbostic 			case '/':
43457710Sbostic 			case '.':
43557710Sbostic 				ungetc(ss, inputt);
43657710Sbostic 				if (start_default == 0 && End_default == 0) {
43757710Sbostic 					strcpy(help_msg,
43857710Sbostic 					    "badly formed address");
43957710Sbostic 					*errnum = -1;
44057710Sbostic 					break;
44157710Sbostic 				}
44257710Sbostic 				ss = l_last;
44357710Sbostic 				l_tempp = address_conv(l_tempp, inputt, errnum);
44457710Sbostic 				if (*errnum < 0)
44557710Sbostic 					break;
44657710Sbostic 				End = l_tempp;
44757710Sbostic 				End_default = 0;
44857710Sbostic 				if (start_default == 0)
44957710Sbostic 					*errnum = address_check(start, End);
45057710Sbostic 				break;
45157710Sbostic 			default:
45257710Sbostic 				*errnum = -1;
45357710Sbostic 				strcpy(help_msg, "unknown command");
45457710Sbostic 				break;
45557710Sbostic 			}	/* end-switch(ss) */
45657694Sbostic 
45757710Sbostic 			/* Things came out okay with the last command. */
45857710Sbostic 			if (*errnum > 0) {
45957710Sbostic 				if (GV_flag == 1)
46057710Sbostic 					return;
46157710Sbostic 				/* Do the suffixes if there were any. */
46257710Sbostic 				if (printsfx > 0) {
46357710Sbostic 					start = End = current;
46457710Sbostic 					ungetc(ss, inputt);
46557710Sbostic 					if (printsfx == 1)
46657710Sbostic 						p(inputt, errnum, 0);
46757710Sbostic 					else
46857710Sbostic 						if (printsfx == 2)
46957710Sbostic 							p(inputt, errnum, 1);
47057710Sbostic 						else if (printsfx == 4)
47157710Sbostic 							l(inputt, errnum);
47257710Sbostic 					/* Unlikely it's needed, but... */
47357710Sbostic 					if (*errnum < 0)
47457710Sbostic 						goto errmsg;
47557710Sbostic 				}
47657710Sbostic 				break;
47757710Sbostic 			}
47857710Sbostic 			/* There was a problem with the last command. */
47957710Sbostic 			else if (*errnum < 0) {
48057710Sbostic errmsg:				while (((ss = getc(inputt)) != '\n') &&
48157710Sbostic 				    (ss != EOF));
482*58315Sbostic 				if (help_flag == 1)
483*58315Sbostic 					printf("%?: %s\n", help_msg);
484*58315Sbostic 				else
485*58315Sbostic 					printf("?\n");
486*58315Sbostic 				if (g_flag > 0)
487*58315Sbostic 					return;
488*58315Sbostic 				break;
48957710Sbostic 			}
49057710Sbostic 			l_last = ss;
49157710Sbostic 			ss = getc(inputt);
49257710Sbostic 		}
49357710Sbostic 	}
49457710Sbostic }
49557694Sbostic 
49657710Sbostic /*
49757710Sbostic  * Exits ed and prints an appropriate message about the command line
49857694Sbostic  * being malformed (see below).
49957694Sbostic  */
50057694Sbostic void
50157694Sbostic ed_exit(err)
50257710Sbostic 	int err;
50357694Sbostic {
50457710Sbostic 	switch (err) {
50557710Sbostic           case 1:
50657710Sbostic 		(void)fprintf(stderr, "ed: illegal option\n");
50757710Sbostic 		break;
50857710Sbostic           case 2:
50957710Sbostic 		(void)fprintf(stderr, "ed: missing promptstring\n");
51057710Sbostic 		break;
51157710Sbostic           case 3:
51257710Sbostic 		(void)fprintf(stderr, "ed: too many filenames\n");
51357710Sbostic 		break;
51457710Sbostic           case 4:
51557710Sbostic 		(void)fprintf(stderr, "ed: out of memory error\n");
51657710Sbostic 		break;
517*58315Sbostic 	  case 5:
518*58315Sbostic 		(void)fprintf(stderr, "ed: unable to create buffer\n");
519*58315Sbostic 		break;
52057710Sbostic           default:
52157710Sbostic 		(void)fprintf(stderr, "ed: command line error\n");
52257710Sbostic 		break;
52357710Sbostic         }
52457710Sbostic 	(void)fprintf(stderr,
52557710Sbostic 	    "ed: ed [ -s ] [ -p promptstring ] [ filename ]\n");
52657710Sbostic 	exit(1);
52757710Sbostic }
52857694Sbostic 
52957694Sbostic /*
53057710Sbostic  * SIGINT is never turned off. We flag it happened and then pay attention
53157710Sbostic  * to it at certain logical locations in the code we don't do more here
53257710Sbostic  * cause some of our buffer pointer's may be in an inbetween state at the
53357710Sbostic  * time of the SIGINT. So we flag it happened, let the local fn handle it
53457710Sbostic  * and do a jump back to the cmd_loop
53557694Sbostic  */
53657710Sbostic static void
53757710Sbostic sigint_handler(signo)
53857710Sbostic 	int signo;
53957710Sbostic {
54057710Sbostic 	sigint_flag = 1;
541*58315Sbostic 	if (sigspecial2) {
542*58315Sbostic 		sigspecial2 = 0;
543*58315Sbostic 		SIGINT_ILACTION;
544*58315Sbostic 	}
545*58315Sbostic 	else
546*58315Sbostic 		if (sigspecial);
547*58315Sbostic 		else
548*58315Sbostic 			SIGINT_ACTION;
54957710Sbostic }
55057694Sbostic 
55157710Sbostic static void
55257710Sbostic sighup_handler(signo)
55357710Sbostic 	int signo;
55457694Sbostic {
55557710Sbostic 	(void)fprintf(stderr,"\n  SIGHUP \n");
55657710Sbostic 	sighup_flag = 1;
55757710Sbostic 	undo();
55857710Sbostic 	do_hup();
55957710Sbostic 	/* NOTREACHED */
56057694Sbostic 
56157710Sbostic 	SIGHUP_ACTION;
56257710Sbostic }
563