xref: /haiku/src/add-ons/kernel/drivers/common/dprintf.cpp (revision 8d794763d5942841cb63919e19f4be7798afaa05)
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
dprintf_open(const char * name,uint32 flags,void ** cookie)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
dprintf_close(void * cookie)36 dprintf_close(void *cookie)
37 {
38 	return B_OK;
39 }
40 
41 
42 static status_t
dprintf_freecookie(void * cookie)43 dprintf_freecookie(void *cookie)
44 {
45 	return B_OK;
46 }
47 
48 
49 static status_t
dprintf_ioctl(void * cookie,uint32 op,void * buffer,size_t length)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
dprintf_read(void * cookie,off_t pos,void * buffer,size_t * length)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
dprintf_write(void * cookie,off_t pos,const void * buffer,size_t * _length)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 		ssize_t size = user_strlcpy(NULL, str, 0);
78 			// there's no user_strnlen()
79 		if (size < 0)
80 			return 0;
81 		int chunkSize = min_c(bytesLeft, (int)size);
82 		// int chunkSize = strnlen(str, bytesLeft);
83 
84 		if (chunkSize == 0) {
85 			// null bytes -- skip
86 			str++;
87 			bytesLeft--;
88 			continue;
89 		}
90 
91 		if (chunkSize == bytesLeft) {
92 			// no null-byte in the remainder of the buffer
93 			// we need to copy to a local buffer and null-terminate
94 			while (bytesLeft > 0) {
95 				chunkSize = bytesLeft;
96 
97 				char localBuffer[512];
98 				if (bytesLeft > (int)sizeof(localBuffer) - 1)
99 					chunkSize = (int)sizeof(localBuffer) - 1;
100 				if (user_memcpy(localBuffer, str, chunkSize) < B_OK)
101 					return B_BAD_ADDRESS;
102 				localBuffer[chunkSize] = '\0';
103 
104 				debug_puts(localBuffer, chunkSize);
105 
106 				str += chunkSize;
107 				bytesLeft -= chunkSize;
108 			}
109 		} else {
110 			// null-terminated chunk -- just write it
111 			debug_puts(str, chunkSize);
112 
113 			str += chunkSize + 1;
114 			bytesLeft -= chunkSize + 1;
115 		}
116 	}
117 
118 	return B_OK;
119 }
120 
121 
122 //	#pragma mark -
123 
124 
125 status_t
init_hardware(void)126 init_hardware(void)
127 {
128 	return B_OK;
129 }
130 
131 
132 const char **
publish_devices(void)133 publish_devices(void)
134 {
135 	static const char *devices[] = {
136 		DEVICE_NAME,
137 		NULL
138 	};
139 
140 	return devices;
141 }
142 
143 
144 device_hooks *
find_device(const char * name)145 find_device(const char *name)
146 {
147 	static device_hooks hooks = {
148 		&dprintf_open,
149 		&dprintf_close,
150 		&dprintf_freecookie,
151 		&dprintf_ioctl,
152 		&dprintf_read,
153 		&dprintf_write,
154 		/* Leave select/deselect/readv/writev undefined. The kernel will
155 		 * use its own default implementation. The basic hooks above this
156 		 * line MUST be defined, however. */
157 		NULL,
158 		NULL,
159 		NULL,
160 		NULL
161 	};
162 
163 	if (!strcmp(name, DEVICE_NAME))
164 		return &hooks;
165 
166 	return NULL;
167 }
168 
169 
170 status_t
init_driver(void)171 init_driver(void)
172 {
173 	return B_OK;
174 }
175 
176 
177 void
uninit_driver(void)178 uninit_driver(void)
179 {
180 }
181 
182