Postfix3.3.1
posix_signals.c
[詳解]
1 /*++
2 /* NAME
3 /* posix_signals 3
4 /* SUMMARY
5 /* POSIX signal handling compatibility
6 /* SYNOPSIS
7 /* #include <posix_signals.h>
8 /*
9 /* int sigemptyset(m)
10 /* sigset_t *m;
11 /*
12 /* int sigaddset(set, signum)
13 /* sigset_t *set;
14 /* int signum;
15 /*
16 /* int sigprocmask(how, set, old)
17 /* int how;
18 /* sigset_t *set;
19 /* sigset_t *old;
20 /*
21 /* int sigaction(sig, act, oact)
22 /* int sig;
23 /* struct sigaction *act;
24 /* struct sigaction *oact;
25 /* DESCRIPTION
26 /* These routines emulate the POSIX signal handling interface.
27 /* AUTHOR(S)
28 /* Pieter Schoenmakers
29 /* Eindhoven University of Technology
30 /* P.O. Box 513
31 /* 5600 MB Eindhoven
32 /* The Netherlands
33 /*--*/
34 
35 /* System library. */
36 
37 #include "sys_defs.h"
38 #include <signal.h>
39 #include <errno.h>
40 
41 /* Utility library.*/
42 
43 #include "posix_signals.h"
44 
45 #ifdef MISSING_SIGSET_T
46 
47 int sigemptyset(sigset_t *m)
48 {
49  return *m = 0;
50 }
51 
52 int sigaddset(sigset_t *set, int signum)
53 {
54  *set |= sigmask(signum);
55  return 0;
56 }
57 
58 int sigprocmask(int how, sigset_t *set, sigset_t *old)
59 {
60  int previous;
61 
62  if (how == SIG_BLOCK)
63  previous = sigblock(*set);
64  else if (how == SIG_SETMASK)
65  previous = sigsetmask(*set);
66  else if (how == SIG_UNBLOCK) {
67  int m = sigblock(0);
68 
69  previous = sigsetmask(m & ~*set);
70  } else {
71  errno = EINVAL;
72  return -1;
73  }
74 
75  if (old)
76  *old = previous;
77  return 0;
78 }
79 
80 #endif
81 
82 #ifdef MISSING_SIGACTION
83 
84 static struct sigaction actions[NSIG] = {};
85 
86 static int sighandle(int signum)
87 {
88  if (signum == SIGCHLD) {
89  /* XXX If the child is just stopped, don't invoke the handler. */
90  }
91  actions[signum].sa_handler(signum);
92 }
93 
94 int sigaction(int sig, struct sigaction *act, struct sigaction *oact)
95 {
96  static int initialized = 0;
97 
98  if (!initialized) {
99  int i;
100 
101  for (i = 0; i < NSIG; i++)
102  actions[i].sa_handler = SIG_DFL;
103  initialized = 1;
104  }
105  if (sig <= 0 || sig >= NSIG) {
106  errno = EINVAL;
107  return -1;
108  }
109  if (oact)
110  *oact = actions[sig];
111 
112  {
113  struct sigvec mine = {
114  sighandle, act->sa_mask,
115  act->sa_flags & SA_RESTART ? SV_INTERRUPT : 0
116  };
117 
118  if (sigvec(sig, &mine, NULL))
119  return -1;
120  }
121 
122  actions[sig] = *act;
123  return 0;
124 }
125 
126 #endif