Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reattach to the syslog-ng console from syslog-ng-ctl #326

Open
wants to merge 11 commits into
base: main
Choose a base branch
from
Open
2 changes: 2 additions & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ set (LIB_HEADERS
atomic-gssize.h
block-ref-parser.h
cache.h
console.h
cfg.h
cfg-lexer.h
cfg-lexer-subst.h
Expand Down Expand Up @@ -179,6 +180,7 @@ set(LIB_SOURCES
apphook.c
block-ref-parser.c
cache.c
console.c
cfg.c
cfg-args.c
cfg-block.c
Expand Down
2 changes: 2 additions & 0 deletions lib/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ pkginclude_HEADERS += \
lib/atomic-gssize.h \
lib/block-ref-parser.h \
lib/cache.h \
lib/console.h \
lib/cfg.h \
lib/cfg-grammar.h \
lib/cfg-grammar-internal.h \
Expand Down Expand Up @@ -195,6 +196,7 @@ lib_libsyslog_ng_la_SOURCES = \
lib/apphook.c \
lib/block-ref-parser.c \
lib/cache.c \
lib/console.c \
lib/cfg.c \
lib/cfg-args.c \
lib/cfg-block.c \
Expand Down
132 changes: 132 additions & 0 deletions lib/console.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/*
* Copyright (c) 2002-2012 Balabit
* Copyright (c) 1998-2012 Balázs Scheidler
* Copyright (c) 2024 Balázs Scheidler <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
*/
#include "console.h"
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>

GMutex console_lock;
gboolean console_present = FALSE;
gboolean using_initial_console = TRUE;

/* NOTE: this is not synced with any changes and is just an indication whether we have a console */
gboolean
console_is_present(gboolean exclude_initial)
{
gboolean result;
/* the lock only serves a memory barrier but is not a real synchronization */
g_mutex_lock(&console_lock);
if (exclude_initial && using_initial_console)
result = FALSE;
else
result = console_present;
g_mutex_unlock(&console_lock);
return result;
}

/* set the current console to be our current stdin/out/err after we start up */
void
console_acquire_from_stdio(void)
{
g_assert(!console_is_present(FALSE));

g_mutex_lock(&console_lock);
console_present = TRUE;
g_mutex_unlock(&console_lock);
}

/* re-acquire a console after startup using an array of fds */
void
console_acquire_from_fds(gint fds[3])
{
const gchar *takeover_message_on_old_console = "[Console taken over, no further output here]\n";
g_assert(!console_is_present(TRUE));

if (using_initial_console)
{
(void) write(1, takeover_message_on_old_console, strlen(takeover_message_on_old_console));
}

g_mutex_lock(&console_lock);

dup2(fds[0], STDIN_FILENO);
dup2(fds[1], STDOUT_FILENO);
dup2(fds[2], STDERR_FILENO);

console_present = TRUE;
using_initial_console = FALSE;
g_mutex_unlock(&console_lock);
}

/**
* console_release:
*
* Use /dev/null as input/output/error. This function is idempotent, can be
* called any number of times without harm.
**/
void
console_release(void)
{
gint devnull_fd;

g_mutex_lock(&console_lock);

if (!console_present)
goto exit;

devnull_fd = open("/dev/null", O_RDONLY);
if (devnull_fd >= 0)
{
dup2(devnull_fd, STDIN_FILENO);
close(devnull_fd);
}
devnull_fd = open("/dev/null", O_WRONLY);
if (devnull_fd >= 0)
{
dup2(devnull_fd, STDOUT_FILENO);
dup2(devnull_fd, STDERR_FILENO);
close(devnull_fd);
}
clearerr(stdin);
clearerr(stdout);
clearerr(stderr);
console_present = FALSE;
using_initial_console = FALSE;

exit:
g_mutex_unlock(&console_lock);
}

void
console_global_init(void)
{
g_mutex_init(&console_lock);
}

void
console_global_deinit(void)
{
g_mutex_clear(&console_lock);
}
38 changes: 38 additions & 0 deletions lib/console.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2002-2012 Balabit
* Copyright (c) 1998-2012 Balázs Scheidler
* Copyright (c) 2024 Balázs Scheidler <[email protected]>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* As an additional exemption you are allowed to compile & link against the
* OpenSSL libraries as published by the OpenSSL project. See the file
* COPYING for details.
*
*/
#ifndef SYSLOG_NG_CONSOLE_H_INCLUDED
#define SYSLOG_NG_CONSOLE_H_INCLUDED

#include "syslog-ng.h"

gboolean console_is_present(gboolean exclude_initial);
void console_acquire_from_fds(gint fds[3]);
void console_acquire_from_stdio(void);
void console_release(void);

void console_global_init(void);
void console_global_deinit(void);

#endif
11 changes: 9 additions & 2 deletions lib/control/control-command-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "messages.h"
#include "secret-storage/secret-storage.h"
#include "scratch-buffers.h"
#include "apphook.h"
#include <iv_event.h>

struct _ControlCommandThread
Expand All @@ -44,6 +45,12 @@ struct _ControlCommandThread
struct iv_event thread_finished;
};

gboolean
control_command_thread_relates_to_connection(ControlCommandThread *self, ControlConnection *cc)
{
return self->connection == cc;
}

static void
_on_thread_finished(gpointer user_data)
{
Expand All @@ -64,7 +71,7 @@ _thread(gpointer user_data)
ControlCommandThread *self = (ControlCommandThread *) user_data;

iv_init();
scratch_buffers_allocator_init();
app_thread_start();

msg_debug("Control command thread has started",
evt_tag_str("control_command", self->command->str));
Expand All @@ -82,8 +89,8 @@ _thread(gpointer user_data)
evt_tag_str("control_command", self->command->str));

scratch_buffers_explicit_gc();
scratch_buffers_allocator_deinit();
control_command_thread_unref(self);
app_thread_stop();
iv_deinit();
}

