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 1259475Sbostic char copyright[] = 1359475Sbostic "@(#) Copyright (c) 1992 The Regents of the University of California.\n\ 1459475Sbostic All rights reserved.\n"; 1557694Sbostic #endif /* not lint */ 1657694Sbostic 1759475Sbostic #ifndef lint 18*59915Sbostic static char sccsid[] = "@(#)main.c 5.12 (Berkeley) 05/11/93"; 1959475Sbostic #endif /* not lint */ 2059475Sbostic 2157710Sbostic #include <sys/types.h> 2258315Sbostic #include <sys/ioctl.h> 2357710Sbostic 2459477Sbostic #include <limits.h> 2557710Sbostic #include <regex.h> 2657710Sbostic #include <setjmp.h> 2757710Sbostic #include <signal.h> 2857710Sbostic #include <stdio.h> 2957710Sbostic #include <stdlib.h> 3057710Sbostic #include <string.h> 3159477Sbostic #include <unistd.h> 3257710Sbostic 3358315Sbostic #ifdef DBI 3458315Sbostic #include <db.h> 3558315Sbostic #endif 3658315Sbostic 3757694Sbostic #include "ed.h" 3857710Sbostic #include "extern.h" 3957694Sbostic 4057694Sbostic /* 4157694Sbostic * This is where all of the "global" variables are declared. They are 4257694Sbostic * set for extern in the ed.h header file (so everyone can get them). 4357694Sbostic */ 4457694Sbostic 4558564Sralph int nn_max, nn_max_flag, Start_default, End_default, address_flag; 4658315Sbostic int zsnum, filename_flag, add_flag=0, join_flag=0; 4759558Sbostic int help_flag=0, gut_num=-1; 4858315Sbostic #ifdef STDIO 4958315Sbostic FILE *fhtmp; 5058315Sbostic int file_seek; 5158315Sbostic #endif 5257694Sbostic 5358315Sbostic #ifdef DBI 5457694Sbostic DB *dbhtmp; 5558315Sbostic #endif 5657694Sbostic 5757694Sbostic LINE *nn_max_start, *nn_max_end; 5857694Sbostic 5957694Sbostic struct MARK mark_matrix[26]; /* in init set all to null */ 6057694Sbostic 6157694Sbostic char *text; 6259475Sbostic LINE **gut=NULL; 6357694Sbostic char *filename_current, *prompt_string=NULL, help_msg[130]; 6457694Sbostic char *template=NULL; 6557694Sbostic int prompt_str_flg=0, start_up_flag=0, name_set=0; 6657694Sbostic 6758564Sralph LINE *top, *current, *bottom, *Start, *End; 6857694Sbostic struct u_layer *u_stk; 6957694Sbostic struct d_layer *d_stk; 7057694Sbostic LINE *u_current, *u_top, *u_bottom; 7157694Sbostic int u_set; 7257694Sbostic regex_t RE_comp; 7357694Sbostic regmatch_t RE_match[RE_SEC]; 7457694Sbostic int RE_sol=0, RE_flag=0; 7557694Sbostic char *RE_patt=NULL; 7657694Sbostic 7757694Sbostic int ss; /* for the getc() */ 7859475Sbostic int explain_flag=1, g_flag=0, GV_flag=0, printsfx=0, exit_code=0; 7957694Sbostic long change_flag=0L; 8057694Sbostic int line_length; 8158352Sbostic jmp_buf ctrl_position, ctrl_position2, ctrl_position3; /* For SIGnal handling. */ 8258352Sbostic int sigint_flag, sighup_flag, sigspecial=0, sigspecial2=0, sigspecial3=0; 8357694Sbostic 8457710Sbostic static void sigint_handler __P((int)); 8557710Sbostic static void sighup_handler __P((int)); 8657710Sbostic 8757710Sbostic /* 8857710Sbostic * Starts the whole show going. Set things up as the arguments spec 8957710Sbostic * in the shell and set a couple of the global variables. 9057710Sbostic * 9157710Sbostic * Note naming viol'n with errnum for consistancy. 9257694Sbostic */ 9357710Sbostic int 9457710Sbostic main(argc, argv) 9557710Sbostic int argc; 9657710Sbostic char *argv[]; 9757694Sbostic { 98*59915Sbostic int l_num, errnum=0, l_err=0; 9958710Sbostic char *l_fnametmp, *l_col, buf[2]; 10058315Sbostic struct winsize win; 10157694Sbostic 10258710Sbostic setbuffer(stdin, buf, 1); 10358315Sbostic line_length = ((l_col = getenv("COLUMNS")) == NULL ? 0 : atoi(l_col)); 10459475Sbostic if ((line_length == 0 && isatty(STDOUT_FILENO) && 10559475Sbostic ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) != -1)) 10658315Sbostic line_length = win.ws_col; 10758315Sbostic if (line_length == 0) 10858315Sbostic line_length = 78; 10957694Sbostic 11058564Sralph Start = End = NULL; 11157710Sbostic top = bottom = NULL; 11257710Sbostic current = NULL; 11357710Sbostic nn_max_flag = 0; 11457710Sbostic nn_max_start = nn_max_end = NULL; 11557710Sbostic l_fnametmp = calloc(FILENAME_LEN, sizeof(char)); 11657710Sbostic if (l_fnametmp == NULL) 11757710Sbostic ed_exit(4); 11857710Sbostic text = calloc(NN_MAX_START + 2, sizeof(char)); 11957710Sbostic if (text == NULL) 12057710Sbostic ed_exit(4); 12158564Sralph Start_default = End_default = 0; 12257710Sbostic zsnum = 22; /* for the 'z' command */ 12359558Sbostic help_msg[0] = '\0'; 12457710Sbostic u_stk = NULL; 12557710Sbostic d_stk = NULL; 12657710Sbostic u_current = u_top = u_bottom = NULL; 12757710Sbostic u_set = 0; /* for in d after a j */ 12857710Sbostic filename_flag = 0; 12957710Sbostic filename_current = NULL; 13057694Sbostic 13157710Sbostic l_num = 1; 13257710Sbostic for (;;) { 13357710Sbostic /* Process the command line options */ 13457710Sbostic if (l_num >= argc) 13557710Sbostic break; 13657710Sbostic switch (argv[l_num][0]) { 13757710Sbostic case '-': 13857710Sbostic switch (argv[l_num][1]) { 13957710Sbostic case '\0': /* this is why 'getopt' not used */ 14057710Sbostic case 's': 14157710Sbostic explain_flag = 0; 14257710Sbostic break; 14357710Sbostic case 'p': 14457710Sbostic if (++l_num < argc) { 14557710Sbostic prompt_string = 14657710Sbostic calloc(strlen(argv[l_num]), 14757710Sbostic sizeof(char)); 14857710Sbostic if (prompt_string == NULL) 14957710Sbostic ed_exit(4); 15057710Sbostic strcpy(prompt_string, argv[l_num]); 15157710Sbostic prompt_str_flg = 1; 15257710Sbostic break; 15357710Sbostic } 15457710Sbostic l_err = 1; 15558710Sbostic case 'v': 15658710Sbostic #ifdef BSD 15759558Sbostic (void)printf("ed: in BSD mode:\n"); 15858710Sbostic #endif 15958710Sbostic #ifdef POSIX 16059558Sbostic (void)printf("ed: in POSIX mode:\n"); 16158710Sbostic #endif 16259475Sbostic break; 16357710Sbostic default: 16457710Sbostic l_err++; 16557710Sbostic ed_exit(l_err); 16657710Sbostic } 16757710Sbostic break; 16857710Sbostic default: 16957710Sbostic if (name_set) 17057710Sbostic ed_exit(3); 17157710Sbostic strcpy(l_fnametmp, argv[l_num]); 17257710Sbostic filename_current = l_fnametmp; 17357710Sbostic name_set = 1; 17457710Sbostic if (prompt_str_flg) 17557710Sbostic break; 17657710Sbostic /* default ed prompt */ 17757710Sbostic prompt_string = (char *) calloc(3, sizeof(char)); 17857710Sbostic strcpy(prompt_string, "*"); 17957710Sbostic break; 18057710Sbostic } 18157710Sbostic l_num++; 18257710Sbostic } 18357710Sbostic 18457710Sbostic start_up_flag = 1; 18557710Sbostic cmd_loop(stdin, &errnum); 18657710Sbostic /* NOTREACHED */ 18757710Sbostic } 18857710Sbostic 18957694Sbostic /* 19057710Sbostic * The command loop. What the command is that the user has specified 19157694Sbostic * is determined here. This is not just for commands coming from 19257694Sbostic * the terminal but any standard i/o stream; see the global commands. 19357694Sbostic * Some of the commands are handled within here (i.e. 'H') while most 19457694Sbostic * are handled in their own functions (as called). 19557694Sbostic */ 19657694Sbostic void 19757694Sbostic cmd_loop(inputt, errnum) 19857710Sbostic FILE *inputt; 19957710Sbostic int *errnum; 20057694Sbostic { 20157710Sbostic LINE *l_tempp; 20257710Sbostic int l_last, l_jmp_flag; 20357694Sbostic 20458315Sbostic l_last = 0; /* value in l_last may be clobbered (reset to = 0) by longjump, but that's okay */ 20557694Sbostic 20657710Sbostic if (g_flag == 0) { /* big, BIG trouble if we don't check! think. */ 20757710Sbostic /* set the jump point for the signals */ 20857710Sbostic l_jmp_flag = setjmp(ctrl_position); 20957710Sbostic signal(SIGINT, sigint_handler); 21057710Sbostic signal(SIGHUP, sighup_handler); 21157710Sbostic switch (l_jmp_flag) { 21257710Sbostic case JMP_SET: 21357710Sbostic break; 21457710Sbostic /* Some general cleanup not specific to the jmp pt. */ 21557710Sbostic case INTERUPT: 21657710Sbostic sigint_flag = 0; 21757710Sbostic GV_flag = 0; /* safest place to do these flags */ 21857710Sbostic g_flag = 0; 21959558Sbostic (void)printf("\n?\n"); 22057710Sbostic break; 22157710Sbostic case HANGUP: /* shouldn't get here. */ 22257710Sbostic break; 22357710Sbostic default: 22457710Sbostic (void)fprintf(stderr, "Signal jump problem\n"); 22557710Sbostic } 22657710Sbostic /* Only do this once! */ 22757710Sbostic if (start_up_flag) { 22857710Sbostic start_up_flag = 0; 22957710Sbostic /* simulate the 'e' at startup */ 23057710Sbostic e2(inputt, errnum); 231*59915Sbostic if (*errnum == 0) 232*59915Sbostic goto errmsg2; 23357710Sbostic } 23457710Sbostic } 23557710Sbostic for (;;) { 23657710Sbostic if (prompt_str_flg == 1) 23757710Sbostic (void)printf("%s", prompt_string); 23857710Sbostic ss = getc(inputt); 23957710Sbostic *errnum = 0; 24058564Sralph l_tempp = Start = End = NULL; 24158564Sralph Start_default = End_default = 1; 24257694Sbostic 24357710Sbostic /* 24457710Sbostic * This isn't nice and alphabetical mainly because of 24557710Sbostic * restrictions with 'G' and 'V' (see ed(1)). 24657710Sbostic */ 24757710Sbostic for (;;) { 24857710Sbostic switch (ss) { 24957710Sbostic case 'd': 25057710Sbostic d(inputt, errnum); 25157710Sbostic break; 25257710Sbostic case 'e': 25357710Sbostic case 'E': 25457710Sbostic e(inputt, errnum); 255*59915Sbostic if (*errnum == 0) 256*59915Sbostic goto errmsg2; 25757710Sbostic break; 25857710Sbostic case 'f': 25957710Sbostic f(inputt, errnum); 26057710Sbostic break; 26157710Sbostic case 'a': 26257710Sbostic case 'c': 26357710Sbostic case 'i': 26457710Sbostic case 'g': 26557710Sbostic case 'G': 26657710Sbostic case 'v': 26757710Sbostic case 'V': 26857710Sbostic if (GV_flag == 1) { 26957710Sbostic (void)sprintf(help_msg, 27057710Sbostic "command `%c' illegal in G/V", ss); 27157710Sbostic *errnum = -1; 27257710Sbostic break; 27357710Sbostic } 27457710Sbostic switch (ss) { 27557710Sbostic case 'a': 27657710Sbostic a(inputt, errnum); 27757710Sbostic break; 27857710Sbostic case 'c': 27957710Sbostic c(inputt, errnum); 28057710Sbostic break; 28157710Sbostic case 'i': 28257710Sbostic i(inputt, errnum); 28357710Sbostic break; 28457710Sbostic default: 28557710Sbostic g(inputt, errnum); 28657710Sbostic } 28757710Sbostic break; 28857710Sbostic case 'h': 28957710Sbostic if (rol(inputt, errnum)) 29057710Sbostic break; 29159558Sbostic if (help_msg[0]) 29259558Sbostic (void)printf("%s\n", help_msg); 29357710Sbostic *errnum = 1; 29457710Sbostic break; 29557710Sbostic case 'H': 29657710Sbostic if (rol(inputt, errnum)) 29757710Sbostic break; 29857710Sbostic if (help_flag == 0) { 29957710Sbostic help_flag = 1; 30059558Sbostic if (help_msg[0]) 30159558Sbostic (void)printf("%s\n", 30259558Sbostic help_msg); 30357710Sbostic } else 30457710Sbostic help_flag = 0; 30557710Sbostic *errnum = 1; 30657710Sbostic break; 30757710Sbostic case 'j': 30857710Sbostic j(inputt, errnum); 30957710Sbostic break; 31057710Sbostic case 'k': 31157710Sbostic set_mark(inputt, errnum); 31257710Sbostic break; 31357710Sbostic case 'l': 31457710Sbostic l(inputt, errnum); 31557710Sbostic break; 31657710Sbostic case 'm': 31757710Sbostic m(inputt, errnum); 31857710Sbostic break; 31957694Sbostic #ifdef POSIX 32057710Sbostic /* In POSIX-land 'P' toggles the prompt. */ 32157710Sbostic case 'P': 32257710Sbostic if (rol(inputt, errnum)) 32357710Sbostic break; 32457710Sbostic prompt_str_flg = prompt_str_flg ? 0 : 1; 32557710Sbostic *errnum = 1; 32657710Sbostic break; 32757694Sbostic #endif 32857710Sbostic case '\n': 32957710Sbostic if (GV_flag == 1) 33057710Sbostic return; 33157710Sbostic /* For 'p' to consume. */ 33257710Sbostic ungetc(ss, inputt); 33357710Sbostic if ((current == bottom) && (End == NULL)) { 33457710Sbostic strcpy(help_msg, "at end of buffer"); 33557710Sbostic *errnum = -1; 33657710Sbostic break; 33757710Sbostic } 33857710Sbostic current = current->below; 33957694Sbostic #ifdef BSD 34057710Sbostic /* In BSD 'P'=='p'. */ 34157710Sbostic case 'P': 34257694Sbostic #endif 34357710Sbostic case 'p': 34457710Sbostic p(inputt, errnum, 0); 34557710Sbostic break; 34657710Sbostic case 'n': 34757710Sbostic p(inputt, errnum, 1); 34857710Sbostic break; 34957710Sbostic /* 35057710Sbostic * An EOF means 'q' unless we're still in the middle 35157710Sbostic * of a global command, in which case it was just the 35257710Sbostic * end of the command list found. 35357710Sbostic */ 35457710Sbostic case EOF: 35557710Sbostic clearerr(inputt); 35657710Sbostic if (g_flag > 0) 35757710Sbostic return; 35858710Sbostic /*ss = 'q';*/ 35957710Sbostic case 'q': 36057710Sbostic case 'Q': 361*59915Sbostic if ((!isatty(STDIN_FILENO)) && (ss == 'q')) 362*59915Sbostic ss = 'Q'; 36357710Sbostic q(inputt, errnum); 36457710Sbostic break; 36557710Sbostic case 'r': 36657710Sbostic r(inputt, errnum); 367*59915Sbostic if (*errnum == 0) 368*59915Sbostic goto errmsg2; 36957710Sbostic break; 37057710Sbostic case 's': 37157710Sbostic s(inputt, errnum); 37257710Sbostic break; 37357710Sbostic case 't': 37457710Sbostic t(inputt, errnum); 37557710Sbostic break; 37657710Sbostic case 'u': 37757710Sbostic u(inputt, errnum); 37857710Sbostic break; 37957710Sbostic case 'w': 38057710Sbostic case 'W': 38157710Sbostic w(inputt, errnum); 38257710Sbostic break; 38357710Sbostic case 'z': 38457710Sbostic z(inputt, errnum); 38557710Sbostic break; 38657710Sbostic case '!': 38757710Sbostic bang(inputt, errnum); 38857710Sbostic break; 38957710Sbostic case '=': 39057710Sbostic equal(inputt, errnum); 39157710Sbostic break; 39257710Sbostic /* 39357710Sbostic * Control of address forms from here down. 39457710Sbostic * 39557710Sbostic * It's a head-game to understand why ";" and "," look 39657710Sbostic * as they do below, but a lot of it has to do with ";" 39757710Sbostic * and "," being special address pair forms themselves 39857710Sbostic * and the compatibility for address "chains". 39957710Sbostic */ 40057710Sbostic case ';': 40158564Sralph if (End_default == 1 && Start_default == 1) { 40258564Sralph Start = current; 40357710Sbostic End = bottom; 40458564Sralph Start_default = End_default = 0; 40557710Sbostic } else { 40658564Sralph Start = current = End; 40758564Sralph Start_default = 0; 40857710Sbostic End_default = 1; 40957710Sbostic } 41057710Sbostic l_tempp = NULL; 41157710Sbostic break; 41257710Sbostic /* 41357710Sbostic * Note address ".,x" where x is a cmd is legal; not a 41457710Sbostic * bug - for backward compatability. 41557710Sbostic */ 41657710Sbostic case ',': 41758564Sralph if (End_default == 1 && Start_default == 1) { 41858564Sralph Start = top; 41957710Sbostic End = bottom; 42058564Sralph Start_default = End_default = 0; 42157710Sbostic } else { 42258564Sralph Start = End; 42358564Sralph Start_default = 0; 42457710Sbostic End_default = 1; 42557710Sbostic } 42657710Sbostic l_tempp = NULL; 42757710Sbostic break; 42857710Sbostic case '%': 42957710Sbostic if (End_default == 0) { 43057710Sbostic strcpy(help_msg, 43157710Sbostic "'%' is an address pair"); 43257710Sbostic *errnum = -1; 43357710Sbostic break; 43457710Sbostic } 43558564Sralph Start = top; 43657710Sbostic End = bottom; 43758564Sralph Start_default = End_default = 0; 43857710Sbostic l_tempp = NULL; 43957710Sbostic break; 44057710Sbostic /* 44157710Sbostic * Within address_conv => l_last = '+', foobar, but 44257710Sbostic * historical and now POSIX... 44357710Sbostic */ 44457710Sbostic case ' ': 44557710Sbostic break; 44657710Sbostic case '0': 44757710Sbostic case '1': 44857710Sbostic case '2': 44957710Sbostic case '3': 45057710Sbostic case '4': 45157710Sbostic case '5': 45257710Sbostic case '6': 45357710Sbostic case '7': 45457710Sbostic case '8': 45557710Sbostic case '9': 45657710Sbostic case '-': 45757710Sbostic case '^': 45857710Sbostic case '+': 45957710Sbostic case '\'': 46057710Sbostic case '$': 46157710Sbostic case '?': 46257710Sbostic case '/': 46357710Sbostic case '.': 46457710Sbostic ungetc(ss, inputt); 46558564Sralph if (Start_default == 0 && End_default == 0) { 46657710Sbostic strcpy(help_msg, 46757710Sbostic "badly formed address"); 46857710Sbostic *errnum = -1; 46957710Sbostic break; 47057710Sbostic } 47157710Sbostic ss = l_last; 47257710Sbostic l_tempp = address_conv(l_tempp, inputt, errnum); 47357710Sbostic if (*errnum < 0) 47457710Sbostic break; 47557710Sbostic End = l_tempp; 47657710Sbostic End_default = 0; 47758564Sralph if (Start_default == 0) 47858564Sralph *errnum = address_check(Start, End); 47957710Sbostic break; 48057710Sbostic default: 48157710Sbostic *errnum = -1; 48257710Sbostic strcpy(help_msg, "unknown command"); 48357710Sbostic break; 48457710Sbostic } /* end-switch(ss) */ 48557694Sbostic 48657710Sbostic /* Things came out okay with the last command. */ 48757710Sbostic if (*errnum > 0) { 48857710Sbostic if (GV_flag == 1) 48957710Sbostic return; 49057710Sbostic /* Do the suffixes if there were any. */ 49157710Sbostic if (printsfx > 0) { 49258564Sralph Start = End = current; 49357710Sbostic ungetc(ss, inputt); 49457710Sbostic if (printsfx == 1) 49557710Sbostic p(inputt, errnum, 0); 49657710Sbostic else 49757710Sbostic if (printsfx == 2) 49857710Sbostic p(inputt, errnum, 1); 49957710Sbostic else if (printsfx == 4) 50057710Sbostic l(inputt, errnum); 50157710Sbostic /* Unlikely it's needed, but... */ 50257710Sbostic if (*errnum < 0) 50357710Sbostic goto errmsg; 50457710Sbostic } 50557710Sbostic break; 50657710Sbostic } 50757710Sbostic /* There was a problem with the last command. */ 50857710Sbostic else if (*errnum < 0) { 50957710Sbostic errmsg: while (((ss = getc(inputt)) != '\n') && 51057710Sbostic (ss != EOF)); 511*59915Sbostic (void)printf("?\n"); 512*59915Sbostic errmsg2: if (help_flag) 513*59915Sbostic (void)printf("%s\n", help_msg); 51459475Sbostic exit_code = 4; 51559475Sbostic /* for people wanting scripts to carry on after a cmd error, then 51659475Sbostic * define NOENDONSCRIPT on the compile line. 51759475Sbostic */ 51859475Sbostic #ifndef NOENDONSCRIPT 51959475Sbostic if (!isatty(STDIN_FILENO)) { 52059475Sbostic ss = 'Q'; 52159475Sbostic ungetc('\n', inputt); 52259475Sbostic q(inputt, errnum); 52359475Sbostic } 52459475Sbostic #endif 52558315Sbostic break; 52657710Sbostic } 52757710Sbostic l_last = ss; 52857710Sbostic ss = getc(inputt); 52957710Sbostic } 53057710Sbostic } 53157710Sbostic } 53257694Sbostic 53357710Sbostic /* 53457710Sbostic * Exits ed and prints an appropriate message about the command line 53557694Sbostic * being malformed (see below). 53657694Sbostic */ 53757694Sbostic void 53857694Sbostic ed_exit(err) 53957710Sbostic int err; 54057694Sbostic { 54157710Sbostic switch (err) { 54257710Sbostic case 1: 54357710Sbostic (void)fprintf(stderr, "ed: illegal option\n"); 54457710Sbostic break; 54557710Sbostic case 2: 54657710Sbostic (void)fprintf(stderr, "ed: missing promptstring\n"); 54757710Sbostic break; 54857710Sbostic case 3: 54957710Sbostic (void)fprintf(stderr, "ed: too many filenames\n"); 55057710Sbostic break; 55157710Sbostic case 4: 55257710Sbostic (void)fprintf(stderr, "ed: out of memory error\n"); 55357710Sbostic break; 55458315Sbostic case 5: 55558315Sbostic (void)fprintf(stderr, "ed: unable to create buffer\n"); 55658315Sbostic break; 55757710Sbostic default: 55857710Sbostic (void)fprintf(stderr, "ed: command line error\n"); 55957710Sbostic break; 56057710Sbostic } 56157710Sbostic (void)fprintf(stderr, 56257710Sbostic "ed: ed [ -s ] [ -p promptstring ] [ filename ]\n"); 56357710Sbostic exit(1); 56457710Sbostic } 56557694Sbostic 56657694Sbostic /* 56757710Sbostic * SIGINT is never turned off. We flag it happened and then pay attention 56857710Sbostic * to it at certain logical locations in the code we don't do more here 56957710Sbostic * cause some of our buffer pointer's may be in an inbetween state at the 57057710Sbostic * time of the SIGINT. So we flag it happened, let the local fn handle it 57157710Sbostic * and do a jump back to the cmd_loop 57257694Sbostic */ 57357710Sbostic static void 57457710Sbostic sigint_handler(signo) 57557710Sbostic int signo; 57657710Sbostic { 57757710Sbostic sigint_flag = 1; 57858352Sbostic if (sigspecial3) { 57958352Sbostic sigspecial3 = 0; 58058352Sbostic SIGINT_ILACTION; 58158352Sbostic } 58258315Sbostic else 58358315Sbostic if (sigspecial); 58458315Sbostic else 58558315Sbostic SIGINT_ACTION; 58657710Sbostic } 58757694Sbostic 58857710Sbostic static void 58957710Sbostic sighup_handler(signo) 59057710Sbostic int signo; 59157694Sbostic { 59257710Sbostic sighup_flag = 1; 59357710Sbostic undo(); 59457710Sbostic do_hup(); 59557710Sbostic /* NOTREACHED */ 59657694Sbostic 59757710Sbostic SIGHUP_ACTION; 59857710Sbostic } 599