diff options
Diffstat (limited to 'signal.c')
-rw-r--r-- | signal.c | 65 |
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; +} |