1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: signals.c 769 2007-10-24 00:15:40Z hubert@u.washington.edu $";
3 #endif
4 
5 /*
6  * ========================================================================
7  * Copyright 2006-2007 University of Washington
8  * Copyright 2013-2021 Eduardo Chappa
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  *     http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * ========================================================================
17  */
18 
19 #include <system.h>
20 #include <general.h>
21 
22 #include "../headers.h"
23 
24 #include "../../pith/charconv/filesys.h"
25 
26 #include "tty.h"
27 
28 #include "signals.h"
29 
30 
31 /* internal prototypes */
32 #ifndef _WINDOWS
33 RETSIGTYPE	do_hup_signal(int);
34 #endif
35 
36 
37 /*
38  * picosigs - Install any handlers for the signals we're interested
39  *	      in catching.
40  */
41 void
picosigs(void)42 picosigs(void)
43 {
44 #ifndef _WINDOWS
45     signal(SIGHUP,  do_hup_signal);	/* deal with SIGHUP */
46     signal(SIGTERM, do_hup_signal);	/* deal with SIGTERM */
47 #ifdef	SIGTSTP
48     signal(SIGTSTP, SIG_DFL);
49 #endif
50 #if	defined(SIGWINCH) && defined(TIOCGWINSZ)
51     signal(SIGWINCH, winch_handler); /* window size changes */
52 #endif
53 #endif /* !_WINDOWS */
54 }
55 
56 
57 
58 
59 #ifndef _WINDOWS
60 /*
61  * do_hup_signal - jump back in the stack to where we can handle this
62  */
63 RETSIGTYPE
do_hup_signal(int sig)64 do_hup_signal(int sig)
65 {
66     signal(SIGHUP,  SIG_IGN);			/* ignore further SIGHUP's */
67     signal(SIGTERM, SIG_IGN);			/* ignore further SIGTERM's */
68     if(Pmaster){
69 	extern jmp_buf finstate;
70 
71 	longjmp(finstate, COMP_GOTHUP);
72     }
73     else{
74 	/*
75 	 * if we've been interrupted and the buffer is changed,
76 	 * save it...
77 	 */
78 	if(anycb() == TRUE){			/* time to save */
79 	    if(curbp->b_fname[0] == '\0'){	/* name it */
80 		strncpy(curbp->b_fname, "pico.save", sizeof(curbp->b_fname));
81 		curbp->b_fname[sizeof(curbp->b_fname)-1] = '\0';
82 	    }
83 	    else{
84 		strncat(curbp->b_fname, ".save", sizeof(curbp->b_fname)-strlen(curbp->b_fname)-1);
85 		curbp->b_fname[sizeof(curbp->b_fname)-1] = '\0';
86 	    }
87 
88 	    our_unlink(curbp->b_fname);
89 	    writeout(curbp->b_fname, TRUE);
90 	}
91 
92 	vttidy();
93 	exit(1);
94     }
95 }
96 #endif /* !_WINDOWS */
97 
98 
99 #if	defined(SIGWINCH) && defined(TIOCGWINSZ)
100 /*
101  * winch_handler - handle window change signal
102  */
103 RETSIGTYPE
winch_handler(int sig)104 winch_handler(int sig)
105 {
106     int i = 0;
107     signal(SIGWINCH, winch_handler);
108     if(wheadp != NULL)
109       ttresize();
110     else if (Pmaster){
111       i = Pmaster->arm_winch_cleanup;
112       Pmaster->arm_winch_cleanup = 1;
113     }
114     if(Pmaster && Pmaster->winch_cleanup && Pmaster->arm_winch_cleanup)
115       (*Pmaster->winch_cleanup)();
116     if(wheadp == NULL && Pmaster != NULL)
117 	Pmaster->arm_winch_cleanup = i;
118 }
119 #endif	/* SIGWINCH and friends */
120 
121 
122 
123 #ifdef	POSIX_SIGNALS
124 /*----------------------------------------------------------------------
125    Reset signals after critical imap code
126  ----*/
127 void
posix_signal(int sig_num,RETSIGTYPE (* action)(int))128 (*posix_signal(int sig_num, RETSIGTYPE (*action)(int)))(int)
129 {
130     struct sigaction new_action, old_action;
131 
132     memset((void *)&new_action, 0, sizeof(struct sigaction));
133     sigemptyset (&new_action.sa_mask);
134     new_action.sa_handler = action;
135 #ifdef	SA_RESTART
136     new_action.sa_flags = SA_RESTART;
137 #else
138     new_action.sa_flags = 0;
139 #endif
140     sigaction(sig_num, &new_action, &old_action);
141     return(old_action.sa_handler);
142 }
143 
144 int
posix_sigunblock(int mask)145 posix_sigunblock(int mask)
146 {
147     sigset_t sig_mask;
148 
149     sigemptyset(&sig_mask);
150     sigaddset(&sig_mask, mask);
151 #if	HAVE_PTHREAD
152 # define sigprocmask	pthread_sigmask
153 #endif
154     return(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL));
155 }
156 #endif /* POSIX_SIGNALS */
157 
158 
159 #if	defined(sv3) || defined(ct)
160 /* Placed by rll to handle the rename function not found in AT&T */
161 int
rename(char * oldname,char * newname)162 rename(char *oldname, char *newname)
163 {
164     int rtn;
165     char b[NLINE];
166 
167     strncpy(b, fname_to_locale(oldname), sizeof(b));
168     b[sizeof(b)-1] = '\0';
169 
170     if ((rtn = link(b, fname_to_locale(newname))) != 0) {
171 	perror("Was not able to rename file.");
172 	return(rtn);
173     }
174 
175     if ((rtn = our_unlink(b)) != 0)
176       perror("Was not able to unlink file.");
177 
178     return(rtn);
179 }
180 #endif
181 
182