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