233{
234 const int bufSize = 4000000;
235 char* p, *q;
236 char* const buf = new char[bufSize];
237 int len;
238 int siz = bufSize * sizeof(char) - 1;
239 int toolong = 0;
240
241 p = buf;
242 fd_set fdset;
243 do {
244 FD_ZERO(&fdset);
245 if (fd <= 0) {
246 printf("Pipe for log is not availablle\n");
247 Abort("No pipe available");
248 }
249 FD_SET(fd, &fdset);
250 struct timeval tv;
251 tv.tv_sec = 0;
252 tv.tv_usec = 0;
253 if (select(fd + 1, &fdset, NULL, NULL, &tv) < 0) {
254 switch (errno) {
255 case EINTR: continue;
256 case EAGAIN: continue;
257 default:
258 perror("select");
259 return -1;
260 }
261 return -1;
262 } else if (!(fd > 0 && FD_ISSET(fd, &fdset))) {
263 return 0;
264 }
265 if ((len = read(fd, p, siz)) < 0) {
266 if (errno == EINTR) continue;
267 if (errno == EPIPE) {
268 Log("broken pipe fd=%d", fd);
269 close(fd);
270 return -1;
271 } else if (errno == EBADF) {
272 Log("bad fd=%d", fd);
273 return -1;
274 }
275 perror("read");
276 Abort("read");
277 } else if (len == 0) {
278 close(fd);
279 return -1;
280 } else {
281 p[len] = 0;
282 len += p - buf;
283 p = buf;
284 do {
285 if (!(q = strchr(p, '\n'))) {
286 if (p == buf && len == siz) {
287 if (! toolong)
288 Warning("too long message from fd=%d", fd);
289 toolong = 1;
290 } else {
291 len -= p - buf;
292 memmove(buf, p, len);
293 siz = bufSize * sizeof(char) - len;
294 p = buf + len;
295 }
296 break;
297 }
298 *q++ = 0;
299 if (! toolong) {
300 if (strlen(p) > 13 &&
301 p[2] == ':' && p[5] == ':' && p[8] == '.' && p[12] == ' ') {
302 p += 13;
303 }
304 if (strncmp(p, "[FATAL] ", 8) == 0) {
305 Fatal("%s", p + 8);
306 } else if (strncmp(p, "[ERROR] ", 8) == 0) {
307 Error("%s", p + 8);
308 } else if (strncmp(p, "[WARNING] ", 10) == 0) {
309 Warning("%s", p + 10);
310 } else if (strncmp(p, "[INFO] ", 7) == 0) {
311 Info("%s", p + 7);
312 } else if (strncmp(p, "[ABORT] ", 8) == 0) {
313 Fatal("abort - %s", p + 8);
314 } else if (strncmp(p, "[sysexit] ", 10) == 0) {
315 Fatal("sysexit - %s", p + 10);
316 } else {
317 Log("%s", p);
318 }
319 }
320 toolong = 0;
321 p = q;
322 if (! *p) return 0;
323 } while (*p);
324 }
325 } while (1);
326}