summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-11-26 13:49:37 +0000
committerkib <kib@FreeBSD.org>2009-11-26 13:49:37 +0000
commit878f33c39357795d6a94d97a21c503a52b96cb9e (patch)
tree1d70aa0b7d5fbac18fcff176e116e1f9f260c88c
parenta5ec5de71c3dddde8033e4f88627b7a80d430af1 (diff)
downloadFreeBSD-src-878f33c39357795d6a94d97a21c503a52b96cb9e.zip
FreeBSD-src-878f33c39357795d6a94d97a21c503a52b96cb9e.tar.gz
Implement sighold, sigignore, sigpause, sigrelse, sigset functions
from SUSv4 XSI. Note that the functions are obsoleted, and only provided to ease porting from System V-like systems. Since sigpause already exists in compat with different interface, XSI sigpause is named xsi_sigpause. Reviewed by: davidxu MFC after: 3 weeks
-rw-r--r--include/signal.h7
-rw-r--r--lib/libc/compat-43/Makefile.inc5
-rw-r--r--lib/libc/compat-43/Symbol.map8
-rw-r--r--lib/libc/compat-43/sigcompat.c85
-rw-r--r--lib/libc/compat-43/sigpause.2160
-rw-r--r--sys/sys/signal.h5
-rw-r--r--sys/sys/signalvar.h2
7 files changed, 259 insertions, 13 deletions
diff --git a/include/signal.h b/include/signal.h
index fdb4b3e..1af0e36 100644
--- a/include/signal.h
+++ b/include/signal.h
@@ -99,7 +99,12 @@ int sigwaitinfo(const sigset_t * __restrict, siginfo_t * __restrict);
#if __XSI_VISIBLE
int killpg(__pid_t, int);
int sigaltstack(const stack_t * __restrict, stack_t * __restrict);
-int sigpause(int);
+int sighold(int sig);
+int sigignore(int sig);
+int sigpause(int sigmask);
+int sigrelse(int sig);
+void (*sigset(int sig, void (*disp)(int)))(int);
+int xsi_sigpause(int sig);
#endif
#if __XSI_VISIBLE >= 600
diff --git a/lib/libc/compat-43/Makefile.inc b/lib/libc/compat-43/Makefile.inc
index 836f0a6..8505ff2 100644
--- a/lib/libc/compat-43/Makefile.inc
+++ b/lib/libc/compat-43/Makefile.inc
@@ -13,6 +13,11 @@ MAN+= creat.2 killpg.2 sigpause.2 sigsetmask.2 sigvec.2
MAN+= gethostid.3 setruid.3
MLINKS+=gethostid.3 sethostid.3
+MLINKS+=sigpause.2 sighold.2
+MLINKS+=sigpause.2 sigignore.2
+MLINKS+=sigpause.2 sigrelse.2
+MLINKS+=sigpause.2 sigset.2
+MLINKS+=sigpause.2 xsi_sigpause.2
MLINKS+=setruid.3 setrgid.3
MLINKS+=sigsetmask.2 sigblock.2
diff --git a/lib/libc/compat-43/Symbol.map b/lib/libc/compat-43/Symbol.map
index e859a31..bd49f99 100644
--- a/lib/libc/compat-43/Symbol.map
+++ b/lib/libc/compat-43/Symbol.map
@@ -17,6 +17,14 @@ FBSD_1.0 {
sigvec;
};
+FBSD_1.2 {
+ sighold;
+ sigignore;
+ sigrelse;
+ sigset;
+ xsi_sigpause;
+};
+
FBSDprivate_1.0 {
__creat;
_creat;
diff --git a/lib/libc/compat-43/sigcompat.c b/lib/libc/compat-43/sigcompat.c
index 6280183..c3ba30a 100644
--- a/lib/libc/compat-43/sigcompat.c
+++ b/lib/libc/compat-43/sigcompat.c
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include "namespace.h"
#include <sys/param.h>
#include <signal.h>
+#include <string.h>
#include "un-namespace.h"
#include "libc_private.h"
@@ -97,8 +98,7 @@ sigblock(mask)
}
int
-sigpause(mask)
- int mask;
+sigpause(int mask)
{
sigset_t set;
@@ -106,3 +106,84 @@ sigpause(mask)
set.__bits[0] = mask;
return (_sigsuspend(&set));
}
+
+int
+xsi_sigpause(int sig)
+{
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, sig);
+ return (_sigsuspend(&set));
+}
+
+int
+sighold(int sig)
+{
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, sig);
+ return (_sigprocmask(SIG_BLOCK, &set, NULL));
+}
+
+int
+sigignore(int sig)
+{
+ struct sigaction sa;
+
+ bzero(&sa, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ return (_sigaction(sig, &sa, NULL));
+}
+
+int
+sigrelse(int sig)
+{
+ sigset_t set;
+
+ sigemptyset(&set);
+ sigaddset(&set, sig);
+ return (_sigprocmask(SIG_UNBLOCK, &set, NULL));
+}
+
+void
+(*sigset(int sig, void (*disp)(int)))(int)
+{
+ sigset_t set, pset;
+ struct sigaction sa, psa;
+ int error;
+
+ sigemptyset(&set);
+ sigaddset(&set, sig);
+ error = _sigprocmask(SIG_BLOCK, NULL, &pset);
+ if (error == -1)
+ return (SIG_ERR);
+ if ((__sighandler_t *)disp == SIG_HOLD) {
+ error = _sigprocmask(SIG_BLOCK, &set, &pset);
+ if (error == -1)
+ return (SIG_ERR);
+ if (sigismember(&pset, sig))
+ return (SIG_HOLD);
+ else {
+ error = _sigaction(sig, NULL, &psa);
+ if (error == -1)
+ return (SIG_ERR);
+ return (psa.sa_handler);
+ }
+ } else {
+ error = _sigprocmask(SIG_UNBLOCK, &set, &pset);
+ if (error == -1)
+ return (SIG_ERR);
+ }
+
+ bzero(&sa, sizeof(sa));
+ sa.sa_handler = disp;
+ error = _sigaction(sig, &sa, &psa);
+ if (error == -1)
+ return (SIG_ERR);
+ if (sigismember(&pset, sig))
+ return (SIG_HOLD);
+ else
+ return (psa.sa_handler);
+}
diff --git a/lib/libc/compat-43/sigpause.2 b/lib/libc/compat-43/sigpause.2
index 39edb0b..bf3cf0b 100644
--- a/lib/libc/compat-43/sigpause.2
+++ b/lib/libc/compat-43/sigpause.2
@@ -28,21 +28,118 @@
.\" @(#)sigpause.2 8.1 (Berkeley) 6/2/93
.\" $FreeBSD$
.\"
+.\" Part of the content of the man page was derived from
+.\" The Open Group Base Specifications Issue 7
+.\" IEEE Std 1003.1-2008
+.\"
.Dd June 2, 1993
.Dt SIGPAUSE 2
.Os
.Sh NAME
-.Nm sigpause
-.Nd atomically release blocked signals and wait for interrupt
+.Nm sighold ,
+.Nm sigignore ,
+.Nm sigpause ,
+.Nm sigrelse ,
+.Nm sigset
+.Nd legacy interface for signal management
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In signal.h
.Ft int
+.Fn sighold "int sig"
+.Ft int
+.Fn sigignore "int sig"
+.Ft int
+.Fn xsi_sigpause "int sigmask"
+.Ft int
+.Fn sigrelse "int sig"
+.Ft void (*)(int)
+.Fn sigset "int" "void (*disp)(int)"
+.Ft int
.Fn sigpause "int sigmask"
.Sh DESCRIPTION
.Sy This interface is made obsolete by
-.Xr sigsuspend 2 .
+.Xr sigsuspend 2
+.Sy and
+.Xr sigaction 2
+.Pp
+The
+.Fn sigset
+function modifies signal dispositions.
+The
+.Fa sig
+argument specifies the signal, which may be any signal except
+.Dv SIGKILL
+and
+.Dv SIGSTOP .
+The
+.Fa disp
+argument specifies the signal's disposition,
+which may be
+.Dv SIG_DFL ,
+.Dv SIG_IGN ,
+or the address of a signal handler.
+If
+.Fn sigset
+is used, and
+.Fa disp
+is the address of a signal handler, the
+system adds
+.Fa sig
+to the signal mask of the calling process before executing the signal
+handler; when the signal handler returns, the system restores the
+signal mask of the calling process to its state prior to the delivery
+of the signal.
+In addition, if
+.Fn sigset
+is used, and
+.Fa disp
+is equal to
+.Dv SIG_HOLD ,
+.Fa sig
+is added to the signal
+mask of the calling process and
+.Fa sig 's
+disposition remains unchanged.
+If
+.Fn sigset
+is used, and
+.Fa disp
+is not equal to
+.Dv SIG_HOLD ,
+.Fa sig
+is removed from the signal mask of the calling process.
+.Pp
+The
+.Fn sighold
+function adds
+.Fa sig
+to the signal mask of the calling process.
+.Pp
+The
+.Fn sigrelse
+function removes
+.Fa sig
+from the signal mask of the calling process.
+.Pp
+The
+.Fn sigignore
+function sets the disposition of
+.Fa sig
+to
+.Dv SIG_IGN .
+.Pp
+The
+.Fn xsi_sigpause
+function removes
+.Fa sig
+from the signal mask of the calling process and suspend the calling process
+until a signal is received.
+The
+.Fn xsi_sigpause
+function restores the signal mask of the process to its original state before
+returning.
.Pp
The
.Fn sigpause
@@ -57,13 +154,47 @@ The
argument
is usually 0 to indicate that no
signals are to be blocked.
+.Sh RETURN VALUES
The
.Fn sigpause
-function
-always terminates by being interrupted, returning -1 with
+and
+.Fn xsi_sigpause
+functions
+always terminate by being interrupted, returning -1 with
.Va errno
set to
-.Er EINTR
+.Er EINTR .
+.Pp
+Upon successful completion,
+.Fn sigset
+returns
+.Dv SIG_HOLD
+if the signal had been blocked and the signal's previous disposition if
+it had not been blocked.
+Otherwise,
+.Dv SIG_ERR is returned and
+.Va errno
+set to indicate the error.
+.Pp
+For all other functions, upon successful completion, 0 is returned.
+Otherwise, -1 is returned and
+.Va errno
+is set to indicate the error:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa sig
+argument
+is not a valid signal number.
+.It Bq Er EINVAL
+For
+.Fn sigset
+and
+.Fn sigignore
+functions, an attempt was made to catch or ignore
+.Dv SIGKILL
+or
+.Dv SIGSTOP .
.Sh SEE ALSO
.Xr kill 2 ,
.Xr sigaction 2 ,
@@ -85,9 +216,26 @@ and was copied from there into the
.Pq Tn XSI
option of
.St -p1003.1-2001 .
+.Fx
+implements it under the name
+.Fn xsi_sigpause .
+The
+.Fn sighold ,
+.Fn sigignore ,
+.Fn sigrelse
+and
+.Fn sigset
+functions are implemented for compatibility with
+.Sy System V
+and
+.Sy XSI
+interfaces.
.Sh HISTORY
The
.Fn sigpause
function appeared in
.Bx 4.2
and has been deprecated.
+All other functions appeared in
+.Fx 9.0
+and were deprecated before being implemented.
diff --git a/sys/sys/signal.h b/sys/sys/signal.h
index 81d45a9..ff2d1fc 100644
--- a/sys/sys/signal.h
+++ b/sys/sys/signal.h
@@ -119,9 +119,8 @@
#define SIG_DFL ((__sighandler_t *)0)
#define SIG_IGN ((__sighandler_t *)1)
#define SIG_ERR ((__sighandler_t *)-1)
-/*
- * XXX missing SIG_HOLD.
- */
+/* #define SIG_CATCH ((__sighandler_t *)2) See signalvar.h */
+#define SIG_HOLD ((__sighandler_t *)3)
/*-
* Type of a signal handling function.
diff --git a/sys/sys/signalvar.h b/sys/sys/signalvar.h
index fd0fac3..c9455c2 100644
--- a/sys/sys/signalvar.h
+++ b/sys/sys/signalvar.h
@@ -97,7 +97,7 @@ typedef void __osiginfohandler_t(int, osiginfo_t *, void *);
/* additional signal action values, used only temporarily/internally */
#define SIG_CATCH ((__sighandler_t *)2)
-#define SIG_HOLD ((__sighandler_t *)3)
+/* #define SIG_HOLD ((__sighandler_t *)3) See signal.h */
/*
* get signal action for process and signal; currently only for current process
OpenPOWER on IntegriCloud