[4.0] Use strip (instead of eu-strip) to support --strip-debug of *.so at build time
[platform/upstream/rpm.git] / rpmio / rpmsq.c
1 /** \ingroup rpmio
2  * \file rpmio/rpmsq.c
3  */
4
5 #include "system.h"
6
7 #include <signal.h>
8 #include <sys/signal.h>
9 #include <errno.h>
10 #include <stdio.h>
11
12 #define ADD_REF(__tbl)  (__tbl)->active++
13 #define SUB_REF(__tbl)  --(__tbl)->active
14
15 #include <rpm/rpmsq.h>
16
17 #include "debug.h"
18
19 static sigset_t rpmsqCaught;
20
21 typedef struct rpmsig_s * rpmsig;
22
23 static struct rpmsig_s {
24     int signum;
25     rpmsqAction_t handler;
26     int active;
27     struct sigaction oact;
28 } rpmsigTbl[] = {
29     { SIGINT,   rpmsqAction },
30 #define rpmsigTbl_sigint        (&rpmsigTbl[0])
31     { SIGQUIT,  rpmsqAction },
32 #define rpmsigTbl_sigquit       (&rpmsigTbl[1])
33     { SIGHUP,   rpmsqAction },
34 #define rpmsigTbl_sighup        (&rpmsigTbl[3])
35     { SIGTERM,  rpmsqAction },
36 #define rpmsigTbl_sigterm       (&rpmsigTbl[4])
37     { SIGPIPE,  rpmsqAction },
38 #define rpmsigTbl_sigpipe       (&rpmsigTbl[5])
39     { -1,       NULL },
40 };
41
42 int rpmsqIsCaught(int signum)
43 {
44     return sigismember(&rpmsqCaught, signum);
45 }
46
47 #ifdef SA_SIGINFO
48 void rpmsqAction(int signum, siginfo_t * info, void * context)
49 #else
50 void rpmsqAction(int signum)
51 #endif
52 {
53     int save = errno;
54     rpmsig tbl;
55
56     for (tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
57         if (tbl->signum != signum)
58             continue;
59
60         (void) sigaddset(&rpmsqCaught, signum);
61         break;
62     }
63     errno = save;
64 }
65
66 int rpmsqEnable(int signum, rpmsqAction_t handler)
67 {
68     int tblsignum = (signum >= 0 ? signum : -signum);
69     struct sigaction sa;
70     rpmsig tbl;
71     int ret = -1;
72
73     for (tbl = rpmsigTbl; tbl->signum >= 0; tbl++) {
74         if (tblsignum != tbl->signum)
75             continue;
76
77         if (signum >= 0) {                      /* Enable. */
78             if (ADD_REF(tbl) <= 0) {
79                 (void) sigdelset(&rpmsqCaught, tbl->signum);
80
81                 /* XXX Don't set a signal handler if already SIG_IGN */
82                 (void) sigaction(tbl->signum, NULL, &tbl->oact);
83                 if (tbl->oact.sa_handler == SIG_IGN)
84                     continue;
85
86                 (void) sigemptyset (&sa.sa_mask);
87 #ifdef SA_SIGINFO
88                 sa.sa_flags = SA_SIGINFO;
89 #else
90                 sa.sa_flags = 0;
91 #endif
92                 sa.sa_sigaction = (handler != NULL ? handler : tbl->handler);
93                 if (sigaction(tbl->signum, &sa, &tbl->oact) < 0) {
94                     SUB_REF(tbl);
95                     break;
96                 }
97                 tbl->active = 1;                /* XXX just in case */
98                 if (handler != NULL)
99                     tbl->handler = handler;
100             }
101         } else {                                /* Disable. */
102             if (SUB_REF(tbl) <= 0) {
103                 if (sigaction(tbl->signum, &tbl->oact, NULL) < 0)
104                     break;
105                 tbl->active = 0;                /* XXX just in case */
106                 tbl->handler = (handler != NULL ? handler : rpmsqAction);
107             }
108         }
109         ret = tbl->active;
110         break;
111     }
112     return ret;
113 }
114