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 29int errno; 30 31 32int* 33_errnop(void) 34{ 35 return &errno; 36} 37 38 39#ifdef ENABLE_SYSLOG 40 41static UDPSocket *sSyslogSocket = NULL; 42 43static void 44sendToSyslog(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 84int 85vfprintf(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 104int 105vprintf(const char *format, va_list args) 106{ 107 return vfprintf(stdout, format, args); 108} 109 110 111int 112printf(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 124int 125fprintf(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 137int 138fputc(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 160int 161fputs(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 177int 178putc(int character) 179{ 180 return fputc(character, stdout); 181} 182 183 184int 185putchar(int character) 186{ 187 return fputc(character, stdout); 188} 189 190 191int 192puts(const char *string) 193{ 194 return fputs(string, stdout); 195} 196 197