1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2012 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                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)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
18da2e3ebdSchin *                                                                      *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /*
22da2e3ebdSchin  * trap  [-p]  action sig...
23da2e3ebdSchin  * kill  [-l] [sig...]
24da2e3ebdSchin  * kill  [-s sig] pid...
25da2e3ebdSchin  *
26da2e3ebdSchin  *   David Korn
27da2e3ebdSchin  *   AT&T Labs
28da2e3ebdSchin  *   research!dgk
29da2e3ebdSchin  *
30da2e3ebdSchin  */
31da2e3ebdSchin 
32da2e3ebdSchin #include	"defs.h"
33da2e3ebdSchin #include	"jobs.h"
34da2e3ebdSchin #include	"builtins.h"
35da2e3ebdSchin 
36da2e3ebdSchin #define L_FLAG	1
37da2e3ebdSchin #define S_FLAG	2
38da2e3ebdSchin 
39da2e3ebdSchin static const char trapfmt[] = "trap -- %s %s\n";
40da2e3ebdSchin 
41*b30d1939SAndy Fiddaman static int	sig_number(Shell_t*,const char*);
42da2e3ebdSchin static void	sig_list(Shell_t*,int);
43da2e3ebdSchin 
b_trap(int argc,char * argv[],Shbltin_t * context)44*b30d1939SAndy Fiddaman int	b_trap(int argc,char *argv[],Shbltin_t *context)
45da2e3ebdSchin {
46da2e3ebdSchin 	register char *arg = argv[1];
477c2fbfb3SApril Chin 	register int sig, clear = 0, dflag = 0, pflag = 0;
48*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
49da2e3ebdSchin 	NOT_USED(argc);
50da2e3ebdSchin 	while (sig = optget(argv, sh_opttrap)) switch (sig)
51da2e3ebdSchin 	{
52da2e3ebdSchin 	    case 'p':
53da2e3ebdSchin 		pflag=1;
54da2e3ebdSchin 		break;
55da2e3ebdSchin 	    case ':':
56da2e3ebdSchin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
57da2e3ebdSchin 		break;
58da2e3ebdSchin 	    case '?':
59da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
60da2e3ebdSchin 		return(2);
61da2e3ebdSchin 		break;
62da2e3ebdSchin 	}
63da2e3ebdSchin 	argv += opt_info.index;
64da2e3ebdSchin 	if(error_info.errors)
65da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
66da2e3ebdSchin 	if(arg = *argv)
67da2e3ebdSchin 	{
68da2e3ebdSchin 		char *action = arg;
697c2fbfb3SApril Chin 		if(!dflag && !pflag)
70da2e3ebdSchin 		{
71da2e3ebdSchin 			/* first argument all digits or - means clear */
72da2e3ebdSchin 			while(isdigit(*arg))
73da2e3ebdSchin 				arg++;
74da2e3ebdSchin 			clear = (arg!=action && *arg==0);
75da2e3ebdSchin 			if(!clear)
76da2e3ebdSchin 			{
77da2e3ebdSchin 				++argv;
78da2e3ebdSchin 				if(*action=='-' && action[1]==0)
79da2e3ebdSchin 					clear++;
807c2fbfb3SApril Chin 				/*
817c2fbfb3SApril Chin 				 * NOTE: 2007-11-26: workaround for tests/signal.sh
827c2fbfb3SApril Chin 				 * if function semantics can be worked out then it
837c2fbfb3SApril Chin 				 * may merit a -d,--default option
847c2fbfb3SApril Chin 				 */
85*b30d1939SAndy Fiddaman 				else if(*action=='+' && action[1]==0 && shp->st.self == &shp->global)
867c2fbfb3SApril Chin 				{
877c2fbfb3SApril Chin 					clear++;
887c2fbfb3SApril Chin 					dflag++;
897c2fbfb3SApril Chin 				}
90da2e3ebdSchin 			}
917c2fbfb3SApril Chin 			if(!argv[0])
92da2e3ebdSchin 				errormsg(SH_DICT,ERROR_exit(1),e_condition);
93da2e3ebdSchin 		}
94da2e3ebdSchin 		while(arg = *argv++)
95da2e3ebdSchin 		{
96*b30d1939SAndy Fiddaman 			sig = sig_number(shp,arg);
97da2e3ebdSchin 			if(sig<0)
98da2e3ebdSchin 			{
99da2e3ebdSchin 				errormsg(SH_DICT,2,e_trap,arg);
100da2e3ebdSchin 				return(1);
101da2e3ebdSchin 			}
102da2e3ebdSchin 			/* internal traps */
103da2e3ebdSchin 			if(sig&SH_TRAP)
104da2e3ebdSchin 			{
105*b30d1939SAndy Fiddaman 				char **trap = (shp->st.otrap?shp->st.otrap:shp->st.trap);
106da2e3ebdSchin 				sig &= ~SH_TRAP;
107da2e3ebdSchin 				if(sig>SH_DEBUGTRAP)
108da2e3ebdSchin 				{
109da2e3ebdSchin 					errormsg(SH_DICT,2,e_trap,arg);
110da2e3ebdSchin 					return(1);
111da2e3ebdSchin 				}
112da2e3ebdSchin 				if(pflag)
113da2e3ebdSchin 				{
114*b30d1939SAndy Fiddaman 					if(arg=trap[sig])
115da2e3ebdSchin 						sfputr(sfstdout,sh_fmtq(arg),'\n');
116da2e3ebdSchin 					continue;
117da2e3ebdSchin 				}
118*b30d1939SAndy Fiddaman 				shp->st.otrap = 0;
119da2e3ebdSchin 				if(shp->st.trap[sig])
120da2e3ebdSchin 					free(shp->st.trap[sig]);
121da2e3ebdSchin 				shp->st.trap[sig] = 0;
122da2e3ebdSchin 				if(!clear && *action)
123da2e3ebdSchin 					shp->st.trap[sig] = strdup(action);
124da2e3ebdSchin 				if(sig == SH_DEBUGTRAP)
125da2e3ebdSchin 				{
126da2e3ebdSchin 					if(shp->st.trap[sig])
127da2e3ebdSchin 						shp->trapnote |= SH_SIGTRAP;
128da2e3ebdSchin 					else
129da2e3ebdSchin 						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 					}
141da2e3ebdSchin 				}
142da2e3ebdSchin 				continue;
143da2e3ebdSchin 			}
144*b30d1939SAndy Fiddaman 			if(sig>shp->gd->sigmax)
145da2e3ebdSchin 			{
146da2e3ebdSchin 				errormsg(SH_DICT,2,e_trap,arg);
147da2e3ebdSchin 				return(1);
148da2e3ebdSchin 			}
149da2e3ebdSchin 			else if(pflag)
150da2e3ebdSchin 			{
151da2e3ebdSchin 				char **trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom);
152da2e3ebdSchin 				if(arg=trapcom[sig])
153da2e3ebdSchin 					sfputr(sfstdout,arg,'\n');
154da2e3ebdSchin 			}
155da2e3ebdSchin 			else if(clear)
1567c2fbfb3SApril Chin 			{
157da2e3ebdSchin 				sh_sigclear(sig);
158*b30d1939SAndy Fiddaman 				if(sig == 0)
159*b30d1939SAndy Fiddaman 					shp->exittrap = 0;
1607c2fbfb3SApril Chin 				if(dflag)
1617c2fbfb3SApril Chin 					signal(sig,SIG_DFL);
1627c2fbfb3SApril Chin 			}
163da2e3ebdSchin 			else
164da2e3ebdSchin 			{
165da2e3ebdSchin 				if(sig >= shp->st.trapmax)
166da2e3ebdSchin 					shp->st.trapmax = sig+1;
16734f9b3eeSRoland Mainz 				arg = shp->st.trapcom[sig];
168da2e3ebdSchin 				sh_sigtrap(sig);
16934f9b3eeSRoland Mainz 				shp->st.trapcom[sig] = (shp->sigflag[sig]&SH_SIGOFF) ? Empty : strdup(action);
17034f9b3eeSRoland Mainz 				if(arg && arg != Empty)
17134f9b3eeSRoland Mainz 					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 				}
177da2e3ebdSchin 			}
178da2e3ebdSchin 		}
179da2e3ebdSchin 	}
180da2e3ebdSchin 	else /* print out current traps */
181*b30d1939SAndy Fiddaman 		sig_list(shp,-2);
182da2e3ebdSchin 	return(0);
183da2e3ebdSchin }
184da2e3ebdSchin 
b_kill(int argc,char * argv[],Shbltin_t * context)185*b30d1939SAndy Fiddaman int	b_kill(int argc,char *argv[],Shbltin_t *context)
186da2e3ebdSchin {
187da2e3ebdSchin 	register char *signame;
188da2e3ebdSchin 	register int sig=SIGTERM, flag=0, n;
189*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
190*b30d1939SAndy Fiddaman 	int usemenu = 0;
191da2e3ebdSchin 	NOT_USED(argc);
192da2e3ebdSchin 	while((n = optget(argv,sh_optkill))) switch(n)
193da2e3ebdSchin 	{
194da2e3ebdSchin 		case ':':
195*b30d1939SAndy Fiddaman 			if((signame=argv[opt_info.index++]) && (sig=sig_number(shp,signame+1))>=0)
196da2e3ebdSchin 				goto endopts;
197da2e3ebdSchin 			opt_info.index--;
198da2e3ebdSchin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
199da2e3ebdSchin 			break;
200da2e3ebdSchin 		case 'n':
201da2e3ebdSchin 			sig = (int)opt_info.num;
202da2e3ebdSchin 			goto endopts;
203da2e3ebdSchin 		case 's':
204da2e3ebdSchin 			flag |= S_FLAG;
205da2e3ebdSchin 			signame = opt_info.arg;
206da2e3ebdSchin 			goto endopts;
207*b30d1939SAndy Fiddaman 		case 'L':
208*b30d1939SAndy Fiddaman 			usemenu = -1;
209*b30d1939SAndy Fiddaman 			/* FALLTHROUGH */
210da2e3ebdSchin 		case 'l':
211da2e3ebdSchin 			flag |= L_FLAG;
212da2e3ebdSchin 			break;
213da2e3ebdSchin 		case '?':
214da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
215da2e3ebdSchin 			break;
216da2e3ebdSchin 	}
217da2e3ebdSchin endopts:
218da2e3ebdSchin 	argv += opt_info.index;
219da2e3ebdSchin 	if(*argv && strcmp(*argv,"--")==0 && strcmp(*(argv-1),"--")!=0)
220da2e3ebdSchin 		argv++;
221da2e3ebdSchin 	if(error_info.errors || flag==(L_FLAG|S_FLAG) || (!(*argv) && !(flag&L_FLAG)))
222da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
223da2e3ebdSchin 	/* just in case we send a kill -9 $$ */
224da2e3ebdSchin 	sfsync(sfstderr);
225da2e3ebdSchin 	if(flag&L_FLAG)
226da2e3ebdSchin 	{
227da2e3ebdSchin 		if(!(*argv))
228*b30d1939SAndy Fiddaman 			sig_list(shp,usemenu);
229da2e3ebdSchin 		else while(signame = *argv++)
230da2e3ebdSchin 		{
231da2e3ebdSchin 			if(isdigit(*signame))
232da2e3ebdSchin 				sig_list(shp,((int)strtol(signame, (char**)0, 10)&0177)+1);
233da2e3ebdSchin 			else
234da2e3ebdSchin 			{
235*b30d1939SAndy Fiddaman 				if((sig=sig_number(shp,signame))<0)
236da2e3ebdSchin 				{
237da2e3ebdSchin 					shp->exitval = 2;
238da2e3ebdSchin 					errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
239da2e3ebdSchin 				}
240da2e3ebdSchin 				sfprintf(sfstdout,"%d\n",sig);
241da2e3ebdSchin 			}
242da2e3ebdSchin 		}
243da2e3ebdSchin 		return(shp->exitval);
244da2e3ebdSchin 	}
245da2e3ebdSchin 	if(flag&S_FLAG)
246da2e3ebdSchin 	{
247*b30d1939SAndy Fiddaman 		if((sig=sig_number(shp,signame)) < 0 || sig > shp->gd->sigmax)
248da2e3ebdSchin 			errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
249da2e3ebdSchin 	}
250da2e3ebdSchin 	if(job_walk(sfstdout,job_kill,sig,argv))
251da2e3ebdSchin 		shp->exitval = 1;
252da2e3ebdSchin 	return(shp->exitval);
253da2e3ebdSchin }
254da2e3ebdSchin 
255da2e3ebdSchin /*
256da2e3ebdSchin  * Given the name or number of a signal return the signal number
257da2e3ebdSchin  */
258da2e3ebdSchin 
sig_number(Shell_t * shp,const char * string)259*b30d1939SAndy Fiddaman static int sig_number(Shell_t *shp,const char *string)
260da2e3ebdSchin {
261da2e3ebdSchin 	const Shtable_t	*tp;
2627c2fbfb3SApril Chin 	register int	n,o,sig=0;
2637c2fbfb3SApril Chin 	char		*last, *name;
264da2e3ebdSchin 	if(isdigit(*string))
265da2e3ebdSchin 	{
266da2e3ebdSchin 		n = strtol(string,&last,10);
267da2e3ebdSchin 		if(*last)
268da2e3ebdSchin 			n = -1;
269da2e3ebdSchin 	}
270da2e3ebdSchin 	else
271da2e3ebdSchin 	{
272da2e3ebdSchin 		register int c;
2737c2fbfb3SApril Chin 		o = staktell();
274da2e3ebdSchin 		do
275da2e3ebdSchin 		{
276da2e3ebdSchin 			c = *string++;
277da2e3ebdSchin 			if(islower(c))
278da2e3ebdSchin 				c = toupper(c);
279da2e3ebdSchin 			stakputc(c);
280da2e3ebdSchin 		}
281da2e3ebdSchin 		while(c);
2827c2fbfb3SApril Chin 		stakseek(o);
2837c2fbfb3SApril Chin 		if(memcmp(stakptr(o),"SIG",3)==0)
284da2e3ebdSchin 		{
285da2e3ebdSchin 			sig = 1;
2867c2fbfb3SApril Chin 			o += 3;
28734f9b3eeSRoland Mainz 			if(isdigit(*stakptr(o)))
28834f9b3eeSRoland Mainz 			{
28934f9b3eeSRoland Mainz 				n = strtol(stakptr(o),&last,10);
29034f9b3eeSRoland Mainz 				if(!*last)
29134f9b3eeSRoland Mainz 					return(n);
29234f9b3eeSRoland Mainz 			}
293da2e3ebdSchin 		}
2947c2fbfb3SApril Chin 		tp = sh_locate(stakptr(o),(const Shtable_t*)shtab_signals,sizeof(*shtab_signals));
295da2e3ebdSchin 		n = tp->sh_number;
296da2e3ebdSchin 		if(sig==1 && (n>=(SH_TRAP-1) && n < (1<<SH_SIGBITS)))
297da2e3ebdSchin 		{
298da2e3ebdSchin 			/* sig prefix cannot match internal traps */
299da2e3ebdSchin 			n = 0;
300da2e3ebdSchin 			tp = (Shtable_t*)((char*)tp + sizeof(*shtab_signals));
3017c2fbfb3SApril Chin 			if(strcmp(stakptr(o),tp->sh_name)==0)
302da2e3ebdSchin 				n = tp->sh_number;
303da2e3ebdSchin 		}
3047c2fbfb3SApril Chin 		if((n>>SH_SIGBITS)&SH_SIGRUNTIME)
305*b30d1939SAndy Fiddaman 			n = shp->gd->sigruntime[(n&((1<<SH_SIGBITS)-1))-1];
3067c2fbfb3SApril Chin 		else
3077c2fbfb3SApril Chin 		{
3087c2fbfb3SApril Chin 			n &= (1<<SH_SIGBITS)-1;
3097c2fbfb3SApril Chin 			if(n < SH_TRAP)
3107c2fbfb3SApril Chin 				n--;
3117c2fbfb3SApril Chin 		}
312*b30d1939SAndy Fiddaman 		if(n<0 && shp->gd->sigruntime[1] && (name=stakptr(o)) && *name++=='R' && *name++=='T')
3137c2fbfb3SApril Chin 		{
3147c2fbfb3SApril Chin 			if(name[0]=='M' && name[1]=='I' && name[2]=='N' && name[3]=='+')
3157c2fbfb3SApril Chin 			{
3167c2fbfb3SApril Chin 				if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
317*b30d1939SAndy Fiddaman 					n = shp->gd->sigruntime[SH_SIGRTMIN] + sig;
3187c2fbfb3SApril Chin 			}
3197c2fbfb3SApril Chin 			else if(name[0]=='M' && name[1]=='A' && name[2]=='X' && name[3]=='-')
3207c2fbfb3SApril Chin 			{
3217c2fbfb3SApril Chin 				if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
322*b30d1939SAndy Fiddaman 					n = shp->gd->sigruntime[SH_SIGRTMAX] - sig;
3237c2fbfb3SApril Chin 			}
3247c2fbfb3SApril Chin 			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])
3277c2fbfb3SApril Chin 				n = -1;
3287c2fbfb3SApril Chin 		}
329da2e3ebdSchin 	}
330da2e3ebdSchin 	return(n);
331da2e3ebdSchin }
332da2e3ebdSchin 
3337c2fbfb3SApril Chin /*
3347c2fbfb3SApril Chin  * synthesize signal name for sig in buf
3357c2fbfb3SApril Chin  * pfx!=0 prepends SIG to default signal number
3367c2fbfb3SApril Chin  */
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)
3387c2fbfb3SApril Chin {
3397c2fbfb3SApril Chin 	register int	i;
3407c2fbfb3SApril Chin 
3417c2fbfb3SApril Chin 	i = 0;
342*b30d1939SAndy Fiddaman 	if(sig>shp->gd->sigruntime[SH_SIGRTMIN] && sig<shp->gd->sigruntime[SH_SIGRTMAX])
3437c2fbfb3SApril Chin 	{
3447c2fbfb3SApril Chin 		buf[i++] = 'R';
3457c2fbfb3SApril Chin 		buf[i++] = 'T';
3467c2fbfb3SApril Chin 		buf[i++] = 'M';
347*b30d1939SAndy Fiddaman 		if(sig>shp->gd->sigruntime[SH_SIGRTMIN]+(shp->gd->sigruntime[SH_SIGRTMAX]-shp->gd->sigruntime[SH_SIGRTMIN])/2)
3487c2fbfb3SApril Chin 		{
3497c2fbfb3SApril Chin 			buf[i++] = 'A';
3507c2fbfb3SApril Chin 			buf[i++] = 'X';
3517c2fbfb3SApril Chin 			buf[i++] = '-';
352*b30d1939SAndy Fiddaman 			sig = shp->gd->sigruntime[SH_SIGRTMAX]-sig;
3537c2fbfb3SApril Chin 		}
3547c2fbfb3SApril Chin 		else
3557c2fbfb3SApril Chin 		{
3567c2fbfb3SApril Chin 			buf[i++] = 'I';
3577c2fbfb3SApril Chin 			buf[i++] = 'N';
3587c2fbfb3SApril Chin 			buf[i++] = '+';
359*b30d1939SAndy Fiddaman 			sig = sig-shp->gd->sigruntime[SH_SIGRTMIN];
3607c2fbfb3SApril Chin 		}
3617c2fbfb3SApril Chin 	}
3627c2fbfb3SApril Chin 	else if(pfx)
3637c2fbfb3SApril Chin 	{
3647c2fbfb3SApril Chin 		buf[i++] = 'S';
3657c2fbfb3SApril Chin 		buf[i++] = 'I';
3667c2fbfb3SApril Chin 		buf[i++] = 'G';
3677c2fbfb3SApril Chin 	}
3687c2fbfb3SApril Chin 	i += sfsprintf(buf+i, 8, "%d", sig);
3697c2fbfb3SApril Chin 	buf[i] = 0;
3707c2fbfb3SApril Chin 	return buf;
3717c2fbfb3SApril Chin }
3727c2fbfb3SApril Chin 
373da2e3ebdSchin /*
374da2e3ebdSchin  * if <flag> is positive, then print signal name corresponding to <flag>
375da2e3ebdSchin  * 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
378da2e3ebdSchin  */
sig_list(register Shell_t * shp,register int flag)379da2e3ebdSchin static void sig_list(register Shell_t *shp,register int flag)
380da2e3ebdSchin {
381da2e3ebdSchin 	register const struct shtable2	*tp;
38234f9b3eeSRoland Mainz 	register int sig;
3837c2fbfb3SApril Chin 	register char *sname;
3847c2fbfb3SApril Chin 	char name[10];
385da2e3ebdSchin 	const char *names[SH_TRAP];
386da2e3ebdSchin 	const char *traps[SH_DEBUGTRAP+1];
387da2e3ebdSchin 	tp=shtab_signals;
3887c2fbfb3SApril Chin 	if(flag<=0)
389da2e3ebdSchin 	{
390da2e3ebdSchin 		/* not all signals may be defined, so initialize */
391*b30d1939SAndy Fiddaman 		for(sig=shp->gd->sigmax; sig>=0; sig--)
392da2e3ebdSchin 			names[sig] = 0;
393da2e3ebdSchin 		for(sig=SH_DEBUGTRAP; sig>=0; sig--)
394da2e3ebdSchin 			traps[sig] = 0;
395da2e3ebdSchin 	}
39634f9b3eeSRoland Mainz 	for(; *tp->sh_name; tp++)
397da2e3ebdSchin 	{
3987c2fbfb3SApril Chin 		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)
40034f9b3eeSRoland Mainz 			continue;
401da2e3ebdSchin 		if(sig==flag)
402da2e3ebdSchin 		{
403da2e3ebdSchin 			sfprintf(sfstdout,"%s\n",tp->sh_name);
404da2e3ebdSchin 			return;
405da2e3ebdSchin 		}
406da2e3ebdSchin 		else if(sig&SH_TRAP)
407da2e3ebdSchin 			traps[sig&~SH_TRAP] = (char*)tp->sh_name;
40834f9b3eeSRoland Mainz 		else if(sig-- && sig < elementsof(names))
409da2e3ebdSchin 			names[sig] = (char*)tp->sh_name;
410da2e3ebdSchin 	}
411da2e3ebdSchin 	if(flag > 0)
412*b30d1939SAndy Fiddaman 		sfputr(sfstdout, sig_name(shp,flag-1,name,0), '\n');
413*b30d1939SAndy Fiddaman 	else if(flag<-1)
414da2e3ebdSchin 	{
415da2e3ebdSchin 		/* print the traps */
4167c2fbfb3SApril Chin 		register char *trap,**trapcom;
417da2e3ebdSchin 		sig = shp->st.trapmax;
418da2e3ebdSchin 		/* use parent traps if otrapcom is set (for $(trap)  */
419da2e3ebdSchin 		trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom);
420da2e3ebdSchin 		while(--sig >= 0)
421da2e3ebdSchin 		{
422da2e3ebdSchin 			if(!(trap=trapcom[sig]))
423da2e3ebdSchin 				continue;
424*b30d1939SAndy Fiddaman 			if(sig > shp->gd->sigmax || !(sname=(char*)names[sig]))
425*b30d1939SAndy Fiddaman 				sname = sig_name(shp,sig,name,1);
426da2e3ebdSchin 			sfprintf(sfstdout,trapfmt,sh_fmtq(trap),sname);
427da2e3ebdSchin 		}
428da2e3ebdSchin 		for(sig=SH_DEBUGTRAP; sig>=0; sig--)
429da2e3ebdSchin 		{
430*b30d1939SAndy Fiddaman 			if(!(trap=shp->st.otrap?shp->st.otrap[sig]:shp->st.trap[sig]))
431da2e3ebdSchin 				continue;
432da2e3ebdSchin 			sfprintf(sfstdout,trapfmt,sh_fmtq(trap),traps[sig]);
433da2e3ebdSchin 		}
434da2e3ebdSchin 	}
435da2e3ebdSchin 	else
436da2e3ebdSchin 	{
437da2e3ebdSchin 		/* print all the signal names */
438*b30d1939SAndy Fiddaman 		for(sig=1; sig <= shp->gd->sigmax; sig++)
439da2e3ebdSchin 		{
44034f9b3eeSRoland Mainz 			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);
455da2e3ebdSchin 		}
456da2e3ebdSchin 	}
457da2e3ebdSchin }
458