xref: /titanic_51/usr/src/lib/libshell/common/bltins/trap.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*3e14f97fSRoger A. Faulkner *          Copyright (c) 1982-2010 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6da2e3ebdSchin *                  Common Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10da2e3ebdSchin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11da2e3ebdSchin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
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 
41da2e3ebdSchin static int	sig_number(const char*);
42da2e3ebdSchin static void	sig_list(Shell_t*,int);
43da2e3ebdSchin 
b_trap(int argc,char * argv[],void * extra)44da2e3ebdSchin int	b_trap(int argc,char *argv[],void *extra)
45da2e3ebdSchin {
46da2e3ebdSchin 	register char *arg = argv[1];
477c2fbfb3SApril Chin 	register int sig, clear = 0, dflag = 0, pflag = 0;
487c2fbfb3SApril Chin 	register Shell_t *shp = ((Shbltin_t*)extra)->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 				 */
857c2fbfb3SApril Chin 				else if(*action=='+' && action[1]==0 && sh.st.self == &sh.global)
867c2fbfb3SApril Chin 				{
877c2fbfb3SApril Chin 					clear++;
887c2fbfb3SApril Chin 					dflag++;
89da2e3ebdSchin 				}
907c2fbfb3SApril Chin 			}
917c2fbfb3SApril Chin 			if(!argv[0])
92da2e3ebdSchin 				errormsg(SH_DICT,ERROR_exit(1),e_condition);
93da2e3ebdSchin 		}
94da2e3ebdSchin 		while(arg = *argv++)
95da2e3ebdSchin 		{
96da2e3ebdSchin 			sig = sig_number(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 			{
105da2e3ebdSchin 				sig &= ~SH_TRAP;
106da2e3ebdSchin 				if(sig>SH_DEBUGTRAP)
107da2e3ebdSchin 				{
108da2e3ebdSchin 					errormsg(SH_DICT,2,e_trap,arg);
109da2e3ebdSchin 					return(1);
110da2e3ebdSchin 				}
111da2e3ebdSchin 				if(pflag)
112da2e3ebdSchin 				{
113da2e3ebdSchin 					if(arg=shp->st.trap[sig])
114da2e3ebdSchin 						sfputr(sfstdout,sh_fmtq(arg),'\n');
115da2e3ebdSchin 					continue;
116da2e3ebdSchin 				}
117da2e3ebdSchin 				if(shp->st.trap[sig])
118da2e3ebdSchin 					free(shp->st.trap[sig]);
119da2e3ebdSchin 				shp->st.trap[sig] = 0;
120da2e3ebdSchin 				if(!clear && *action)
121da2e3ebdSchin 					shp->st.trap[sig] = strdup(action);
122da2e3ebdSchin 				if(sig == SH_DEBUGTRAP)
123da2e3ebdSchin 				{
124da2e3ebdSchin 					if(shp->st.trap[sig])
125da2e3ebdSchin 						shp->trapnote |= SH_SIGTRAP;
126da2e3ebdSchin 					else
127da2e3ebdSchin 						shp->trapnote = 0;
128da2e3ebdSchin 				}
129da2e3ebdSchin 				continue;
130da2e3ebdSchin 			}
131da2e3ebdSchin 			if(sig>shp->sigmax)
132da2e3ebdSchin 			{
133da2e3ebdSchin 				errormsg(SH_DICT,2,e_trap,arg);
134da2e3ebdSchin 				return(1);
135da2e3ebdSchin 			}
136da2e3ebdSchin 			else if(pflag)
137da2e3ebdSchin 			{
138da2e3ebdSchin 				char **trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom);
139da2e3ebdSchin 				if(arg=trapcom[sig])
140da2e3ebdSchin 					sfputr(sfstdout,arg,'\n');
141da2e3ebdSchin 			}
142da2e3ebdSchin 			else if(clear)
1437c2fbfb3SApril Chin 			{
144da2e3ebdSchin 				sh_sigclear(sig);
1457c2fbfb3SApril Chin 				if(dflag)
1467c2fbfb3SApril Chin 					signal(sig,SIG_DFL);
1477c2fbfb3SApril Chin 			}
148da2e3ebdSchin 			else
149da2e3ebdSchin 			{
150da2e3ebdSchin 				if(sig >= shp->st.trapmax)
151da2e3ebdSchin 					shp->st.trapmax = sig+1;
15234f9b3eeSRoland Mainz 				arg = shp->st.trapcom[sig];
153da2e3ebdSchin 				sh_sigtrap(sig);
15434f9b3eeSRoland Mainz 				shp->st.trapcom[sig] = (shp->sigflag[sig]&SH_SIGOFF) ? Empty : strdup(action);
15534f9b3eeSRoland Mainz 				if(arg && arg != Empty)
15634f9b3eeSRoland Mainz 					free(arg);
157da2e3ebdSchin 			}
158da2e3ebdSchin 		}
159da2e3ebdSchin 	}
160da2e3ebdSchin 	else /* print out current traps */
161da2e3ebdSchin 		sig_list(shp,-1);
162da2e3ebdSchin 	return(0);
163da2e3ebdSchin }
164da2e3ebdSchin 
b_kill(int argc,char * argv[],void * extra)165da2e3ebdSchin int	b_kill(int argc,char *argv[],void *extra)
166da2e3ebdSchin {
167da2e3ebdSchin 	register char *signame;
168da2e3ebdSchin 	register int sig=SIGTERM, flag=0, n;
1697c2fbfb3SApril Chin 	register Shell_t *shp = ((Shbltin_t*)extra)->shp;
170da2e3ebdSchin 	NOT_USED(argc);
171da2e3ebdSchin 	while((n = optget(argv,sh_optkill))) switch(n)
172da2e3ebdSchin 	{
173da2e3ebdSchin 		case ':':
174da2e3ebdSchin 			if((signame=argv[opt_info.index++]) && (sig=sig_number(signame+1))>=0)
175da2e3ebdSchin 				goto endopts;
176da2e3ebdSchin 			opt_info.index--;
177da2e3ebdSchin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
178da2e3ebdSchin 			break;
179da2e3ebdSchin 		case 'n':
180da2e3ebdSchin 			sig = (int)opt_info.num;
181da2e3ebdSchin 			goto endopts;
182da2e3ebdSchin 		case 's':
183da2e3ebdSchin 			flag |= S_FLAG;
184da2e3ebdSchin 			signame = opt_info.arg;
185da2e3ebdSchin 			goto endopts;
186da2e3ebdSchin 		case 'l':
187da2e3ebdSchin 			flag |= L_FLAG;
188da2e3ebdSchin 			break;
189da2e3ebdSchin 		case '?':
190da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
191da2e3ebdSchin 			break;
192da2e3ebdSchin 	}
193da2e3ebdSchin endopts:
194da2e3ebdSchin 	argv += opt_info.index;
195da2e3ebdSchin 	if(*argv && strcmp(*argv,"--")==0 && strcmp(*(argv-1),"--")!=0)
196da2e3ebdSchin 		argv++;
197da2e3ebdSchin 	if(error_info.errors || flag==(L_FLAG|S_FLAG) || (!(*argv) && !(flag&L_FLAG)))
198da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage((char*)0));
199da2e3ebdSchin 	/* just in case we send a kill -9 $$ */
200da2e3ebdSchin 	sfsync(sfstderr);
201da2e3ebdSchin 	if(flag&L_FLAG)
202da2e3ebdSchin 	{
203da2e3ebdSchin 		if(!(*argv))
204da2e3ebdSchin 			sig_list(shp,0);
205da2e3ebdSchin 		else while(signame = *argv++)
206da2e3ebdSchin 		{
207da2e3ebdSchin 			if(isdigit(*signame))
208da2e3ebdSchin 				sig_list(shp,((int)strtol(signame, (char**)0, 10)&0177)+1);
209da2e3ebdSchin 			else
210da2e3ebdSchin 			{
211da2e3ebdSchin 				if((sig=sig_number(signame))<0)
212da2e3ebdSchin 				{
213da2e3ebdSchin 					shp->exitval = 2;
214da2e3ebdSchin 					errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
215da2e3ebdSchin 				}
216da2e3ebdSchin 				sfprintf(sfstdout,"%d\n",sig);
217da2e3ebdSchin 			}
218da2e3ebdSchin 		}
219da2e3ebdSchin 		return(shp->exitval);
220da2e3ebdSchin 	}
221da2e3ebdSchin 	if(flag&S_FLAG)
222da2e3ebdSchin 	{
223da2e3ebdSchin 		if((sig=sig_number(signame)) < 0 || sig > shp->sigmax)
224da2e3ebdSchin 			errormsg(SH_DICT,ERROR_exit(1),e_nosignal,signame);
225da2e3ebdSchin 	}
226da2e3ebdSchin 	if(job_walk(sfstdout,job_kill,sig,argv))
227da2e3ebdSchin 		shp->exitval = 1;
228da2e3ebdSchin 	return(shp->exitval);
229da2e3ebdSchin }
230da2e3ebdSchin 
231da2e3ebdSchin /*
232da2e3ebdSchin  * Given the name or number of a signal return the signal number
233da2e3ebdSchin  */
234da2e3ebdSchin 
sig_number(const char * string)235da2e3ebdSchin static int sig_number(const char *string)
236da2e3ebdSchin {
237da2e3ebdSchin 	const Shtable_t	*tp;
2387c2fbfb3SApril Chin 	register int	n,o,sig=0;
2397c2fbfb3SApril Chin 	char		*last, *name;
240da2e3ebdSchin 	if(isdigit(*string))
241da2e3ebdSchin 	{
242da2e3ebdSchin 		n = strtol(string,&last,10);
243da2e3ebdSchin 		if(*last)
244da2e3ebdSchin 			n = -1;
245da2e3ebdSchin 	}
246da2e3ebdSchin 	else
247da2e3ebdSchin 	{
248da2e3ebdSchin 		register int c;
2497c2fbfb3SApril Chin 		o = staktell();
250da2e3ebdSchin 		do
251da2e3ebdSchin 		{
252da2e3ebdSchin 			c = *string++;
253da2e3ebdSchin 			if(islower(c))
254da2e3ebdSchin 				c = toupper(c);
255da2e3ebdSchin 			stakputc(c);
256da2e3ebdSchin 		}
257da2e3ebdSchin 		while(c);
2587c2fbfb3SApril Chin 		stakseek(o);
2597c2fbfb3SApril Chin 		if(memcmp(stakptr(o),"SIG",3)==0)
260da2e3ebdSchin 		{
261da2e3ebdSchin 			sig = 1;
2627c2fbfb3SApril Chin 			o += 3;
26334f9b3eeSRoland Mainz 			if(isdigit(*stakptr(o)))
26434f9b3eeSRoland Mainz 			{
26534f9b3eeSRoland Mainz 				n = strtol(stakptr(o),&last,10);
26634f9b3eeSRoland Mainz 				if(!*last)
26734f9b3eeSRoland Mainz 					return(n);
26834f9b3eeSRoland Mainz 			}
269da2e3ebdSchin 		}
2707c2fbfb3SApril Chin 		tp = sh_locate(stakptr(o),(const Shtable_t*)shtab_signals,sizeof(*shtab_signals));
271da2e3ebdSchin 		n = tp->sh_number;
272da2e3ebdSchin 		if(sig==1 && (n>=(SH_TRAP-1) && n < (1<<SH_SIGBITS)))
273da2e3ebdSchin 		{
274da2e3ebdSchin 			/* sig prefix cannot match internal traps */
275da2e3ebdSchin 			n = 0;
276da2e3ebdSchin 			tp = (Shtable_t*)((char*)tp + sizeof(*shtab_signals));
2777c2fbfb3SApril Chin 			if(strcmp(stakptr(o),tp->sh_name)==0)
278da2e3ebdSchin 				n = tp->sh_number;
279da2e3ebdSchin 		}
2807c2fbfb3SApril Chin 		if((n>>SH_SIGBITS)&SH_SIGRUNTIME)
2817c2fbfb3SApril Chin 			n = sh.sigruntime[(n&((1<<SH_SIGBITS)-1))-1];
2827c2fbfb3SApril Chin 		else
2837c2fbfb3SApril Chin 		{
284da2e3ebdSchin 			n &= (1<<SH_SIGBITS)-1;
285da2e3ebdSchin 			if(n < SH_TRAP)
286da2e3ebdSchin 				n--;
287da2e3ebdSchin 		}
28834f9b3eeSRoland Mainz 		if(n<0 && sh.sigruntime[1] && (name=stakptr(o)) && *name++=='R' && *name++=='T')
2897c2fbfb3SApril Chin 		{
2907c2fbfb3SApril Chin 			if(name[0]=='M' && name[1]=='I' && name[2]=='N' && name[3]=='+')
2917c2fbfb3SApril Chin 			{
2927c2fbfb3SApril Chin 				if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
2937c2fbfb3SApril Chin 					n = sh.sigruntime[SH_SIGRTMIN] + sig;
2947c2fbfb3SApril Chin 			}
2957c2fbfb3SApril Chin 			else if(name[0]=='M' && name[1]=='A' && name[2]=='X' && name[3]=='-')
2967c2fbfb3SApril Chin 			{
2977c2fbfb3SApril Chin 				if((sig=(int)strtol(name+4,&name,10)) >= 0 && !*name)
2987c2fbfb3SApril Chin 					n = sh.sigruntime[SH_SIGRTMAX] - sig;
2997c2fbfb3SApril Chin 			}
3007c2fbfb3SApril Chin 			else if((sig=(int)strtol(name,&name,10)) > 0 && !*name)
3017c2fbfb3SApril Chin 				n = sh.sigruntime[SH_SIGRTMIN] + sig - 1;
3027c2fbfb3SApril Chin 			if(n<sh.sigruntime[SH_SIGRTMIN] || n>sh.sigruntime[SH_SIGRTMAX])
3037c2fbfb3SApril Chin 				n = -1;
3047c2fbfb3SApril Chin 		}
3057c2fbfb3SApril Chin 	}
306da2e3ebdSchin 	return(n);
307da2e3ebdSchin }
308da2e3ebdSchin 
309da2e3ebdSchin /*
3107c2fbfb3SApril Chin  * synthesize signal name for sig in buf
3117c2fbfb3SApril Chin  * pfx!=0 prepends SIG to default signal number
3127c2fbfb3SApril Chin  */
sig_name(int sig,char * buf,int pfx)3137c2fbfb3SApril Chin static char* sig_name(int sig, char* buf, int pfx)
3147c2fbfb3SApril Chin {
3157c2fbfb3SApril Chin 	register int	i;
3167c2fbfb3SApril Chin 
3177c2fbfb3SApril Chin 	i = 0;
3187c2fbfb3SApril Chin 	if(sig>sh.sigruntime[SH_SIGRTMIN] && sig<sh.sigruntime[SH_SIGRTMAX])
3197c2fbfb3SApril Chin 	{
3207c2fbfb3SApril Chin 		buf[i++] = 'R';
3217c2fbfb3SApril Chin 		buf[i++] = 'T';
3227c2fbfb3SApril Chin 		buf[i++] = 'M';
3237c2fbfb3SApril Chin 		if(sig>sh.sigruntime[SH_SIGRTMIN]+(sh.sigruntime[SH_SIGRTMAX]-sh.sigruntime[SH_SIGRTMIN])/2)
3247c2fbfb3SApril Chin 		{
3257c2fbfb3SApril Chin 			buf[i++] = 'A';
3267c2fbfb3SApril Chin 			buf[i++] = 'X';
3277c2fbfb3SApril Chin 			buf[i++] = '-';
3287c2fbfb3SApril Chin 			sig = sh.sigruntime[SH_SIGRTMAX]-sig;
3297c2fbfb3SApril Chin 		}
3307c2fbfb3SApril Chin 		else
3317c2fbfb3SApril Chin 		{
3327c2fbfb3SApril Chin 			buf[i++] = 'I';
3337c2fbfb3SApril Chin 			buf[i++] = 'N';
3347c2fbfb3SApril Chin 			buf[i++] = '+';
3357c2fbfb3SApril Chin 			sig = sig-sh.sigruntime[SH_SIGRTMIN];
3367c2fbfb3SApril Chin 		}
3377c2fbfb3SApril Chin 	}
3387c2fbfb3SApril Chin 	else if(pfx)
3397c2fbfb3SApril Chin 	{
3407c2fbfb3SApril Chin 		buf[i++] = 'S';
3417c2fbfb3SApril Chin 		buf[i++] = 'I';
3427c2fbfb3SApril Chin 		buf[i++] = 'G';
3437c2fbfb3SApril Chin 	}
3447c2fbfb3SApril Chin 	i += sfsprintf(buf+i, 8, "%d", sig);
3457c2fbfb3SApril Chin 	buf[i] = 0;
3467c2fbfb3SApril Chin 	return buf;
3477c2fbfb3SApril Chin }
3487c2fbfb3SApril Chin 
3497c2fbfb3SApril Chin /*
350da2e3ebdSchin  * if <flag> is positive, then print signal name corresponding to <flag>
351da2e3ebdSchin  * if <flag> is zero, then print all signal names
352da2e3ebdSchin  * if <flag> is negative, then print all traps
353da2e3ebdSchin  */
sig_list(register Shell_t * shp,register int flag)354da2e3ebdSchin static void sig_list(register Shell_t *shp,register int flag)
355da2e3ebdSchin {
356da2e3ebdSchin 	register const struct shtable2	*tp;
35734f9b3eeSRoland Mainz 	register int sig;
3587c2fbfb3SApril Chin 	register char *sname;
3597c2fbfb3SApril Chin 	char name[10];
360da2e3ebdSchin 	const char *names[SH_TRAP];
361da2e3ebdSchin 	const char *traps[SH_DEBUGTRAP+1];
362da2e3ebdSchin 	tp=shtab_signals;
3637c2fbfb3SApril Chin 	if(flag<=0)
364da2e3ebdSchin 	{
365da2e3ebdSchin 		/* not all signals may be defined, so initialize */
36634f9b3eeSRoland Mainz 		for(sig=shp->sigmax; sig>=0; sig--)
367da2e3ebdSchin 			names[sig] = 0;
368da2e3ebdSchin 		for(sig=SH_DEBUGTRAP; sig>=0; sig--)
369da2e3ebdSchin 			traps[sig] = 0;
370da2e3ebdSchin 	}
37134f9b3eeSRoland Mainz 	for(; *tp->sh_name; tp++)
372da2e3ebdSchin 	{
3737c2fbfb3SApril Chin 		sig = tp->sh_number&((1<<SH_SIGBITS)-1);
37434f9b3eeSRoland Mainz 		if (((tp->sh_number>>SH_SIGBITS) & SH_SIGRUNTIME) && (sig = sh.sigruntime[sig-1]+1) == 1)
37534f9b3eeSRoland Mainz 			continue;
376da2e3ebdSchin 		if(sig==flag)
377da2e3ebdSchin 		{
378da2e3ebdSchin 			sfprintf(sfstdout,"%s\n",tp->sh_name);
379da2e3ebdSchin 			return;
380da2e3ebdSchin 		}
381da2e3ebdSchin 		else if(sig&SH_TRAP)
382da2e3ebdSchin 			traps[sig&~SH_TRAP] = (char*)tp->sh_name;
38334f9b3eeSRoland Mainz 		else if(sig-- && sig < elementsof(names))
384da2e3ebdSchin 			names[sig] = (char*)tp->sh_name;
385da2e3ebdSchin 	}
386da2e3ebdSchin 	if(flag > 0)
3877c2fbfb3SApril Chin 		sfputr(sfstdout, sig_name(flag-1,name,0), '\n');
388da2e3ebdSchin 	else if(flag<0)
389da2e3ebdSchin 	{
390da2e3ebdSchin 		/* print the traps */
3917c2fbfb3SApril Chin 		register char *trap,**trapcom;
392da2e3ebdSchin 		sig = shp->st.trapmax;
393da2e3ebdSchin 		/* use parent traps if otrapcom is set (for $(trap)  */
394da2e3ebdSchin 		trapcom = (shp->st.otrapcom?shp->st.otrapcom:shp->st.trapcom);
395da2e3ebdSchin 		while(--sig >= 0)
396da2e3ebdSchin 		{
397da2e3ebdSchin 			if(!(trap=trapcom[sig]))
398da2e3ebdSchin 				continue;
39934f9b3eeSRoland Mainz 			if(sig > shp->sigmax || !(sname=(char*)names[sig]))
4007c2fbfb3SApril Chin 				sname = sig_name(sig,name,1);
401da2e3ebdSchin 			sfprintf(sfstdout,trapfmt,sh_fmtq(trap),sname);
402da2e3ebdSchin 		}
403da2e3ebdSchin 		for(sig=SH_DEBUGTRAP; sig>=0; sig--)
404da2e3ebdSchin 		{
405da2e3ebdSchin 			if(!(trap=shp->st.trap[sig]))
406da2e3ebdSchin 				continue;
407da2e3ebdSchin 			sfprintf(sfstdout,trapfmt,sh_fmtq(trap),traps[sig]);
408da2e3ebdSchin 		}
409da2e3ebdSchin 	}
410da2e3ebdSchin 	else
411da2e3ebdSchin 	{
412da2e3ebdSchin 		/* print all the signal names */
41334f9b3eeSRoland Mainz 		for(sig=1; sig <= shp->sigmax; sig++)
414da2e3ebdSchin 		{
41534f9b3eeSRoland Mainz 			if(!(sname=(char*)names[sig]))
4167c2fbfb3SApril Chin 				sname = sig_name(sig,name,1);
4177c2fbfb3SApril Chin 			sfputr(sfstdout,sname,'\n');
418da2e3ebdSchin 		}
419da2e3ebdSchin 	}
420da2e3ebdSchin }
421