@@ -2038,14 +2038,46 @@ static int sync_journal(void) {
20382038 return send_signal_and_wait (SIGRTMIN + 1 , "/run/systemd/journal/synced" );
20392039}
20402040
2041- int main (int argc , char * argv []) {
2041+ static int wait_for_change (sd_journal * j , int poll_fd ) {
2042+ struct pollfd pollfds [] = {
2043+ { .fd = poll_fd , .events = POLLIN },
2044+ { .fd = STDOUT_FILENO },
2045+ };
2046+
2047+ struct timespec ts ;
2048+ usec_t timeout ;
20422049 int r ;
2050+
2051+ assert (j );
2052+ assert (poll_fd >= 0 );
2053+
2054+ /* Much like sd_journal_wait() but also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that,
2055+ * i.e. when it is closed. */
2056+
2057+ r = sd_journal_get_timeout (j , & timeout );
2058+ if (r < 0 )
2059+ return log_error_errno (r , "Failed to determine journal waiting time: %m" );
2060+
2061+ if (ppoll (pollfds , ELEMENTSOF (pollfds ), timeout == USEC_INFINITY ? NULL : timespec_store (& ts , timeout ), NULL ) < 0 )
2062+ return log_error_errno (errno , "Couldn't wait for journal event: %m" );
2063+
2064+ if (pollfds [1 ].revents & (POLLHUP |POLLERR )) { /* STDOUT has been closed? */
2065+ log_debug ("Standard output has been closed." );
2066+ return - ECANCELED ;
2067+ }
2068+
2069+ r = sd_journal_process (j );
2070+ if (r < 0 )
2071+ return log_error_errno (r , "Failed to process journal events: %m" );
2072+
2073+ return 0 ;
2074+ }
2075+
2076+ int main (int argc , char * argv []) {
2077+ bool previous_boot_id_valid = false, first_line = true, ellipsized = false, need_seek = false;
20432078 _cleanup_ (sd_journal_closep ) sd_journal * j = NULL ;
2044- bool need_seek = false;
20452079 sd_id128_t previous_boot_id ;
2046- bool previous_boot_id_valid = false, first_line = true;
2047- int n_shown = 0 ;
2048- bool ellipsized = false;
2080+ int n_shown = 0 , r , poll_fd = -1 ;
20492081
20502082 setlocale (LC_ALL , "" );
20512083 log_parse_environment ();
@@ -2373,15 +2405,15 @@ int main(int argc, char *argv[]) {
23732405
23742406 /* Opening the fd now means the first sd_journal_wait() will actually wait */
23752407 if (arg_follow ) {
2376- r = sd_journal_get_fd (j );
2377- if (r == - EMFILE ) {
2378- log_warning ( "Insufficent watch descriptors available. Reverting to -n." );
2408+ poll_fd = sd_journal_get_fd (j );
2409+ if (poll_fd == - EMFILE ) {
2410+ log_warning_errno ( poll_fd , "Insufficent watch descriptors available. Reverting to -n." );
23792411 arg_follow = false;
2380- } else if (r == - EMEDIUMTYPE ) {
2381- log_error_errno (r , "The --follow switch is not supported in conjunction with reading from STDIN." );
2412+ } else if (poll_fd == - EMEDIUMTYPE ) {
2413+ log_error_errno (poll_fd , "The --follow switch is not supported in conjunction with reading from STDIN." );
23822414 goto finish ;
2383- } else if (r < 0 ) {
2384- log_error_errno (r , "Failed to get journal fd: %m" );
2415+ } else if (poll_fd < 0 ) {
2416+ log_error_errno (poll_fd , "Failed to get journal fd: %m" );
23852417 goto finish ;
23862418 }
23872419 }
@@ -2603,7 +2635,7 @@ int main(int argc, char *argv[]) {
26032635 need_seek = true;
26042636 if (r == - EADDRNOTAVAIL )
26052637 break ;
2606- else if (r < 0 || ferror ( stdout ) )
2638+ else if (r < 0 )
26072639 goto finish ;
26082640
26092641 n_shown ++ ;
@@ -2641,11 +2673,10 @@ int main(int argc, char *argv[]) {
26412673 }
26422674
26432675 fflush (stdout );
2644- r = sd_journal_wait ( j , ( uint64_t ) -1 );
2645- if ( r < 0 ) {
2646- log_error_errno ( r , "Couldn't wait for journal event: %m" );
2676+
2677+ r = wait_for_change ( j , poll_fd );
2678+ if ( r < 0 )
26472679 goto finish ;
2648- }
26492680
26502681 first_line = false;
26512682 }
0 commit comments