void *sym = dlsym (RTLD_NEXT, name);
if (sym == NULL)
{
- fprintf (stderr, "Cannot resolve symbol %s!\n", name);
+ fprintf (stderr, "Cannot resolve symbol %s: %s\n", name,
+ dlerror ());
abort ();
}
return sym;
/** Signals **/
#include <signal.h>
+static bool blocked_signal (int num)
+{
+ switch (num)
+ {
+ case SIGINT:
+ case SIGHUP:
+ case SIGQUIT:
+ case SIGTERM:
+ case SIGPIPE:
+ case SIGCHLD:
+ return true;
+ }
+ return false;
+}
+
void (*signal (int signum, void (*handler) (int))) (int)
{
if (override)
{
- const char *msg = "Error";
-
- if ((signum == SIGPIPE && handler == SIG_IGN)
- || (signum != SIGPIPE && handler == SIG_DFL))
- /* Same settings we already use */
- msg = "Warning";
- LOG(msg, "%d, %p", signum, handler);
+ if (handler != SIG_IGN && handler != SIG_DFL)
+ goto error;
+ if (!blocked_signal (signum))
+ goto error;
+ /* For our blocked signals, the handler won't matter much... */
+ LOG("Warning", "%d, %p", signum, handler);
}
return CALL(signal, signum, handler);
+error:
+ LOG("Blocked", "%d, %p", signum, handler);
+ return SIG_DFL;
}
int sigaction (int signum, const struct sigaction *act, struct sigaction *old)
{
- if (act != NULL)
- LOG("Error", "%d, %p, %p", signum, act, old);
+ if (override && act != NULL)
+ {
+ if ((act->sa_flags & SA_SIGINFO)
+ || (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL))
+ goto error;
+ LOG("Warning", "%d, %p, %p", signum, act, old);
+ }
return CALL(sigaction, signum, act, old);
+error:
+ LOG("Blocked", "%d, %p, %p", signum, act, old);
+ return -1;
+}
+
+
+/*** Locales ***
+ * setlocale() is not thread-safe and has a tendency to crash other threads as
+ * quite many libc and libintl calls depend on the locale.
+ * Use uselocale() instead for thread-safety.
+ */
+#include <locale.h>
+
+char *setlocale (int cat, const char *locale)
+{
+ if (override && locale != NULL)
+ {
+ LOG("Blocked", "%d, \"%s\"", cat, locale);
+ return NULL;
+ }
+ return CALL(setlocale, cat, locale);
}