Expand Down
2 changes: 2 additions & 0 deletions lib/control/control-command-thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@

#include "control.h"

gboolean control_command_thread_relates_to_connection(ControlCommandThread *self, ControlConnection *cc);

void control_command_thread_run(ControlCommandThread *self);
void control_command_thread_cancel(ControlCommandThread *self);
const gchar *control_command_thread_get_command(ControlCommandThread *self);
Expand Down
10 changes: 9 additions & 1 deletion lib/control/control-connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ _g_string_destroy(gpointer user_data)
g_string_free(str, TRUE);
}

gboolean
control_connection_get_attached_fds(ControlConnection *self, gint *fds, gsize *num_fds)
{
if (self->get_attached_fds)
return self->get_attached_fds(self, fds, num_fds);
return FALSE;
}

static void
_control_connection_free(ControlConnection *self)
{
Expand Down Expand Up @@ -215,7 +223,7 @@ control_connection_io_input(void *s)
}
else if (rc == 0)
{
msg_debug("EOF on control channel, closing connection");
msg_trace("EOF on control channel, closing connection");
goto destroy_connection;
}
else
Expand Down
2 changes: 2 additions & 0 deletions lib/control/control-connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ struct _ControlConnection
GString *output_buffer;
gsize pos;
ControlServer *server;
gboolean (*get_attached_fds)(ControlConnection *self, gint *fds, gsize *num_fds);
gboolean (*run_command)(ControlConnection *self, ControlCommand *command_desc, GString *command_string);
int (*read)(ControlConnection *self, gpointer buffer, gsize size);
int (*write)(ControlConnection *self, gpointer buffer, gsize size);
Expand All @@ -56,6 +57,7 @@ struct _ControlConnection

};

gboolean control_connection_get_attached_fds(ControlConnection *self, gint *fds, gsize *num_fds);
gboolean control_connection_run_command(ControlConnection *self, GString *command_string);
void control_connection_send_reply(ControlConnection *self, GString *reply);
void control_connection_send_batched_reply(ControlConnection *self, GString *reply);
Expand Down
Loading
Loading