journalctl: do not fail on SIGTERM/SIGINT or STDOUT disconnect when running with --follow (#38116)

Closes #38114.
This commit is contained in:
Yu Watanabe
2025-07-11 10:36:31 +09:00
committed by GitHub
12 changed files with 17 additions and 62 deletions
+6 -10
View File
@@ -371,7 +371,7 @@ static int on_synchronize_reply(
static int on_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *vl = NULL;
Context *c = ASSERT_PTR(userdata);
int r;
int r = 0;
assert(s);
assert(si);
@@ -381,7 +381,7 @@ static int on_signal(sd_event_source *s, const struct signalfd_siginfo *si, void
goto finish;
if (c->synchronize_varlink) /* Already pending? Then exit immediately, so that user can cancel the sync */
return sd_event_exit(c->event, EXIT_SUCCESS);
goto finish;
r = varlink_connect_journal(&vl);
if (r < 0) {
@@ -417,7 +417,7 @@ static int on_signal(sd_event_source *s, const struct signalfd_siginfo *si, void
return 0;
finish:
return sd_event_exit(c->event, si->ssi_signo);
return sd_event_exit(c->event, r);
}
static int setup_event(Context *c, int fd) {
@@ -436,12 +436,12 @@ static int setup_event(Context *c, int fd) {
(void) sd_event_add_signal(e, /* ret= */ NULL, SIGTERM | SD_EVENT_SIGNAL_PROCMASK, on_signal, c);
(void) sd_event_add_signal(e, /* ret= */ NULL, SIGINT | SD_EVENT_SIGNAL_PROCMASK, on_signal, c);
r = sd_event_add_io(e, NULL, fd, EPOLLIN, &on_journal_event, c);
r = sd_event_add_io(e, /* ret = */ NULL, fd, EPOLLIN, &on_journal_event, c);
if (r < 0)
return log_error_errno(r, "Failed to add io event source for journal: %m");
/* Also keeps an eye on STDOUT, and exits as soon as we see a POLLHUP on that, i.e. when it is closed. */
r = sd_event_add_io(e, NULL, STDOUT_FILENO, EPOLLHUP|EPOLLERR, NULL, INT_TO_PTR(-ECANCELED));
r = sd_event_add_io(e, /* ret = */ NULL, STDOUT_FILENO, EPOLLHUP|EPOLLERR, /* callback = */ NULL, /* userdata = */ NULL);
if (r == -EPERM)
/* Installing an epoll watch on a regular file doesn't work and fails with EPERM. Which is
* totally OK, handle it gracefully. epoll_ctl() documents EPERM as the error returned when
@@ -544,8 +544,6 @@ int action_show(char **matches) {
}
if (arg_follow) {
int sig;
assert(poll_fd >= 0);
r = setup_event(&c, poll_fd);
@@ -555,14 +553,12 @@ int action_show(char **matches) {
r = sd_event_loop(c.event);
if (r < 0)
return r;
sig = r;
r = update_cursor(c.journal);
if (r < 0)
return r;
/* re-send the original signal. */
return sig;
return 0;
}
(void) sd_notify(/* unset_environment= */ false, "READY=1");
+1 -1
View File
@@ -1189,4 +1189,4 @@ static int run(int argc, char *argv[]) {
}
}
DEFINE_MAIN_FUNCTION_WITH_POSITIVE_SIGNAL(run);
DEFINE_MAIN_FUNCTION(run);
-1
View File
@@ -115,7 +115,6 @@ bool generator_soft_rebooted(void);
impl(argv[1], \
argv[argc == 4 ? 2 : 1], \
argv[argc == 4 ? 3 : 1]), \
exit_failure_if_negative, \
exit_failure_if_negative)
typedef enum GptAutoRoot {
-24
View File
@@ -1,20 +1,15 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stdlib.h>
#if HAVE_VALGRIND_VALGRIND_H
# include <valgrind/valgrind.h>
#endif
#include "sd-daemon.h"
#include "argv-util.h"
#include "ask-password-agent.h"
#include "hashmap.h"
#include "main-func.h"
#include "pager.h"
#include "polkit-agent.h"
#include "selinux-util.h"
#include "signal-util.h"
#include "string-util.h"
void main_prepare(int argc, char *argv[]) {
@@ -32,25 +27,6 @@ void main_finalize(int r, int exit_status) {
mac_selinux_finish();
}
int raise_or_exit_status(int ret) {
if (ret < 0)
return EXIT_FAILURE;
if (ret == 0)
return EXIT_SUCCESS;
if (!SIGNAL_VALID(ret))
return EXIT_FAILURE;
#if HAVE_VALGRIND_VALGRIND_H
/* If raise() below succeeds, the destructor cleanup_pools() in hashmap.c will never called. */
if (RUNNING_ON_VALGRIND)
hashmap_trim_pools();
#endif
(void) raise(ret);
/* exit with failure if raise() does not immediately abort the program. */
return EXIT_FAILURE;
}
int exit_failure_if_negative(int result) {
return result < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
+7 -13
View File
@@ -8,15 +8,16 @@ void main_prepare(int argc, char *argv[]);
void main_finalize(int r, int exit_status);
#define _DEFINE_MAIN_FUNCTION(intro, impl, result_to_exit_status, result_to_return_value) \
#define _DEFINE_MAIN_FUNCTION(intro, impl, result_to_exit_status) \
int main(int argc, char *argv[]) { \
int r; \
int r, s; \
main_prepare(argc, argv); \
intro; \
r = impl; \
main_finalize(r, result_to_exit_status(r)); \
s = result_to_exit_status(r); \
main_finalize(r, s); \
static_destruct(); \
return result_to_return_value(r); \
return s; \
}
int exit_failure_if_negative(int result) _const_;
@@ -24,7 +25,7 @@ int exit_failure_if_negative(int result) _const_;
/* Negative return values from impl are mapped to EXIT_FAILURE, and
* everything else means success! */
#define DEFINE_MAIN_FUNCTION(impl) \
_DEFINE_MAIN_FUNCTION(,impl(argc, argv), exit_failure_if_negative, exit_failure_if_negative)
_DEFINE_MAIN_FUNCTION(, impl(argc, argv), exit_failure_if_negative)
int exit_failure_if_nonzero(int result) _const_;
@@ -32,11 +33,4 @@ int exit_failure_if_nonzero(int result) _const_;
* and positive values are propagated.
* Note: "true" means failure! */
#define DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(impl) \
_DEFINE_MAIN_FUNCTION(,impl(argc, argv), exit_failure_if_nonzero, exit_failure_if_nonzero)
int raise_or_exit_status(int ret);
/* Negative return values from impl are mapped to EXIT_FAILURE, zero is mapped to EXIT_SUCCESS,
* and raise if a positive signal is returned from impl. */
#define DEFINE_MAIN_FUNCTION_WITH_POSITIVE_SIGNAL(impl) \
_DEFINE_MAIN_FUNCTION(,impl(argc, argv), exit_failure_if_negative, raise_or_exit_status)
_DEFINE_MAIN_FUNCTION(, impl(argc, argv), exit_failure_if_nonzero)