diff --git a/audisp/plugins/remote/audisp-remote.c b/audisp/plugins/remote/audisp-remote.c index 2b79929c9..d97d319e2 100644 --- a/audisp/plugins/remote/audisp-remote.c +++ b/audisp/plugins/remote/audisp-remote.c @@ -199,17 +199,6 @@ static int sync_error_handler (const char *why) return 0; } -static int is_pipe(int fd) -{ - struct stat st; - - if (fstat(fd, &st) == 0) { - if (S_ISFIFO(st.st_mode)) - return 1; - } - return 0; -} - static void change_runlevel(const char *level) { char *argv[3]; diff --git a/common/common.c b/common/common.c index d400528e8..3b92c9390 100644 --- a/common/common.c +++ b/common/common.c @@ -29,6 +29,8 @@ #include #include // strtol #include +#include +#include /* * This function returns 1 if it is the last record in an event. @@ -162,3 +164,43 @@ long time_string_to_seconds(const char *time_string, return i; } +int is_pipe(int fd) +{ + struct stat st; + + return (!fstat(fd, &st) && S_ISFIFO(st.st_mode)); +} + +/* + * Check if stdin is a pipe, and it is, check if it has data on it. + * + * Return: + * 0: no data to read + * 1: has data to read + * -errno: error from poll() or -EPIPE if errno wasn't set + */ +int check_stdin_data(void) +{ + struct pollfd in = { + .fd = STDIN_FILENO, + .events = POLLIN, + }; + int ret; + + if (!is_pipe(in.fd)) + return 0; + + /* this is stdin, so a 0 timeout should be enough for this check */ + ret = poll(&in, 1, 0); + if (ret < 0 || (in.revents & POLLERR)) { + ret = errno ? -errno : -EPIPE; + fprintf(stderr, "\n", ret); + + return ret; + } + + if (!ret || !(in.revents & POLLIN)) + return 0; + + return 1; +} diff --git a/common/common.h b/common/common.h index 5c9d5d9f4..0d8afc8c8 100644 --- a/common/common.h +++ b/common/common.h @@ -87,6 +87,9 @@ void wall_message(const char *fmt, ...) ; #endif +int is_pipe(int fd); +int check_stdin_data(void); + AUDIT_HIDDEN_END #endif diff --git a/src/aureport.c b/src/aureport.c index 666d06c95..4518c4b52 100644 --- a/src/aureport.c +++ b/src/aureport.c @@ -69,21 +69,10 @@ extern int force_logs; extern time_t arg_eoe_timeout; -static int is_pipe(int fd) -{ - struct stat st; - - if (fstat(fd, &st) == 0) { - if (S_ISFIFO(st.st_mode)) - return 1; - } - return 0; -} - int main(int argc, char *argv[]) { struct rlimit limit; - int rc; + int rc, has_stdin; /* Check params and build regexpr */ setlocale (LC_ALL, ""); @@ -111,6 +100,10 @@ int main(int argc, char *argv[]) fprintf(stderr, "NOTE - using built-in logs: %s\n", config.log_file); + has_stdin = check_stdin_data(); + if (has_stdin < 0) + return 1; + /* Set timeout from the config file */ lol_set_eoe_timeout((time_t)config.end_of_event_timeout); @@ -143,12 +136,10 @@ int main(int argc, char *argv[]) break; } } - } else if (force_logs) + } else if (force_logs || !has_stdin) rc = process_logs(); - else if (is_pipe(0)) - rc = process_stdin(); else - rc = process_logs(); + rc = process_stdin(); lol_clear(&lo); if (rc) return rc; diff --git a/src/ausearch-common.h b/src/ausearch-common.h index 3040547af..e0661803e 100644 --- a/src/ausearch-common.h +++ b/src/ausearch-common.h @@ -30,6 +30,7 @@ #include #include "ausearch-string.h" #include "auparse-defs.h" +#include "common.h" /* * MAX_EVENT_DELTA_SECS is the maximum number of seconds it would take for diff --git a/src/ausearch.c b/src/ausearch.c index c47b9ed44..695ce4482 100644 --- a/src/ausearch.c +++ b/src/ausearch.c @@ -76,22 +76,10 @@ extern void output_auparse_finish(void); */ extern time_t arg_eoe_timeout; -static int is_pipe(int fd) -{ - struct stat st; - int pipe_mode=0; - - if (fstat(fd, &st) == 0) { - if (S_ISFIFO(st.st_mode)) - pipe_mode = 1; - } - return pipe_mode; -} - int main(int argc, char *argv[]) { struct rlimit limit; - int rc; + int rc, has_stdin; struct stat sb; /* Check params and build regexpr */ @@ -124,6 +112,10 @@ int main(int argc, char *argv[]) } } + has_stdin = check_stdin_data(); + if (has_stdin < 0) + return 1; + /* Set timeout from the config file */ lol_set_eoe_timeout((time_t)config.end_of_event_timeout); @@ -179,16 +171,15 @@ int main(int argc, char *argv[]) free_config(&config); break; } - } else if (force_logs) + } else if (force_logs || !has_stdin) rc = process_logs(); - else if (is_pipe(0)) { + else { rc = process_stdin(); if (checkpt_filename) fprintf(stderr, "Warning - checkpointing stdin is not supported"); goto skip_checkpt; // Don't overwrite chkpt when reading a pipe - } else - rc = process_logs(); + } /* Generate a checkpoint if required */ if (checkpt_filename) {