/* ZZ FIXME: * This should really be part of logmsg, as the timestamps have currently * the time when the logger reads the message from the log pipe. There can be * quite a delay at times when there is a high system activity. Moving the timestamp * to logmsg() will fix this. * The timestamp option should also NOT depend on anything like daemon mode. * logs entries should always be timestamped, in a fixed format, such that * log readers may decide to skip the timestamp when displaying (ie panel.c). */ static void logger_logfile_timestamp() { if (!sysblk.daemon_mode) { struct timeval now; time_t tt; char hhmmss[10]; gettimeofday( &now, NULL ); tt = now.tv_sec; strlcpy( hhmmss, ctime(&tt)+11, sizeof(hhmmss) ); logger_logfile_write( hhmmss, strlen(hhmmss) ); } }
static void* logger_thread(void *arg) { int bytes_read; UNREFERENCED(arg); /* Set root mode in order to set priority */ SETMODE(ROOT); /* Set device thread priority; ignore any errors */ if(set_thread_priority(0, sysblk.devprio)) WRMSG(HHC00136, "W", "set_thread_priority()", strerror(errno)); /* Back to user mode */ SETMODE(USER); #if !defined( _MSVC_ ) /* Redirect stdout to the logger */ if(dup2(logger_syslogfd[LOG_WRITE],STDOUT_FILENO) == -1) { if(logger_hrdcpy) fprintf(logger_hrdcpy, MSG(HHC02102, "E", "dup2()", strerror(errno))); exit(1); } #endif /* !defined( _MSVC_ ) */ setvbuf (stdout, NULL, _IONBF, 0); obtain_lock(&logger_lock); logger_active = 1; /* Signal initialization complete */ signal_condition(&logger_cond); release_lock(&logger_lock); /* ZZ FIXME: We must empty the read pipe before we terminate */ /* (Couldn't we just loop waiting for a 'select(,&readset,,,timeout)' to return zero?? Or use the 'poll' function similarly?? - Fish) */ while(logger_active) { bytes_read = read_pipe(logger_syslogfd[LOG_READ],logger_buffer + logger_currmsg, ((logger_bufsize - logger_currmsg) > LOG_DEFSIZE ? LOG_DEFSIZE : logger_bufsize - logger_currmsg)); if(bytes_read == -1) { int read_pipe_errno = HSO_errno; // (ignore any/all errors at shutdown) if (sysblk.shutdown) continue; if (HSO_EINTR == read_pipe_errno) continue; obtain_lock(&logger_lock); if(logger_hrdcpy) { fprintf(logger_hrdcpy, MSG(HHC02102, "E", "read_pipe()", strerror(read_pipe_errno))); } release_lock(&logger_lock); bytes_read = 0; } /* If Hercules is not running in daemon mode and panel initialization is not yet complete, write message to stderr so the user can see it on the terminal */ if (!sysblk.daemon_mode) { if (!sysblk.panel_init) { char* pLeft2 = logger_buffer + logger_currmsg; int nLeft2 = bytes_read; #if defined( OPTION_MSGCLR ) /* Remove "<pnl,..." color string if it exists */ if (1 && nLeft2 > 5 && strncasecmp( pLeft2, "<pnl", 4 ) == 0 && (pLeft2 = memchr( pLeft2+4, '>', nLeft2-4 )) != NULL ) { pLeft2++; nLeft2 -= (int)(pLeft2 - (logger_buffer + logger_currmsg)); } #endif // defined( OPTION_MSGCLR ) /* (ignore any errors; we did the best we could) */ if (nLeft2) { if ( fwrite( pLeft2, nLeft2, 1, stderr ) ) { perror(QLINE "fwrite failure/HHC02102 "); } } } } obtain_lock(&logger_lock); /* Write log data to hardcopy file */ if (logger_hrdcpy) { /* Need to prefix each line with a timestamp. */ static int needstamp = 1; char* pLeft = logger_buffer + logger_currmsg; int nLeft = bytes_read; char* pRight = NULL; int nRight = 0; char* pNL = NULL; /* (pointer to NEWLINE character) */ if (needstamp) { if (!sysblk.logoptnotime) logger_logfile_timestamp(); needstamp = 0; } while ( (pNL = memchr( pLeft, '\n', nLeft )) != NULL ) { pRight = pNL + 1; nRight = nLeft - (int)(pRight - pLeft); nLeft -= nRight; #if defined( OPTION_MSGCLR ) /* Remove "<pnl...>" color string if it exists */ { char* pLeft2 = pLeft; int nLeft2 = nLeft; if (1 && nLeft > 5 && strncasecmp( pLeft, "<pnl", 4 ) == 0 && (pLeft2 = memchr( pLeft+4, '>', nLeft-4 )) != NULL ) { pLeft2++; nLeft2 -= (int)(pLeft2 - pLeft); } else { pLeft2 = pLeft; nLeft2 = nLeft; } if (nLeft2) logger_logfile_write( pLeft2, nLeft2 ); } #else // !defined( OPTION_MSGCLR ) if (nLeft) logger_logfile_write( pLeft, nLeft ); #endif // defined( OPTION_MSGCLR ) pLeft = pRight; nLeft = nRight; if (!nLeft) { needstamp = 1; break; } if (!sysblk.logoptnotime) logger_logfile_timestamp(); } if (nLeft) logger_logfile_write( pLeft, nLeft ); } release_lock(&logger_lock); /* Increment buffer index to next available position */ logger_currmsg += bytes_read; if(logger_currmsg >= logger_bufsize) { logger_currmsg = 0; logger_wrapped = 1; } /* Notify all interested parties new log data is available */ obtain_lock(&logger_lock); broadcast_condition(&logger_cond); release_lock(&logger_lock); } logger_tid = 0; /* Logger is now terminating */ obtain_lock(&logger_lock); /* Write final message to hardcopy file */ if (logger_hrdcpy) { char* term_msg = MSG(HHC02103, "I"); size_t term_msg_len = strlen(term_msg); if (!sysblk.logoptnotime) logger_logfile_timestamp(); logger_logfile_write( term_msg, term_msg_len ); } /* Redirect all msgs to stderr */ logger_syslog[LOG_WRITE] = stderr; logger_syslogfd[LOG_WRITE] = STDERR_FILENO; fflush(stderr); /* Signal any waiting tasks */ broadcast_condition(&logger_cond); release_lock(&logger_lock); return NULL; }