summaryrefslogtreecommitdiffstats
path: root/signal.h
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-09-22 06:48:22 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-09-22 06:48:22 -0700
commit7804b5af1f14c0f35977543a637cf5ff7c285fec (patch)
tree6e95c9fc8105ef875ee063dca6dc7f3ba3279df8 /signal.h
parent1f57463ee7f381bd527f2b8ea1638ae8a3916834 (diff)
downloadtxr-7804b5af1f14c0f35977543a637cf5ff7c285fec.tar.gz
txr-7804b5af1f14c0f35977543a637cf5ff7c285fec.tar.bz2
txr-7804b5af1f14c0f35977543a637cf5ff7c285fec.zip
C++ upkeep: cannot assign to volatile sigset_t.
This is a hack for an ugly problem. A plain old struct is actually a class in C++, and assignment to a struct goes thorugh a generated assignment operator. Unfortunately, C++ doesn't generate an assignment operator for volatile destinations, so assignment to a volatile-qualified struct object is erroneous. * signal.h (copy_sigset): New inline function to copy a sigset_t, even if the left hand side is volatile. This works by stripping the qualifier. (sig_save_enable): Use the function.
Diffstat (limited to 'signal.h')
-rw-r--r--signal.h12
1 files changed, 11 insertions, 1 deletions
diff --git a/signal.h b/signal.h
index 09caddbb..9dc076cd 100644
--- a/signal.h
+++ b/signal.h
@@ -42,6 +42,15 @@ extern int debug_depth;
#if HAVE_POSIX_SIGS
+INLINE void copy_sigset(volatile sigset_t *dest, const sigset_t *src)
+{
+#ifdef __cplusplus
+ *strip_qual(sigset_t *, dest) = *src;
+#else
+ *dest = *src;
+#endif
+}
+
#define sig_save_enable \
do { \
int sig_save = async_sig_enabled; \
@@ -104,7 +113,8 @@ typedef struct {
(EJB).de = dyn_env, \
(EJB).gc = gc_enabled, \
(EJB).gc_pt = gc_prot_top, \
- (EJB).blocked = sig_blocked_cache, \
+ copy_sigset(&(EJB).blocked, \
+ &sig_blocked_cache), \
EJ_OPT_SAVE(EJB) \
0))