1 /* $OpenBSD: rthread_debug.c,v 1.2 2017/08/15 06:38:41 guenther Exp $ */ 2 3 /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ 4 5 #include <pthread.h> 6 #include <stdarg.h> 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <unistd.h> 10 11 #include "rthread.h" 12 13 REDIRECT_SYSCALL(issetugid); 14 15 int _rthread_debug_level; 16 17 /* 18 * Note: messages truncated at 255 characters. Could use vasprintf, 19 * but don't want to use malloc here so the function can be used 20 * in signal handlers. 21 */ 22 #define MAX_MSG_LEN 256 23 #define RTHREAD_ENV_DEBUG "RTHREAD_DEBUG" 24 25 /* 26 * format and send output to stderr if the given "level" is less than or 27 * equal to the current debug level. Messages with a level <= 0 will 28 * always be printed. 29 */ 30 void 31 _rthread_debug(int level, const char *fmt, ...) 32 { 33 char msg[MAX_MSG_LEN]; 34 char *p; 35 int cnt; 36 ssize_t c; 37 38 if (_rthread_debug_level >= level) { 39 va_list ap; 40 va_start(ap, fmt); 41 cnt = vsnprintf(msg, MAX_MSG_LEN, fmt, ap); 42 va_end(ap); 43 if (cnt > MAX_MSG_LEN - 1) 44 cnt = MAX_MSG_LEN - 1; 45 p = msg; 46 do { 47 c = write(STDERR_FILENO, p, cnt); 48 if (c == -1) 49 break; 50 if (c != cnt) 51 sched_yield(); 52 p += c; 53 cnt -= c; 54 } while (cnt > 0); 55 } 56 } 57 58 /* 59 * set the debug level from an environment string. Bogus values are 60 * silently ignored. 61 */ 62 void 63 _rthread_debug_init(void) 64 { 65 char *envp; 66 char *rem; 67 68 if (issetugid()) 69 return; 70 envp = getenv(RTHREAD_ENV_DEBUG); 71 if (envp) { 72 _rthread_debug_level = (int) strtol(envp, &rem, 0); 73 if (*rem || _rthread_debug_level < 0) 74 _rthread_debug_level = 0; 75 } 76 } 77