vfs: check userland buffers before reading them.
[haiku.git] / src / servers / package / DebugSupport.cpp
blob8377cf340c90fcdee2828cd148bc51f268952fc0
1 /*
2 * Copyright 2003-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
7 #include "DebugSupport.h"
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <stdarg.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <unistd.h>
16 #include <OS.h>
19 /*!
20 \file Debug.cpp
21 \brief Defines debug output function with printf() signature printing
22 into a file.
24 \note The initialization is not thread safe!
28 // locking support
29 static int32 init_counter = 0;
30 static sem_id dbg_printf_sem = -1;
31 static thread_id dbg_printf_thread = -1;
32 static int dbg_printf_nesting = 0;
35 #if DEBUG_PRINT
36 static int out = -1;
37 #endif
40 status_t
41 init_debugging()
43 status_t error = B_OK;
44 if (init_counter++ == 0) {
45 // open the file
46 #if DEBUG_PRINT
47 out = open(DEBUG_PRINT_FILE, O_RDWR | O_CREAT | O_TRUNC);
48 if (out < 0) {
49 error = errno;
50 init_counter--;
52 #endif // DEBUG_PRINT
53 // allocate the semaphore
54 if (error == B_OK) {
55 dbg_printf_sem = create_sem(1, "dbg_printf");
56 if (dbg_printf_sem < 0)
57 error = dbg_printf_sem;
59 if (error == B_OK) {
60 #if DEBUG
61 __out("##################################################\n");
62 #endif
63 } else
64 exit_debugging();
66 return error;
70 status_t
71 exit_debugging()
73 status_t error = B_OK;
74 if (--init_counter == 0) {
75 #if DEBUG_PRINT
76 close(out);
77 out = -1;
78 #endif // DEBUG_PRINT
79 delete_sem(dbg_printf_sem);
80 } else
81 error = B_NO_INIT;
82 return error;
86 static inline bool
87 dbg_printf_lock()
89 thread_id thread = find_thread(NULL);
90 if (thread != dbg_printf_thread) {
91 if (acquire_sem(dbg_printf_sem) != B_OK)
92 return false;
93 dbg_printf_thread = thread;
95 dbg_printf_nesting++;
96 return true;
100 static inline void
101 dbg_printf_unlock()
103 thread_id thread = find_thread(NULL);
104 if (thread != dbg_printf_thread)
105 return;
106 dbg_printf_nesting--;
107 if (dbg_printf_nesting == 0) {
108 dbg_printf_thread = -1;
109 release_sem(dbg_printf_sem);
114 void
115 dbg_printf_begin()
117 dbg_printf_lock();
121 void
122 dbg_printf_end()
124 dbg_printf_unlock();
128 #if DEBUG_PRINT
130 void
131 dbg_printf(const char *format,...)
133 if (!dbg_printf_lock())
134 return;
135 char buffer[1024];
136 va_list args;
137 va_start(args, format);
138 // no vsnprintf() on PPC and in kernel
139 #if defined(__INTEL__) && USER
140 vsnprintf(buffer, sizeof(buffer) - 1, format, args);
141 #else
142 vsprintf(buffer, format, args);
143 #endif
144 va_end(args);
145 buffer[sizeof(buffer) - 1] = '\0';
146 write(out, buffer, strlen(buffer));
147 dbg_printf_unlock();
150 #endif // DEBUG_PRINT