xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/bltins/trap.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman *                                                                      *
3*b30d1939SAndy Fiddaman *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2012 AT&T Intellectual Property          *
5*b30d1939SAndy Fiddaman *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
7*b30d1939SAndy Fiddaman *                    by AT&T Intellectual Property                     *
8*b30d1939SAndy Fiddaman *                                                                      *
9*b30d1939SAndy Fiddaman *                A copy of the License is available at                 *
10*b30d1939SAndy Fiddaman *          http://www.eclipse.org/org/documents/epl-v10.html           *
11*b30d1939SAndy Fiddaman *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12*b30d1939SAndy Fiddaman *                                                                      *
13*b30d1939SAndy Fiddaman *              Information and Software Systems Research               *
14*b30d1939SAndy Fiddaman *                            AT&T Research                             *
15*b30d1939SAndy Fiddaman *                           Florham Park NJ                            *
16*b30d1939SAndy Fiddaman *                                                                      *
17*b30d1939SAndy Fiddaman *                  David Korn <dgk@research.att.com>                   *
18*b30d1939SAndy Fiddaman *                                                                      *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman  * trap  [-p]  action sig...
23*b30d1939SAndy Fiddaman  * kill  [-l] [sig...]
24*b30d1939SAndy Fiddaman  * kill  [-s sig] pid...
25*b30d1939SAndy Fiddaman  *
26*b30d1939SAndy Fiddaman  *   David Korn
27*b30d1939SAndy Fiddaman  *   AT&T Labs
28*b30d1939SAndy Fiddaman  *   research!dgk
29*b30d1939SAndy Fiddaman  *
30*b30d1939SAndy Fiddaman  */
31*b30d1939SAndy Fiddaman 
32*b30d1939SAndy Fiddaman #include	"defs.h"
33*b30d1939SAndy Fiddaman #include	"jobs.h"
34*b30d1939SAndy Fiddaman #include	"builtins.h"
35*b30d1939SAndy Fiddaman 
36*b30d1939SAndy Fiddaman #define L_FLAG	1
37*b30d1939SAndy Fiddaman #define S_FLAG	2
38*b30d1939SAndy Fiddaman 
39*b30d1939SAndy Fiddaman static const char trapfmt[] = "trap -- %s %s\n";
40*b30d1939SAndy Fiddaman 
41*b30d1939SAndy Fiddaman static int	sig_number(Shell_t*,const char*);
42*b30d1939SAndy Fiddaman static void	sig_list(Shell_t*,int);
43*b30d1939SAndy Fiddaman 
b_trap(int argc,char * argv[],Shbltin_t * context)44*b30d1939SAndy Fiddaman int	b_trap(int argc,char *argv[],Shbltin_t *context)
45*b30d1939SAndy Fiddaman {
46*b30d1939SAndy Fiddaman 	register char *arg = argv[1];
47*b30d1939SAndy Fiddaman 	register int sig, clear = 0, dflag = 0, pflag = 0;
48*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
49*b30d1939SAndy Fiddaman 	NOT_USED(argc);
50*b30d1939SAndy Fiddaman 	while (sig = optget(argv, sh_opttrap)) switch (sig)
51*b30d1939SAndy Fiddaman 	{
52*b30d1939SAndy Fiddaman 	    case 'p':
53*b30d1939SAndy Fiddaman 		pflag=1;
54*b30d1939SAndy Fiddaman 		break;
55*b30d1939SAndy Fiddaman 	    case ':':
56*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,2, "%s", opt_info.arg);
57*b30d1939SAndy Fiddaman 		break;
58*b30d1939SAndy Fiddaman 	    case '?':
59*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
60*b30d1939SAndy Fiddaman 		return(2);
61*b30d1939SAndy Fiddaman 		break;
62*b30d1939SAndy Fiddaman 	}
63*b30d1939SAndy Fiddaman 	argv += opt_info.index;
64*b30d1939SAndy Fiddaman 	if(error_info.errors)
65*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
66*b30d1939SAndy Fiddaman 	if(arg = *argv)
67*b30d1939SAndy Fiddaman 	{
68*b30d1939SAndy Fiddaman 		char *action = arg;
69*b30d1939SAndy Fiddaman 		if(!dflag && !pflag)
70*b30d1939SAndy Fiddaman 		{
71*b30d1939SAndy Fiddaman 			/* first argument all digits or - means clear */
72*b30d1939SAndy Fiddaman 			while(isdigit(*arg))
73*b30d1939SAndy Fiddaman 				arg++;
74*b30d1939SAndy Fiddaman 			clear = (arg!=action && *arg==0);
75*b30d1939SAndy Fiddaman 			if(!clear)
76*b30d1939SAndy Fiddaman 			{
77*b30d1939SAndy Fiddaman 				++argv;
78*b30d1939SAndy Fiddaman 				if(*action=='-' && action[1]==0)
79*b30d1939SAndy Fiddaman 					clear++;
80*b30d1939SAndy Fiddaman 				/*
81*b30d1939SAndy Fiddaman 				 * NOTE: 2007-11-26: workaround for tests/signal.sh
82*b30d1939SAndy Fiddaman 				 * if function semantics can be worked out then it
83*b30d1939SAndy Fiddaman 				 * may merit a -d,--default option
84*b30d1939SAndy Fiddaman 				 */
85*b30d1939SAndy Fiddaman 				else if(*action=='+' && action[1]==0 && shp->st.self == &shp->global)
86*b30d1939SAndy Fiddaman 				{
87*b30d1939SAndy Fiddaman 					clear++;
88*b30d1939SAndy Fiddaman 					dflag++;
89*b30d1939SAndy Fiddaman 				}
90*b30d1939SAndy Fiddaman 			}
91*b30d1939SAndy Fiddaman 			if(!argv[0])
92*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,ERROR_exit(1),e_condition);
93*b30d1939SAndy Fiddaman 		}
94*b30d1939SAndy Fiddaman 		while(arg = *argv++)
95*b30d1939SAndy Fiddaman 		{
96*b30d1939SAndy Fiddaman 			sig = sig_number(shp,arg);
97*b30d1939SAndy Fiddaman 			if(sig<0)
98*b30d1939SAndy Fiddaman 			{
99*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,2,e_trap,arg);
100*b30d1939SAndy Fiddaman 				return(1);
101*b30d1939SAndy Fiddaman 			}
102*b30d1939SAndy Fiddaman 			/* internal traps */
103*b30d1939SAndy Fiddaman 			if(sig&SH_TRAP)
104*b30d1939SAndy Fiddaman 			{
105*b30d1939SAndy Fiddaman 				char **trap = (shp->st.otrap?shp->st.otrap:shp->st.trap);
106*b30d1939SAndy Fiddaman 				sig &= ~SH_TRAP;
107*b30d1939SAndy Fiddaman 				if(sig>SH_DEBUGTRAP)
108*b30d1939SAndy Fiddaman 				{
109*b30d1939SAndy Fiddaman 					errormsg(SH_DICT,2,e_trap,arg);
110*b30d1939SAndy Fiddaman 					return(1);
111*b30d1939SAndy Fiddaman 				}
112*b30d1939SAndy Fiddaman 				if(pflag)
113*b30d1939SAndy Fiddaman 				{
114*b30d1939SAndy Fiddaman 					if(arg=trap[sig])
115*b30d1939SAndy Fiddaman 						sfputr(sfstdout,sh_fmtq(arg),'\n');
116*b30d1939SAndy Fiddaman 					continue;
117*b30d1939SAndy Fiddaman 				}
118*b30d1939SAndy Fiddaman 				shp->st.otrap = 0;
119*b30d1939SAndy Fiddaman 				if(shp->st.trap[sig])
120*b30d1939SAndy Fiddaman 					free(shp->st.trap[sig]);
121*b30d1939SAndy Fiddaman 				shp->st.trap[sig] = 0;
122*b30d1939SAndy Fiddaman 				if(!clear && *action)
123*b30d1939SAndy Fiddaman 					shp->st.trap[sig] = strdup(action);
124*b30d1939SAndy Fiddaman 				if(sig == SH_DEBUGTRAP)
125*b30d1939SAndy Fiddaman 				{
126*b30d1939SAndy Fiddaman 					if(shp->st.trap[sig])
127*b30d1939SAndy Fiddaman 						shp->trapnote |= SH_SIGTRAP;
128*b30d1939SAndy Fiddaman 					else
129*b30d1939SAndy Fiddaman 						shp->trapnote = 0;
130*b30d1939SAndy Fiddaman 
131*b30d1939SAndy Fiddaman 				}
132*b30d1939SAndy Fiddaman 				if(sig == SH_ERRTRAP)
133*b30d1939SAndy Fiddaman 				{
134*b30d1939SAndy Fiddaman 					if(clear)
135*b30d1939SAndy Fiddaman 						shp->errtrap = 0;
136*b30d1939SAndy Fiddaman 					else
137*b30d1939SAndy Fiddaman 					{
138*b30d1939SAndy Fiddaman 						if(!shp->fn_depth || shp->end_fn)
139*b30d1939SAndy Fiddaman 							shp->errtrap = 1;
140*b30d1939SAndy Fiddaman 					}
141*b30d1939SAndy Fiddaman 				}
142*b30d1939SAndy Fiddaman 				continue;
143*b30d1939SAndy Fiddaman 			}
144*b30d1939SAndy Fiddaman 			if(sig>shp->gd->sigmax)
145*b30d1939SAndy Fiddaman 			{
146*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,2,e_trap,arg);
147*b30d1939SAndy Fiddaman 				return(1);
148*b30d1939SAndy Fiddaman 			}
149*b30d1939SAndy Fiddaman 			else if(pflag)
150*b30d1939SAndy Fiddaman 			{
151*b30d1939SAndy Fiddaman 				char **trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom);
152*b30d1939SAndy Fiddaman 				if(arg=trapcom[sig])
153*b30d1939SAndy Fiddaman 					sfputr(sfstdout,arg,'\n');
154*b30d1939SAndy Fiddaman 			}
155*b30d1939SAndy Fiddaman 			else if(clear)
156*b30d1939SAndy Fiddaman 			{
157*b30d1939SAndy Fiddaman 				sh_sigclear(sig);
158*b30d1939SAndy Fiddaman 				if(sig == 0)
159*b30d1939SAndy Fiddaman 					shp->exittrap = 0;
160*b30d1939SAndy Fiddaman 				if(dflag)
161*b30d1939SAndy Fiddaman 					signal(sig,SIG_DFL);
162*b30d1939SAndy Fiddaman 			}
163*b30d1939SAndy Fiddaman 			else
164*b30d1939SAndy Fiddaman 			{
165*b30d1939SAndy Fiddaman 				if(sig >= shp->st.trapmax)
166*b30d1939SAndy Fiddaman 					shp->st.trapmax = sig+1;
167*b30d1939SAndy Fiddaman 				arg = shp->st.trapcom[sig];
168*b30d1939SAndy Fiddaman 				sh_sigtrap(sig);
169*b30d1939SAndy Fiddaman 				shp->st.trapcom[sig] = (shp->sigflag[sig]&SH_SIGOFF) ? Empty : strdup(action);
170*b30d1939SAndy Fiddaman 				if(arg && arg != Empty)
171*b30d1939SAndy Fiddaman 					free(arg);
172*b30d1939SAndy Fiddaman 				if(sig == 0)
173*b30d1939SAndy Fiddaman 				{
174*b30d1939SAndy Fiddaman 					if(!shp->fn_depth || shp->end_fn)
175*b30d1939SAndy Fiddaman 						shp->exittrap = 1;
176*b30d1939SAndy Fiddaman 				}
177*b30d1939SAndy Fiddaman 			}
178*b30d1939SAndy Fiddaman 		}
179*b30d1939SAndy Fiddaman 	}
180*b30d1939SAndy Fiddaman 	else /* print out current traps */
181*b30d1939SAndy Fiddaman 		sig_list(shp,-2);
182*b30d1939SAndy Fiddaman 	return(0);
183*b30d1939SAndy Fiddaman }
184*b30d1939SAndy Fiddaman 
b_kill(int argc,char * argv[],Shbltin_t * context)185*b30d1939SAndy Fiddaman int	b_kill(int argc,char *argv[],Shbltin_t *context)
186*b30d1939SAndy Fiddaman {
187*b30d1939SAndy Fiddaman 	register char *signame;
188*b30d1939SAndy Fiddaman 	register int sig=SIGTERM, flag=0, n;
189*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
190*b30d1939SAndy Fiddaman 	int usemenu = 0;
191*b30d1939SAndy Fiddaman 	NOT_USED(argc);
192*b30d1939SAndy Fiddaman 	while((n = optget(argv,sh_optkill))) switch(n)
193*b30d1939SAndy Fiddaman 	{
194*b30d1939SAndy Fiddaman 		case ':':
195*b30d1939SAndy Fiddaman 			if((signame=argv[opt_info.index++]) && (sig=sig_number(shp,signame+1))>=0)
196*b30d1939SAndy Fiddaman 				goto endopts;
197*b30d1939SAndy Fiddaman 			opt_info.index--;
198*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,2, "%s", opt_info.arg);
199*b30d1939SAndy Fiddaman 			break;
200*b30d1939SAndy Fiddaman 		case 'n':
201*b30d1939SAndy Fiddaman 			sig = (int)opt_info.num;
202*b30d1939SAndy Fiddaman 			goto endopts;
203*b30d1939SAndy Fiddaman 		case 's':
204*b30d1939SAndy Fiddaman 			flag |= S_FLAG;
205*b30d1939SAndy Fiddaman 			signame = opt_info.arg;
206*b30d1939SAndy Fiddaman 			goto endopts;
207*b30d1939SAndy Fiddaman 		case 'L':
208*b30d1939SAndy Fiddaman 			usemenu = -1;
209*b30d1939SAndy Fiddaman 			/* FALLTHROUGH */
210*b30d1939SAndy Fiddaman 		case 'l':
211*b30d1939SAndy Fiddaman 			flag |= L_FLAG;
212*b30d1939SAndy Fiddaman 			break;
213*b30d1939SAndy Fiddaman 		case '?':
214*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
215*b30d1939SAndy Fiddaman 			break;
216*b30d1939SAndy Fiddaman 	}
217*b30d1939SAndy Fiddaman endopts:
218*b30d1939SAndy Fiddaman 	argv += opt_info.index;
219*b30d1939SAndy Fiddaman 	if(*argv && strcmp(*argv,"--")==0 && strcmp(*(argv-1),"--")!=0)
220*b30d1939SAndy Fiddaman 		argv++;
221*b30d1939SAndy Fiddaman 	if(error_info.errors || flag==(L_FLAG|S_FLAG) || (!(*argv) && !(flag&L_FLAG)))
222*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
223*b30d1939SAndy Fiddaman 	/* just in case we send a kill -9 $$ */
224*b30d1939SAndy Fiddaman 	sfsync(sfstderr);
225*b30d1939SAndy Fiddaman 	if(flag&L_FLAG)
226*b30d1939SAndy Fiddaman 	{
227*b30d1939SAndy Fiddaman 		if(!(*argv))
228*b30d1939SAndy Fiddaman 			sig_list(shp,usemenu);
229*b30d1939SAndy Fiddaman 		else while(signame = *argv++)
230*b30d1939SAndy Fiddaman 		{
231*b30d1939SAndy Fiddaman 			if(isdigit(*signame))
232*b30d1939SAndy Fiddaman 				sig_list(shp,((int)strtol(signame, (char**)0, 10)&0177)+1);
233*b30d1939SAndy Fiddaman 			else
234*b30d1939SAndy Fiddaman 			{
235*b30d1939SAndy Fiddaman 				if((sig=sig_number(shp,signame))<0)
236*b30d1939SAndy Fiddaman 				{
237*b30d1939SAndy Fiddaman 					shp->exitval = 2;
238*b30d1939SAndy Fiddaman 					errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
239*b30d1939SAndy Fiddaman 				}
240*b30d1939SAndy Fiddaman 				sfprintf(sfstdout,"%d\n",sig);
241*b30d1939SAndy Fiddaman 			}
242*b30d1939SAndy Fiddaman 		}
243*b30d1939SAndy Fiddaman 		return(shp->exitval);
244*b30d1939SAndy Fiddaman 	}
245*b30d1939SAndy Fiddaman 	if(flag&S_FLAG)
246*b30d1939SAndy Fiddaman 	{
247*b30d1939SAndy Fiddaman 		if((sig=sig_number(shp,signame)) < 0 || sig > shp->gd->sigmax)
248*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
249*b30d1939SAndy Fiddaman 	}
250*b30d1939SAndy Fiddaman 	if(job_walk(sfstdout,job_kill,sig,argv))
251*b30d1939SAndy Fiddaman 		shp->exitval = 1;
252*b30d1939SAndy Fiddaman 	return(shp->exitval);
253*b30d1939SAndy Fiddaman }
254*b30d1939SAndy Fiddaman 
255*b30d1939SAndy Fiddaman /*
256*b30d1939SAndy Fiddaman  * Given the name or number of a signal return the signal number
257*b30d1939SAndy Fiddaman  */
258*b30d1939SAndy Fiddaman 
sig_number(Shell_t * shp,const char * string)259*b30d1939SAndy Fiddaman static int sig_number(Shell_t *shp,const char *string)
260*b30d1939SAndy Fiddaman {
261*b30d1939SAndy Fiddaman 	const Shtable_t	*tp;
262*b30d1939SAndy Fiddaman 	register int	n,o,sig=0;
263*b30d1939SAndy Fiddaman 	char		*last, *name;
264*b30d1939SAndy Fiddaman 	if(isdigit(*string))
265*b30d1939SAndy Fiddaman 	{
266*b30d1939SAndy Fiddaman 		n = strtol(string,&last,10);
267*b30d1939SAndy Fiddaman 		if(*last)
268*b30d1939SAndy Fiddaman 			n = -1;
269*b30d1939SAndy Fiddaman 	}
270*b30d1939SAndy Fiddaman 	else
271*b30d1939SAndy Fiddaman 	{
272*b30d1939SAndy Fiddaman 		register int c;
273*b30d1939SAndy Fiddaman 		o = staktell();
274*b30d1939SAndy Fiddaman 		do
275*b30d1939SAndy Fiddaman 		{
276*b30d1939SAndy Fiddaman 			c = *string++;
277*b30d1939SAndy Fiddaman 			if(islower(c))
278*b30d1939SAndy Fiddaman 				c = toupper(c);
279*b30d1939SAndy Fiddaman 			stakputc(c);
280*b30d1939SAndy Fiddaman 		}
281*b30d1939SAndy Fiddaman 		while(c);
282*b30d1939SAndy Fiddaman 		stakseek(o);
283*b30d1939SAndy Fiddaman 		if(memcmp(stakptr(o),"SIG",3)==0)
284*b30d1939SAndy Fiddaman 		{
285*b30d1939SAndy Fiddaman 			sig = 1;
286*b30d1939SAndy Fiddaman 			o += 3;
287*b30d1939SAndy Fiddaman 			if(isdigit(*stakptr(o)))
288*b30d1939SAndy Fiddaman 			{
289*b30d1939SAndy Fiddaman 				n = strtol(stakptr(o),&last,10);
290*b30d1939SAndy Fiddaman 				if(!*last)
291*b30d1939SAndy Fiddaman 					return(n);
292*b30d1939SAndy Fiddaman 			}
293*b30d1939SAndy Fiddaman 		}
294*b30d1939SAndy Fiddaman 		tp = sh_locate(stakptr(o),(const Shtable_t*)shtab_signals,sizeof(*shtab_signals));
295*b30d1939SAndy Fiddaman 		n = tp->sh_number;
296*b30d1939SAndy Fiddaman 		if(sig==1 && (n>=(SH_TRAP-1) && n < (1<<SH_SIGBITS)))
297*b30d1939SAndy Fiddaman 		{
298*b30d1939SAndy Fiddaman 			/* sig prefix cannot match internal traps */
299*b30d1939SAndy Fiddaman 			n = 0;
300*b30d1939SAndy Fiddaman 			tp = (Shtable_t*)((char*)tp + sizeof(*shtab_signals));
301*b30d1939SAndy Fiddaman 			if(strcmp(stakptr(o),tp->sh_name)==0)
302*b30d1939SAndy Fiddaman 				n = tp->sh_number;
303*b30d1939SAndy Fiddaman 		}
304*b30d1939SAndy Fiddaman 		if((n>>SH_SIGBITS)&SH_SIGRUNTIME)
305*b30d1939SAndy Fiddaman 			n = shp->gd->sigruntime[(n&((1<<SH_SIGBITS)-1))-1];
306*b30d1939SAndy Fiddaman 		else
307*b30d1939SAndy Fiddaman 		{
308*b30d1939SAndy Fiddaman 			n &= (1<<SH_SIGBITS)-1;
309*b30d1939SAndy Fiddaman 			if(n < SH_TRAP)
310*b30d1939SAndy Fiddaman 				n--;
311*b30d1939SAndy Fiddaman 		}
312*b30d1939SAndy Fiddaman 		if(n<0 && shp->gd->sigruntime[1] && (name=stakptr(o)) && *name++=='R' && *name++=='T')
313*b30d1939SAndy Fiddaman 		{
314*b30d1939SAndy Fiddaman 			if(name[0]=='M' && name[1]=='I' && name[2]=='N' && name[3]=='+')
315*b30d1939SAndy Fiddaman 			{
316*b30d1939SAndy Fiddaman 				if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
317*b30d1939SAndy Fiddaman 					n = shp->gd->sigruntime[SH_SIGRTMIN] + sig;
318*b30d1939SAndy Fiddaman 			}
319*b30d1939SAndy Fiddaman 			else if(name[0]=='M' && name[1]=='A' && name[2]=='X' && name[3]=='-')
320*b30d1939SAndy Fiddaman 			{
321*b30d1939SAndy Fiddaman 				if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
322*b30d1939SAndy Fiddaman 					n = shp->gd->sigruntime[SH_SIGRTMAX] - sig;
323*b30d1939SAndy Fiddaman 			}
324*b30d1939SAndy Fiddaman 			else if((sig=(int)strtol(name,&name,10)) > 0 && !*name)
325*b30d1939SAndy Fiddaman 				n = shp->gd->sigruntime[SH_SIGRTMIN] + sig - 1;
326*b30d1939SAndy Fiddaman 			if(n<shp->gd->sigruntime[SH_SIGRTMIN] || n>shp->gd->sigruntime[SH_SIGRTMAX])
327*b30d1939SAndy Fiddaman 				n = -1;
328*b30d1939SAndy Fiddaman 		}
329*b30d1939SAndy Fiddaman 	}
330*b30d1939SAndy Fiddaman 	return(n);
331*b30d1939SAndy Fiddaman }
332*b30d1939SAndy Fiddaman 
333*b30d1939SAndy Fiddaman /*
334*b30d1939SAndy Fiddaman  * synthesize signal name for sig in buf
335*b30d1939SAndy Fiddaman  * pfx!=0 prepends SIG to default signal number
336*b30d1939SAndy Fiddaman  */
sig_name(Shell_t * shp,int sig,char * buf,int pfx)337*b30d1939SAndy Fiddaman static char* sig_name(Shell_t *shp,int sig, char* buf, int pfx)
338*b30d1939SAndy Fiddaman {
339*b30d1939SAndy Fiddaman 	register int	i;
340*b30d1939SAndy Fiddaman 
341*b30d1939SAndy Fiddaman 	i = 0;
342*b30d1939SAndy Fiddaman 	if(sig>shp->gd->sigruntime[SH_SIGRTMIN] && sig<shp->gd->sigruntime[SH_SIGRTMAX])
343*b30d1939SAndy Fiddaman 	{
344*b30d1939SAndy Fiddaman 		buf[i++] = 'R';
345*b30d1939SAndy Fiddaman 		buf[i++] = 'T';
346*b30d1939SAndy Fiddaman 		buf[i++] = 'M';
347*b30d1939SAndy Fiddaman 		if(sig>shp->gd->sigruntime[SH_SIGRTMIN]+(shp->gd->sigruntime[SH_SIGRTMAX]-shp->gd->sigruntime[SH_SIGRTMIN])/2)
348*b30d1939SAndy Fiddaman 		{
349*b30d1939SAndy Fiddaman 			buf[i++] = 'A';
350*b30d1939SAndy Fiddaman 			buf[i++] = 'X';
351*b30d1939SAndy Fiddaman 			buf[i++] = '-';
352*b30d1939SAndy Fiddaman 			sig = shp->gd->sigruntime[SH_SIGRTMAX]-sig;
353*b30d1939SAndy Fiddaman 		}
354*b30d1939SAndy Fiddaman 		else
355*b30d1939SAndy Fiddaman 		{
356*b30d1939SAndy Fiddaman 			buf[i++] = 'I';
357*b30d1939SAndy Fiddaman 			buf[i++] = 'N';
358*b30d1939SAndy Fiddaman 			buf[i++] = '+';
359*b30d1939SAndy Fiddaman 			sig = sig-shp->gd->sigruntime[SH_SIGRTMIN];
360*b30d1939SAndy Fiddaman 		}
361*b30d1939SAndy Fiddaman 	}
362*b30d1939SAndy Fiddaman 	else if(pfx)
363*b30d1939SAndy Fiddaman 	{
364*b30d1939SAndy Fiddaman 		buf[i++] = 'S';
365*b30d1939SAndy Fiddaman 		buf[i++] = 'I';
366*b30d1939SAndy Fiddaman 		buf[i++] = 'G';
367*b30d1939SAndy Fiddaman 	}
368*b30d1939SAndy Fiddaman 	i += sfsprintf(buf+i, 8, "%d", sig);
369*b30d1939SAndy Fiddaman 	buf[i] = 0;
370*b30d1939SAndy Fiddaman 	return buf;
371*b30d1939SAndy Fiddaman }
372*b30d1939SAndy Fiddaman 
373*b30d1939SAndy Fiddaman /*
374*b30d1939SAndy Fiddaman  * if <flag> is positive, then print signal name corresponding to <flag>
375*b30d1939SAndy Fiddaman  * if <flag> is zero, then print all signal names
376*b30d1939SAndy Fiddaman  * if <flag> is -1, then print all signal names in menu format
377*b30d1939SAndy Fiddaman  * if <flag> is <-1, then print all traps
378*b30d1939SAndy Fiddaman  */
sig_list(register Shell_t * shp,register int flag)379*b30d1939SAndy Fiddaman static void sig_list(register Shell_t *shp,register int flag)
380*b30d1939SAndy Fiddaman {
381*b30d1939SAndy Fiddaman 	register const struct shtable2	*tp;
382*b30d1939SAndy Fiddaman 	register int sig;
383*b30d1939SAndy Fiddaman 	register char *sname;
384*b30d1939SAndy Fiddaman 	char name[10];
385*b30d1939SAndy Fiddaman 	const char *names[SH_TRAP];
386*b30d1939SAndy Fiddaman 	const char *traps[SH_DEBUGTRAP+1];
387*b30d1939SAndy Fiddaman 	tp=shtab_signals;
388*b30d1939SAndy Fiddaman 	if(flag<=0)
389*b30d1939SAndy Fiddaman 	{
390*b30d1939SAndy Fiddaman 		/* not all signals may be defined, so initialize */
391*b30d1939SAndy Fiddaman 		for(sig=shp->gd->sigmax; sig>=0; sig--)
392*b30d1939SAndy Fiddaman 			names[sig] = 0;
393*b30d1939SAndy Fiddaman 		for(sig=SH_DEBUGTRAP; sig>=0; sig--)
394*b30d1939SAndy Fiddaman 			traps[sig] = 0;
395*b30d1939SAndy Fiddaman 	}
396*b30d1939SAndy Fiddaman 	for(; *tp->sh_name; tp++)
397*b30d1939SAndy Fiddaman 	{
398*b30d1939SAndy Fiddaman 		sig = tp->sh_number&((1<<SH_SIGBITS)-1);
399*b30d1939SAndy Fiddaman 		if (((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME) && (sig = shp->gd->sigruntime[sig-1]+1) == 1)
400*b30d1939SAndy Fiddaman 			continue;
401*b30d1939SAndy Fiddaman 		if(sig==flag)
402*b30d1939SAndy Fiddaman 		{
403*b30d1939SAndy Fiddaman 			sfprintf(sfstdout,"%s\n",tp->sh_name);
404*b30d1939SAndy Fiddaman 			return;
405*b30d1939SAndy Fiddaman 		}
406*b30d1939SAndy Fiddaman 		else if(sig&SH_TRAP)
407*b30d1939SAndy Fiddaman 			traps[sig&~SH_TRAP] = (char*)tp->sh_name;
408*b30d1939SAndy Fiddaman 		else if(sig-- && sig < elementsof(names))
409*b30d1939SAndy Fiddaman 			names[sig] = (char*)tp->sh_name;
410*b30d1939SAndy Fiddaman 	}
411*b30d1939SAndy Fiddaman 	if(flag > 0)
412*b30d1939SAndy Fiddaman 		sfputr(sfstdout, sig_name(shp,flag-1,name,0), '\n');
413*b30d1939SAndy Fiddaman 	else if(flag<-1)
414*b30d1939SAndy Fiddaman 	{
415*b30d1939SAndy Fiddaman 		/* print the traps */
416*b30d1939SAndy Fiddaman 		register char *trap,**trapcom;
417*b30d1939SAndy Fiddaman 		sig = shp->st.trapmax;
418*b30d1939SAndy Fiddaman 		/* use parent traps if otrapcom is set (for $(trap)  */
419*b30d1939SAndy Fiddaman 		trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom);
420*b30d1939SAndy Fiddaman 		while(--sig >= 0)
421*b30d1939SAndy Fiddaman 		{
422*b30d1939SAndy Fiddaman 			if(!(trap=trapcom[sig]))
423*b30d1939SAndy Fiddaman 				continue;
424*b30d1939SAndy Fiddaman 			if(sig > shp->gd->sigmax || !(sname=(char*)names[sig]))
425*b30d1939SAndy Fiddaman 				sname = sig_name(shp,sig,name,1);
426*b30d1939SAndy Fiddaman 			sfprintf(sfstdout,trapfmt,sh_fmtq(trap),sname);
427*b30d1939SAndy Fiddaman 		}
428*b30d1939SAndy Fiddaman 		for(sig=SH_DEBUGTRAP; sig>=0; sig--)
429*b30d1939SAndy Fiddaman 		{
430*b30d1939SAndy Fiddaman 			if(!(trap=shp->st.otrap?shp->st.otrap[sig]:shp->st.trap[sig]))
431*b30d1939SAndy Fiddaman 				continue;
432*b30d1939SAndy Fiddaman 			sfprintf(sfstdout,trapfmt,sh_fmtq(trap),traps[sig]);
433*b30d1939SAndy Fiddaman 		}
434*b30d1939SAndy Fiddaman 	}
435*b30d1939SAndy Fiddaman 	else
436*b30d1939SAndy Fiddaman 	{
437*b30d1939SAndy Fiddaman 		/* print all the signal names */
438*b30d1939SAndy Fiddaman 		for(sig=1; sig <= shp->gd->sigmax; sig++)
439*b30d1939SAndy Fiddaman 		{
440*b30d1939SAndy Fiddaman 			if(!(sname=(char*)names[sig]))
441*b30d1939SAndy Fiddaman 			{
442*b30d1939SAndy Fiddaman 				sname = sig_name(shp,sig,name,1);
443*b30d1939SAndy Fiddaman 				if(flag)
444*b30d1939SAndy Fiddaman 					sname = stakcopy(sname);
445*b30d1939SAndy Fiddaman 			}
446*b30d1939SAndy Fiddaman 			if(flag)
447*b30d1939SAndy Fiddaman 				names[sig] = sname;
448*b30d1939SAndy Fiddaman 			else
449*b30d1939SAndy Fiddaman 				sfputr(sfstdout,sname,'\n');
450*b30d1939SAndy Fiddaman 		}
451*b30d1939SAndy Fiddaman 		if(flag)
452*b30d1939SAndy Fiddaman 		{
453*b30d1939SAndy Fiddaman 			names[sig] = 0;
454*b30d1939SAndy Fiddaman 			sh_menu(sfstdout,shp->gd->sigmax,(char**)names+1);
455*b30d1939SAndy Fiddaman 		}
456*b30d1939SAndy Fiddaman 	}
457*b30d1939SAndy Fiddaman }
458