1 /* 2 * Copyright 2003-2013, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <boot/vfs.h> 8 #include <boot/stdio.h> 9 #include <boot/net/NetStack.h> 10 #include <boot/net/UDP.h> 11 12 #include <errno.h> 13 #include <stdarg.h> 14 #include <string.h> 15 16 #include <algorithm> 17 18 19 //#undef stdout 20 //#undef stdin 21 //extern FILE *stdout; 22 //extern FILE *stdin; 23 24 25 //#define ENABLE_SYSLOG 26 27 28 #undef errno 29 int errno; 30 31 32 int* 33 _errnop(void) 34 { 35 return &errno; 36 } 37 38 39 #ifdef ENABLE_SYSLOG 40 41 static UDPSocket *sSyslogSocket = NULL; 42 43 static void 44 sendToSyslog(const char *message, int length) 45 { 46 // Lazy-initialize the socket 47 if (sSyslogSocket == NULL) { 48 // Check if the network stack has been initialized yet 49 if (NetStack::Default() != NULL) { 50 sSyslogSocket = new(std::nothrow) UDPSocket; 51 sSyslogSocket->Bind(INADDR_ANY, 60514); 52 } 53 } 54 55 if (sSyslogSocket == NULL) 56 return; 57 58 // Strip trailing newlines 59 while (length > 0) { 60 if (message[length - 1] != '\n' 61 && message[length - 1] != '\r') { 62 break; 63 } 64 length--; 65 } 66 if (length <= 0) 67 return; 68 69 char buffer[1500]; 70 // same comment as in vfprintf applies... 71 const int facility = 0; // kernel 72 int severity = 7; // debug 73 int offset = snprintf(buffer, sizeof(buffer), 74 "<%d>1 - - Haiku - - - \xEF\xBB\xBF", 75 facility * 8 + severity); 76 length = std::min(length, (int)sizeof(buffer) - offset); 77 memcpy(buffer + offset, message, length); 78 sSyslogSocket->Send(INADDR_BROADCAST, 514, buffer, offset + length); 79 } 80 81 #endif 82 83 84 int 85 vfprintf(FILE *file, const char *format, va_list list) 86 { 87 ConsoleNode *node = (ConsoleNode *)file; 88 char buffer[512]; 89 // the buffer handling could (or should) be done better... 90 91 int length = vsnprintf(buffer, sizeof(buffer), format, list); 92 length = std::min(length, (int)sizeof(buffer) - 1); 93 if (length > 0) { 94 node->Write(buffer, length); 95 #ifdef ENABLE_SYSLOG 96 sendToSyslog(buffer, length); 97 #endif 98 } 99 100 return length; 101 } 102 103 104 int 105 vprintf(const char *format, va_list args) 106 { 107 return vfprintf(stdout, format, args); 108 } 109 110 111 int 112 printf(const char *format, ...) 113 { 114 va_list args; 115 116 va_start(args, format); 117 int status = vfprintf(stdout, format, args); 118 va_end(args); 119 120 return status; 121 } 122 123 124 int 125 fprintf(FILE *file, const char *format, ...) 126 { 127 va_list args; 128 129 va_start(args, format); 130 int status = vfprintf(file, format, args); 131 va_end(args); 132 133 return status; 134 } 135 136 137 int 138 fputc(int c, FILE *file) 139 { 140 if (file == NULL) 141 return B_FILE_ERROR; 142 143 status_t status; 144 char character = (char)c; 145 146 // we only support direct console output right now... 147 status = ((ConsoleNode *)file)->Write(&character, 1); 148 149 #ifdef ENABLE_SYSLOG 150 sendToSyslog(&character, 1); 151 #endif 152 153 if (status > 0) 154 return character; 155 156 return status; 157 } 158 159 160 int 161 fputs(const char *string, FILE *file) 162 { 163 if (file == NULL) 164 return B_FILE_ERROR; 165 166 status_t status = ((ConsoleNode *)file)->Write(string, strlen(string)); 167 fputc('\n', file); 168 169 #ifdef ENABLE_SYSLOG 170 sendToSyslog(string, strlen(string)); 171 #endif 172 173 return status; 174 } 175 176 177 int 178 putc(int character) 179 { 180 return fputc(character, stdout); 181 } 182 183 184 int 185 putchar(int character) 186 { 187 return fputc(character, stdout); 188 } 189 190 191 int 192 puts(const char *string) 193 { 194 return fputs(string, stdout); 195 } 196 197