remove OSF1 support
[oweals/cde.git] / cde / programs / dtksh / ksh93 / src / cmd / ksh93 / bltins / trap.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these libraries and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: trap.c /main/4 1996/08/16 15:31:57 rswiston $ */
24 /***************************************************************
25 *                                                              *
26 *                      AT&T - PROPRIETARY                      *
27 *                                                              *
28 *        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF        *
29 *                    AT&T BELL LABORATORIES                    *
30 *         AND IS NOT TO BE DISCLOSED OR USED EXCEPT IN         *
31 *            ACCORDANCE WITH APPLICABLE AGREEMENTS             *
32 *                                                              *
33 *                Copyright (c) 1995 AT&T Corp.                 *
34 *              Unpublished & Not for Publication               *
35 *                     All Rights Reserved                      *
36 *                                                              *
37 *       The copyright notice above does not evidence any       *
38 *      actual or intended publication of such source code      *
39 *                                                              *
40 *               This software was created by the               *
41 *           Advanced Software Technology Department            *
42 *                    AT&T Bell Laboratories                    *
43 *                                                              *
44 *               For further information contact                *
45 *                    {research,attmail}!dgk                    *
46 *                                                              *
47 ***************************************************************/
48
49 /* : : generated by proto : : */
50
51 #if !defined(__PROTO__)
52 #if defined(__STDC__) || defined(__cplusplus) || defined(_proto) || defined(c_plusplus)
53 #if defined(__cplusplus)
54 #define __MANGLE__      "C"
55 #else
56 #define __MANGLE__
57 #endif
58 #define __STDARG__
59 #define __PROTO__(x)    x
60 #define __OTORP__(x)
61 #define __PARAM__(n,o)  n
62 #if !defined(__STDC__) && !defined(__cplusplus)
63 #if !defined(c_plusplus)
64 #define const
65 #endif
66 #define signed
67 #define void            int
68 #define volatile
69 #define __V_            char
70 #else
71 #define __V_            void
72 #endif
73 #else
74 #define __PROTO__(x)    ()
75 #define __OTORP__(x)    x
76 #define __PARAM__(n,o)  o
77 #define __MANGLE__
78 #define __V_            char
79 #define const
80 #define signed
81 #define void            int
82 #define volatile
83 #endif
84 #if defined(__cplusplus) || defined(c_plusplus)
85 #define __VARARG__      ...
86 #else
87 #define __VARARG__
88 #endif
89 #if defined(__STDARG__)
90 #define __VA_START__(p,a)       va_start(p,a)
91 #else
92 #define __VA_START__(p,a)       va_start(p)
93 #endif
94 #endif
95 #include        "defs.h"
96 #include        <ctype.h>
97 #include        "jobs.h"
98 #include        "builtins.h"
99
100 #define L_FLAG  1
101 #define S_FLAG  2
102
103 static const char trapfmt[] = "trap -- %s %s\n";
104
105 static int      sig_number __PROTO__((const char*));
106 static void     sig_list __PROTO__((int));
107
108 int     b_trap __PARAM__((int argc,char *argv[],__V_ *extra), (argc, argv, extra)) __OTORP__(int argc;char *argv[];__V_ *extra;){
109         register char *arg = argv[1];
110         register int sig, pflag = 0;
111         NOT_USED(argc);
112         NOT_USED(extra);
113         while (sig = optget(argv, sh_opttrap)) switch (sig)
114         {
115             case 'p':
116                 pflag=1;
117                 break;
118             case ':':
119                 error(2, opt_arg);
120                 break;
121             case '?':
122                 error(ERROR_usage(2), opt_arg);
123                 break;
124         }
125         argv += opt_index;
126         if(error_info.errors)
127                 error(ERROR_usage(2),optusage((char*)0));
128         if(arg = *argv)
129         {
130                 register int    clear;
131                 char *action = arg;
132                 if(!pflag)
133                 {
134                         /* first argument all digits or - means clear */
135                         while(isdigit(*arg))
136                                 arg++;
137                         clear = (arg!=action && *arg==0);
138                         if(!clear)
139                         {
140                                 ++argv;
141                                 if(*action=='-' && action[1]==0)
142                                         clear++;
143                         }
144                         while(!argv[0])
145                                 error(ERROR_exit(1),e_condition);
146                 }
147                 while(arg = *argv++)
148                 {
149                         sig = sig_number(arg);
150                         if(sig<0)
151                         {
152                                 error(2,e_trap,arg);
153                                 return(1);
154                         }
155                         /* internal traps */
156                         if(sig&SH_TRAP)
157                         {
158                                 sig &= ~SH_TRAP;
159                                 if(sig>SH_DEBUGTRAP)
160                                 {
161                                         error(2,e_trap,arg);
162                                         return(1);
163                                 }
164                                 if(pflag)
165                                 {
166                                         if(arg=sh.st.trap[sig])
167                                                 sfputr(sfstdout,sh_fmtq(arg),'\n');
168                                         continue;
169                                 }
170                                 if(sh.st.trap[sig])
171                                         free(sh.st.trap[sig]);
172                                 sh.st.trap[sig] = 0;
173                                 if(!clear && *action)
174                                         sh.st.trap[sig] = strdup(action);
175                                 if(sig == SH_DEBUGTRAP)
176                                 {
177                                         if(sh.st.trap[sig])
178                                                 sh.trapnote |= SH_SIGTRAP;
179                                         else
180                                                 sh.trapnote = 0;
181                                 }
182                                 continue;
183                         }
184                         if(sig>sh.sigmax)
185                         {
186                                 error(2,e_trap,arg);
187                                 return(1);
188                         }
189                         else if(pflag)
190                         {
191                                 if(arg=sh.st.trapcom[sig])
192                                         sfputr(sfstdout,sh_fmtq(arg),'\n');
193                         }
194                         else if(clear)
195                                 sh_sigclear(sig);
196                         else
197                         {
198                                 if(sig >= sh.st.trapmax)
199                                         sh.st.trapmax = sig+1;
200                                 if(arg=sh.st.trapcom[sig])
201                                         free(arg);
202                                 sh.st.trapcom[sig] = strdup(action);
203                                 sh_sigtrap(sig);
204                         }
205                 }
206         }
207         else /* print out current traps */
208                 sig_list(-1);
209         return(0);
210 }
211
212 int     b_kill __PARAM__((int argc,char *argv[],__V_ *extra), (argc, argv, extra)) __OTORP__(int argc;char *argv[];__V_ *extra;){
213         register char *signame;
214         register int sig=SIGTERM, flag=0, n;
215         NOT_USED(argc);
216         NOT_USED(extra);
217         while((n = optget(argv,sh_optkill))) switch(n)
218         {
219                 case ':':
220                         if((signame=argv[opt_index++]) && (sig=sig_number(signame+1))>=0)
221                         {
222                                 if(argv[opt_index] && strcmp(argv[opt_index],"--")==0)
223                                         opt_index++;
224                                 goto endopts;
225                         }
226                         opt_index--;
227                         error(2, opt_arg);
228                         break;
229                 case 'n':
230                         sig = (int)opt_num;
231                         break;
232                 case 's':
233                         flag |= S_FLAG;
234                         signame = opt_arg;
235                         break;
236                 case 'l':
237                         flag |= L_FLAG;
238                         break;
239                 case '?':
240                         error(ERROR_usage(2), opt_arg);
241                         break;
242         }
243 endopts:
244         argv += opt_index;
245         if(error_info.errors || flag==(L_FLAG|S_FLAG) || (!(*argv) && !(flag&L_FLAG)))
246                 error(ERROR_usage(2),optusage((char*)0));
247         /* just in case we send a kill -9 $$ */
248         sfsync(sfstderr);
249         if(flag&L_FLAG)
250         {
251                 if(!(*argv))
252                         sig_list(0);
253                 else while(signame = *argv++)
254                 {
255                         if(isdigit(*signame))
256                                 sig_list((atoi(signame)&0177)+1);
257                         else
258                         {
259                                 if((sig=sig_number(signame))<0)
260                                 {
261                                         sh.exitval = 2;
262                                         error(ERROR_exit(1),e_nosignal,signame);
263                                 }
264                                 sfprintf(sfstdout,"%d\n",sig);
265                         }
266                 }
267                 return(sh.exitval);
268         }
269         if(flag&S_FLAG)
270         {
271                 if((sig=sig_number(signame)) < 0 || sig > sh.sigmax)
272                         error(ERROR_exit(1),e_nosignal,signame);
273         }
274         if(job_walk(sfstdout,job_kill,sig,argv))
275                 sh.exitval = 1;
276         return(sh.exitval);
277 }
278
279 /*
280  * Given the name or number of a signal return the signal number
281  */
282
283 static int sig_number __PARAM__((const char *string), (string)) __OTORP__(const char *string;){
284         register int n;
285         char *last;
286         if(isdigit(*string))
287         {
288                 n = strtol(string,&last,10);
289                 if(*last)
290                         n = -1;
291         }
292         else
293         {
294                 register int c;
295                 n = staktell();
296                 do
297                 {
298                         c = *string++;
299                         if(islower(c))
300                                 c = toupper(c);
301                         stakputc(c);
302                 }
303                 while(c);
304                 stakseek(n);
305                 init_shtab_signals();
306                 n = sh_lookup(stakptr(n),shtab_signals);
307                 n &= (1<<SH_SIGBITS)-1;
308                 if(n < SH_TRAP)
309                         n--;
310         }
311         return(n);
312 }
313
314 /*
315  * if <flag> is positive, then print signal name corresponding to <flag>
316  * if <flag> is zero, then print all signal names
317  * if <flag> is negative, then print all traps
318  */
319 static void sig_list __PARAM__((register int flag), (flag)) __OTORP__(register int flag;){
320         register const struct shtable2  *tp;
321         register int sig = sh.sigmax+1;
322         const char *names[SH_TRAP];
323         const char *traps[SH_DEBUGTRAP+1];
324
325         init_shtab_signals();
326
327         tp=shtab_signals;
328         if(flag==0)
329         {
330                 /* not all signals may be defined, so initialize */
331                 while(--sig >= 0)
332                         names[sig] = 0;
333                 for(sig=SH_DEBUGTRAP; sig>=0; sig--)
334                         traps[sig] = 0;
335         }
336         while(*tp->sh_name)
337         {
338                 sig = tp->sh_number;
339                 sig &= ((1<<SH_SIGBITS)-1);
340                 if(sig==flag)
341                 {
342                         sfprintf(sfstdout,"%s\n",tp->sh_name);
343                         return;
344                 }
345                 else if(sig&SH_TRAP)
346                         traps[sig&~SH_TRAP] = (char*)tp->sh_name;
347                 else if(sig < sizeof(names)/sizeof(char*))
348                         names[sig] = (char*)tp->sh_name;
349                 tp++;
350         }
351         if(flag > 0)
352                 sfprintf(sfstdout,"%d\n",flag-1);
353         else if(flag<0)
354         {
355                 /* print the traps */
356                 register char *trap,*sname,**trapcom;
357                 sig = sh.st.trapmax;
358                 /* use parent traps if otrapcom is set (for $(trap)  */
359                 trapcom = (sh.st.otrapcom?sh.st.otrapcom:sh.st.trapcom);
360                 while(--sig >= 0)
361                 {
362                         if(!(trap=trapcom[sig]))
363                                 continue;
364                         if(!(sname=(char*)names[sig+1]))
365                         {
366                                 sname="SIG??";
367                                 sname[3] = (sig/10)+'0';
368                                 sname[4] = (sig%10)+'0';
369                         }
370                         sfprintf(sfstdout,trapfmt,sh_fmtq(trap),sname);
371                 }
372                 for(sig=SH_DEBUGTRAP; sig>=0; sig--)
373                 {
374                         if(!(trap=sh.st.trap[sig]))
375                                 continue;
376                         sfprintf(sfstdout,trapfmt,sh_fmtq(trap),traps[sig]);
377                 }
378         }
379         else
380         {
381                 /* print all the signal names */
382                 for(sig=2; sig <= sh.sigmax; sig++)
383                 {
384                         if(names[sig])
385                                 sfputr(sfstdout,names[sig],'\n');
386                         else
387                                 sfprintf(sfstdout,"SIG%d\n",sig-1);
388                 }
389         }
390 }
391