#define VG_USERREQ__GET_KEY_D_AND_S 0x3022
#define VG_USERREQ__NUKE_OTHER_THREADS 0x3023
+
+/* Ask how many signal handler returns have happened to this
+ thread. */
#define VG_USERREQ__GET_N_SIGS_RETURNED 0x3024
+
+
/* Cosmetic ... */
#define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
/* Log a pthread error from client-space. Cosmetic. */
extern void VG_(send_signal_to_thread) ( ThreadId thread,
Int signo );
+extern void VG_(do_sigpending) ( ThreadId tid, vki_ksigset_t* set );
+
+
/* Modify the current thread's state once we have detected it is
returning from a signal handler. */
extern Bool VG_(signal_returns) ( ThreadId );
extern Int VG_(ksigaltstack)( const vki_kstack_t* ss, vki_kstack_t* oss );
extern Int VG_(kill)( Int pid, Int signo );
+extern Int VG_(sigpending) ( vki_ksigset_t* set );
/* ---------------------------------------------------------------------
}
+Int VG_(sigpending) ( vki_ksigset_t* set )
+{
+ Int res = vg_do_syscall1(__NR_sigpending, (UInt)set);
+ return VG_(is_kerror)(res) ? -1 : 0;
+}
+
+
/* ---------------------------------------------------------------------
mmap/munmap, exit, fcntl
------------------------------------------------------------------ */
}
+/* Store in set the signals which could be delivered to this thread
+ right now (since they are pending) but cannot be, because the
+ thread has masked them out. */
+void VG_(do_sigpending) ( ThreadId tid, vki_ksigset_t* set )
+{
+ Int sig, res;
+ Bool maybe_pend;
+ vki_ksigset_t process_pending;
+
+ /* Get the set of signals which are pending for the process as a
+ whole. */
+ res = VG_(sigpending)( &process_pending );
+ vg_assert(res == 0);
+
+ VG_(ksigemptyset)(set);
+ for (sig = 1; sig <= VKI_KNSIG; sig++) {
+
+ /* Figure out if the signal could be pending for this thread.
+ There are two cases. */
+ maybe_pend = False;
+
+ /* Case 1: perhaps the signal is pending for the process as a
+ whole -- that is, is blocked even valgrind's signal
+ handler. */
+ if (VG_(ksigismember)( &process_pending, sig ))
+ maybe_pend = True;
+
+ /* Case 2: the signal has been collected by our handler and is
+ now awaiting disposition inside valgrind. */
+ if (/* is it pending at all? */
+ vg_dcss.dcss_sigpending[sig]
+ &&
+ /* check it is not specifically directed to some other thread */
+ (vg_dcss.dcss_destthread[sig] == VG_INVALID_THREADID
+ || vg_dcss.dcss_destthread[sig] == tid)
+ )
+ maybe_pend = True;
+
+ if (!maybe_pend)
+ continue; /* this signal just ain't pending! */
+
+ /* Check other necessary conditions now ... */
+
+ if (VG_(ksigismember)( &VG_(threads)[tid].sigs_waited_for, sig ))
+ continue; /* tid is sigwaiting for sig, so will never be
+ offered to a handler */
+ if (! VG_(ksigismember)( &VG_(threads)[tid].sig_mask, sig ))
+ continue; /* not blocked in this thread */
+
+ /* Ok, sig could be delivered to this thread if only it wasn't
+ masked out. So we add it to set. */
+ VG_(ksigaddset)( set, sig );
+ }
+}
+
+
/* ---------------------------------------------------------------------
LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
------------------------------------------------------------------ */
#define VG_USERREQ__GET_KEY_D_AND_S 0x3022
#define VG_USERREQ__NUKE_OTHER_THREADS 0x3023
+
+/* Ask how many signal handler returns have happened to this
+ thread. */
#define VG_USERREQ__GET_N_SIGS_RETURNED 0x3024
+
+
/* Cosmetic ... */
#define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
/* Log a pthread error from client-space. Cosmetic. */
extern void VG_(send_signal_to_thread) ( ThreadId thread,
Int signo );
+extern void VG_(do_sigpending) ( ThreadId tid, vki_ksigset_t* set );
+
+
/* Modify the current thread's state once we have detected it is
returning from a signal handler. */
extern Bool VG_(signal_returns) ( ThreadId );
extern Int VG_(ksigaltstack)( const vki_kstack_t* ss, vki_kstack_t* oss );
extern Int VG_(kill)( Int pid, Int signo );
+extern Int VG_(sigpending) ( vki_ksigset_t* set );
/* ---------------------------------------------------------------------
}
+Int VG_(sigpending) ( vki_ksigset_t* set )
+{
+ Int res = vg_do_syscall1(__NR_sigpending, (UInt)set);
+ return VG_(is_kerror)(res) ? -1 : 0;
+}
+
+
/* ---------------------------------------------------------------------
mmap/munmap, exit, fcntl
------------------------------------------------------------------ */
}
+/* Store in set the signals which could be delivered to this thread
+ right now (since they are pending) but cannot be, because the
+ thread has masked them out. */
+void VG_(do_sigpending) ( ThreadId tid, vki_ksigset_t* set )
+{
+ Int sig, res;
+ Bool maybe_pend;
+ vki_ksigset_t process_pending;
+
+ /* Get the set of signals which are pending for the process as a
+ whole. */
+ res = VG_(sigpending)( &process_pending );
+ vg_assert(res == 0);
+
+ VG_(ksigemptyset)(set);
+ for (sig = 1; sig <= VKI_KNSIG; sig++) {
+
+ /* Figure out if the signal could be pending for this thread.
+ There are two cases. */
+ maybe_pend = False;
+
+ /* Case 1: perhaps the signal is pending for the process as a
+ whole -- that is, is blocked even valgrind's signal
+ handler. */
+ if (VG_(ksigismember)( &process_pending, sig ))
+ maybe_pend = True;
+
+ /* Case 2: the signal has been collected by our handler and is
+ now awaiting disposition inside valgrind. */
+ if (/* is it pending at all? */
+ vg_dcss.dcss_sigpending[sig]
+ &&
+ /* check it is not specifically directed to some other thread */
+ (vg_dcss.dcss_destthread[sig] == VG_INVALID_THREADID
+ || vg_dcss.dcss_destthread[sig] == tid)
+ )
+ maybe_pend = True;
+
+ if (!maybe_pend)
+ continue; /* this signal just ain't pending! */
+
+ /* Check other necessary conditions now ... */
+
+ if (VG_(ksigismember)( &VG_(threads)[tid].sigs_waited_for, sig ))
+ continue; /* tid is sigwaiting for sig, so will never be
+ offered to a handler */
+ if (! VG_(ksigismember)( &VG_(threads)[tid].sig_mask, sig ))
+ continue; /* not blocked in this thread */
+
+ /* Ok, sig could be delivered to this thread if only it wasn't
+ masked out. So we add it to set. */
+ VG_(ksigaddset)( set, sig );
+ }
+}
+
+
/* ---------------------------------------------------------------------
LOW LEVEL STUFF TO DO WITH SIGNALS: IMPLEMENTATION
------------------------------------------------------------------ */
make_readable( arg3, sizeof(vki_ksigset_t));
break;
+ case __NR_sigpending: /* syscall 73 */
+# if defined(__NR_rt_sigpending)
+ case __NR_rt_sigpending: /* syscall 176 */
+# endif
+ /* int sigpending( sigset_t *set ) ; */
+ if (VG_(clo_trace_syscalls))
+ VG_(printf)( "sigpending ( %p )\n", arg1 );
+ must_be_writable( tst, "sigpending(set)",
+ arg1, sizeof(vki_ksigset_t));
+# if SIGNAL_SIMULATION
+ VG_(do_sigpending)( tid, (vki_ksigset_t*)arg1 );
+ res = 0;
+ SET_EAX(tid, res);
+# else
+ KERNEL_DO_SYSCALL(tid, res);
+# endif
+ if ( !VG_( is_kerror )( res ) && res == 0 )
+ make_readable( arg1, sizeof( vki_ksigset_t ) ) ;
+ break ;
+
default:
VG_(message)
(Vg_DebugMsg,"FATAL: unhandled syscall: %d",syscallno);