xref: /haiku/src/add-ons/kernel/drivers/common/dprintf.cpp (revision b028e77473189065f2baefc6f5e10d451cf591e2)
1 /*
2  * Copyright 2005-2007, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Author(s):
6  *   Ingo Weinhold <bonefish@users.sourceforge.net>
7  *
8  * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
9  * Distributed under the terms of the NewOS License.
10  */
11 
12 
13 #include <debug.h>
14 
15 #include <Drivers.h>
16 #include <KernelExport.h>
17 
18 #include <string.h>
19 #include <termios.h>
20 
21 
22 #define DEVICE_NAME "dprintf"
23 
24 int32 api_version = B_CUR_DRIVER_API_VERSION;
25 
26 
27 static status_t
28 dprintf_open(const char *name, uint32 flags, void **cookie)
29 {
30 	*cookie = NULL;
31 	return B_OK;
32 }
33 
34 
35 static status_t
36 dprintf_close(void *cookie)
37 {
38 	return B_OK;
39 }
40 
41 
42 static status_t
43 dprintf_freecookie(void *cookie)
44 {
45 	return B_OK;
46 }
47 
48 
49 static status_t
50 dprintf_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
51 {
52 	if (op == TCGETA) {
53 		// let isatty() think we are a terminal
54 		// (this lets libroot use unbuffered I/O)
55 		return B_OK;
56 	}
57 
58 	return EPERM;
59 }
60 
61 
62 static status_t
63 dprintf_read(void *cookie, off_t pos, void *buffer, size_t *length)
64 {
65 	*length = 0;
66 	return B_OK;
67 }
68 
69 
70 static status_t
71 dprintf_write(void *cookie, off_t pos, const void *buffer, size_t *_length)
72 {
73 	const char *str = (const char*)buffer;
74 
75 	int bytesLeft = *_length;
76 	while (bytesLeft > 0) {
77 		int chunkSize = strnlen(str, bytesLeft);
78 		if (chunkSize == 0) {
79 			// null bytes -- skip
80 			str++;
81 			bytesLeft--;
82 			continue;
83 		}
84 
85 		if (chunkSize == bytesLeft) {
86 			// no null-byte in the remainder of the buffer
87 			// we need to copy to a local buffer and null-terminate
88 			while (bytesLeft > 0) {
89 				chunkSize = bytesLeft;
90 
91 				char localBuffer[512];
92 				if (bytesLeft > (int)sizeof(localBuffer) - 1)
93 					chunkSize = (int)sizeof(localBuffer) - 1;
94 				memcpy(localBuffer, str, chunkSize);
95 				localBuffer[chunkSize] = '\0';
96 
97 				debug_puts(localBuffer, chunkSize);
98 
99 				str += chunkSize;
100 				bytesLeft -= chunkSize;
101 			}
102 		} else {
103 			// null-terminated chunk -- just write it
104 			debug_puts(str, chunkSize);
105 
106 			str += chunkSize + 1;
107 			bytesLeft -= chunkSize + 1;
108 		}
109 	}
110 
111 	return B_OK;
112 }
113 
114 
115 //	#pragma mark -
116 
117 
118 status_t
119 init_hardware(void)
120 {
121 	return B_OK;
122 }
123 
124 
125 const char **
126 publish_devices(void)
127 {
128 	static const char *devices[] = {
129 		DEVICE_NAME,
130 		NULL
131 	};
132 
133 	return devices;
134 }
135 
136 
137 device_hooks *
138 find_device(const char *name)
139 {
140 	static device_hooks hooks = {
141 		&dprintf_open,
142 		&dprintf_close,
143 		&dprintf_freecookie,
144 		&dprintf_ioctl,
145 		&dprintf_read,
146 		&dprintf_write,
147 		/* Leave select/deselect/readv/writev undefined. The kernel will
148 		 * use its own default implementation. The basic hooks above this
149 		 * line MUST be defined, however. */
150 		NULL,
151 		NULL,
152 		NULL,
153 		NULL
154 	};
155 
156 	if (!strcmp(name, DEVICE_NAME))
157 		return &hooks;
158 
159 	return NULL;
160 }
161 
162 
163 status_t
164 init_driver(void)
165 {
166 	return B_OK;
167 }
168 
169 
170 void
171 uninit_driver(void)
172 {
173 }
174 
175