summaryrefslogtreecommitdiff
path: root/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'signal.c')
-rw-r--r--signal.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/signal.c b/signal.c
new file mode 100644
index 0000000..e0a41ca
--- /dev/null
+++ b/signal.c
@@ -0,0 +1,65 @@
+/*
+ * signal.c
+ *
+ * Description:
+ * POSIX thread-aware signal functions.
+ */
+
+#include "pthread.h"
+
+int
+pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
+{
+ /* Validate the `how' argument.*/
+ if (set != NULL)
+ {
+ switch (how)
+ {
+ case SIG_BLOCK:
+ break;
+ case SIG_UNBLOCK:
+ break;
+ case SIG_SETMASK:
+ break;
+ default:
+ /* Invalid `how' argument. */
+ return EINVAL;
+ }
+ }
+
+ /* Copy the old mask before modifying it. */
+ if (oset != NULL)
+ {
+ memcpy(oset, this->attr->sigmask, sizeof(sigset_t));
+ }
+
+ if (set != NULL)
+ {
+ int i;
+ unsigned long *src = set;
+ unsigned long *dest = this->attr->sigmask;
+
+ switch (how)
+ {
+ case SIG_BLOCK:
+ for (i = 0; i < (sizeof(sigset_t) / sizeof(unsigned long)); i++)
+ {
+ /* OR the bit field longword-wise. */
+ *src++ |= *dest++;
+ }
+ break;
+ case SIG_UNBLOCK:
+ for (i = 0; i < (sizeof(sigset_t) / sizeof(unsigned long)); i++)
+ {
+ /* XOR the bitfield longword-wise. */
+ *src++ ^= *dest++;
+ }
+ case SIG_SET:
+ /* Replace the whole sigmask. */
+ memcpy(this->attr.sigmask, set, sizeof(sigset_t));
+ break;
+ }
+ }
+
+ return 0;
+}