summaryrefslogtreecommitdiffstats
path: root/lib/libc/thread/rthread_debug.c
diff options
context:
space:
mode:
authorguenther <guenther@openbsd.org>2017-08-15 06:13:24 +0000
committerguenther <guenther@openbsd.org>2017-08-15 06:13:24 +0000
commit7e321ac128fdcd388c62dfa54aca790ebbd73ce1 (patch)
treedcaaa56a773388005748dd5a23dadbd6c1338a21 /lib/libc/thread/rthread_debug.c
parentAfter we stopped processing router advertisements in the kernel (diff)
downloadwireguard-openbsd-7e321ac128fdcd388c62dfa54aca790ebbd73ce1.tar.xz
wireguard-openbsd-7e321ac128fdcd388c62dfa54aca790ebbd73ce1.zip
Copy files from ../librthread in preparation for moving functionality
from libpthread to libc. No changes to the build yet, just making it easier to review the substantive diffs. ok beck@ kettenis@ tedu@
Diffstat (limited to 'lib/libc/thread/rthread_debug.c')
-rw-r--r--lib/libc/thread/rthread_debug.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/libc/thread/rthread_debug.c b/lib/libc/thread/rthread_debug.c
new file mode 100644
index 00000000000..ce7d347f83e
--- /dev/null
+++ b/lib/libc/thread/rthread_debug.c
@@ -0,0 +1,76 @@
+/* $OpenBSD: rthread_debug.c,v 1.1 2017/08/15 06:13:24 guenther Exp $ */
+
+/* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */
+
+#include <pthread.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "rthread.h"
+
+REDIRECT_SYSCALL(issetugid);
+
+int _rthread_debug_level;
+
+/*
+ * Note: messages truncated at 255 characters. Could use vasprintf,
+ * but don't want to use malloc here so the function can be used
+ * in signal handlers.
+ */
+#define MAX_MSG_LEN 256
+#define RTHREAD_ENV_DEBUG "RTHREAD_DEBUG"
+
+/*
+ * format and send output to stderr if the given "level" is less than or
+ * equal to the current debug level. Messages with a level <= 0 will
+ * always be printed.
+ */
+void
+_rthread_debug(int level, const char *fmt, ...)
+{
+ char msg[MAX_MSG_LEN];
+ char *p;
+ int cnt;
+ ssize_t c;
+
+ if (_rthread_debug_level >= level) {
+ va_list ap;
+ va_start(ap, fmt);
+ cnt = vsnprintf(msg, MAX_MSG_LEN, fmt, ap);
+ va_end(ap);
+ if (cnt > MAX_MSG_LEN - 1)
+ cnt = MAX_MSG_LEN - 1;
+ p = msg;
+ do {
+ c = write(STDERR_FILENO, p, cnt);
+ if (c == -1)
+ break;
+ if (c != cnt)
+ sched_yield();
+ p += c;
+ cnt -= c;
+ } while (cnt > 0);
+ }
+}
+
+/*
+ * set the debug level from an environment string. Bogus values are
+ * silently ignored.
+ */
+void
+_rthread_debug_init(void)
+{
+ char *envp;
+ char *rem;
+
+ if (issetugid())
+ return;
+ envp = getenv(RTHREAD_ENV_DEBUG);
+ if (envp) {
+ _rthread_debug_level = (int) strtol(envp, &rem, 0);
+ if (*rem || _rthread_debug_level < 0)
+ _rthread_debug_level = 0;
+ }
+}