It's much better to get EPIPE than SIGPIPE.
Block SIGPIPE in all threads we create. In the daemon, block SIGPIPE in
the main thread.
Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
}
int r;
+
+ // The child thread will inherit our signal mask. Set our signal mask to
+ // the set of signals we want to block. (It's ok to block signals more
+ // signals than usual for a little while-- they will just be delivered to
+ // another thread or delieverd to this thread later.)
+ sigset_t old_sigset;
if (g_code_env == CODE_ENVIRONMENT_LIBRARY) {
- // The child thread will inherit our signal mask. We want it to block all
- // signals, so set our mask to that. (It's ok to block signals for a
- // little while-- they will just be delivered to another thread or
- // delieverd to this thread later.)
- sigset_t old_sigset;
- block_all_signals(&old_sigset);
- r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
- restore_sigset(&old_sigset);
+ block_signals(&old_sigset, NULL);
}
else {
- r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
+ int to_block[] = { SIGPIPE , 0 };
+ block_signals(&old_sigset, to_block);
}
+ r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
+ restore_sigset(&old_sigset);
if (thread_attr)
free(thread_attr);
g_conf.log_to_stderr = LOG_TO_STDERR_SOME;
set_cv(&g_conf.log_dir, "/var/log/ceph");
set_cv(&g_conf.pid_file, "/var/run/ceph/$type.$id.pid");
+
+ // block SIGPIPE
+ int siglist[] = { SIGPIPE, 0 };
+ block_signals(NULL, siglist);
}
else {
g_conf.pid_file = 0;
install_sighandler(SIGSYS, handle_fatal_signal, SA_RESETHAND | SA_NODEFER);
}
-void block_all_signals(sigset_t *old_sigset)
+void block_signals(sigset_t *old_sigset, int *siglist)
{
sigset_t sigset;
- sigfillset(&sigset);
+ if (!siglist) {
+ sigfillset(&sigset);
+ }
+ else {
+ int i = 0;
+ sigemptyset(&sigset);
+ while (siglist[i]) {
+ sigaddset(&sigset, siglist[i]);
+ ++i;
+ }
+ }
sigdelset(&sigset, SIGKILL);
if (pthread_sigmask(SIG_BLOCK, &sigset, old_sigset)) {
derr << "block_all_signals: sigprocmask failed" << dendl;
// Other threads may have a different set (this is per-thread thing).
std::string signal_mask_to_str();
-// Block all signals. On success, stores the old set of blocked signals in
+// Block a list of signals. If siglist == NULL, blocks all signals.
+// If not, the list is terminated with a 0 element.
+//
+// On success, stores the old set of blocked signals in
// old_sigset. On failure, stores an invalid set of blocked signals in
// old_sigset.
-void block_all_signals(sigset_t *old_sigset);
+void block_signals(sigset_t *old_sigset, int *siglist);
// Restore the set of blocked signals. Will not restore an invalid set of
// blocked signals.