diff options
| author | Michael Biebl <biebl@debian.org> | 2023-02-10 11:50:34 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2023-02-10 11:50:34 +0100 |
| commit | 1372848511cb896b80b51ed1a3e9606bd9816631 (patch) | |
| tree | 674792b9385bdef935988894b45f06b2af39f88c /src/libnm-client-impl/nm-libnm-utils.c | |
| parent | 40ec077ea305994c1fc2130add6787ca0c73e2c6 (diff) | |
New upstream version 1.42.0 upstream/1.42.0
Diffstat (limited to 'src/libnm-client-impl/nm-libnm-utils.c')
| -rw-r--r-- | src/libnm-client-impl/nm-libnm-utils.c | 163 |
1 files changed, 132 insertions, 31 deletions
diff --git a/src/libnm-client-impl/nm-libnm-utils.c b/src/libnm-client-impl/nm-libnm-utils.c index 6a7c155e..398c6ebc 100644 --- a/src/libnm-client-impl/nm-libnm-utils.c +++ b/src/libnm-client-impl/nm-libnm-utils.c @@ -16,7 +16,13 @@ /*****************************************************************************/ -volatile int _nml_dbus_log_level = 0; +#define LOG_FILE_FD_UNSET -3 +#define LOG_FILE_FD_NONE -2 +#define LOG_FILE_FD_DEFUNCT -1 + +volatile int _nml_dbus_log_level = 0; +const char *_nml_dbus_log_file = NULL; +int _nml_dbus_log_file_fd = LOG_FILE_FD_UNSET; int _nml_dbus_log_level_init(void) @@ -40,6 +46,97 @@ _nml_dbus_log_level_init(void) return l; } +static const char * +_nml_dbus_log_file_init(void) +{ + const char *s; + + s = g_getenv("LIBNM_CLIENT_DEBUG_FILE"); + if (nm_str_not_empty(s)) { + if (strstr(s, "%p")) { + gs_strfreev char **tokens = NULL; + char pid_str[100]; + + tokens = g_strsplit(s, "%p", -1); + nm_sprintf_buf(pid_str, "%lld", (long long) getpid()); + s = nm_str_realloc(g_strjoinv(pid_str, tokens)); + } else + s = g_strdup(s); + } else + s = ""; + + if (!g_atomic_pointer_compare_and_exchange(&_nml_dbus_log_file, NULL, s)) { + if (s[0] != '\0') + g_free((gpointer) s); + s = g_atomic_pointer_get(&_nml_dbus_log_file); + } + + return s; +} + +#define nml_dbus_log_file() \ + ({ \ + const char *_l; \ + \ + _l = g_atomic_pointer_get(&_nml_dbus_log_file); \ + if (G_UNLIKELY(!_l)) \ + _l = _nml_dbus_log_file_init(); \ + \ + _l[0] ? _l : NULL; \ + }) + +static int +_nml_dbus_log_file_fd_init(void) +{ + static GMutex mutex; + NM_G_MUTEX_LOCKED(&mutex); + int fd; + + fd = g_atomic_int_get(&_nml_dbus_log_file_fd); + if (fd == LOG_FILE_FD_UNSET) { + const char *name; + + name = nml_dbus_log_file(); + if (!name) + fd = LOG_FILE_FD_NONE; + else { + fd = open(name, O_WRONLY | O_TRUNC | O_CREAT | O_CLOEXEC, 0600); + if (fd < 0) + fd = LOG_FILE_FD_DEFUNCT; + } + g_atomic_int_set(&_nml_dbus_log_file_fd, fd); + } + + return fd; +} + +#define nml_dbus_log_file_fd() \ + ({ \ + int _fd2; \ + \ + _fd2 = g_atomic_int_get(&_nml_dbus_log_file_fd); \ + if (G_UNLIKELY(_fd2 == LOG_FILE_FD_UNSET)) \ + _fd2 = _nml_dbus_log_file_fd_init(); \ + \ + nm_assert(NM_IN_SET(_fd2, LOG_FILE_FD_NONE, LOG_FILE_FD_DEFUNCT) || _fd2 >= 0); \ + _fd2; \ + }) + +#define _log_printf(use_stdout, ...) \ + G_STMT_START \ + { \ + const int _fd = nml_dbus_log_file_fd(); \ + \ + if (_fd != LOG_FILE_FD_NONE) { \ + if (_fd >= 0) \ + dprintf(_fd, __VA_ARGS__); \ + } else if (use_stdout) \ + g_print(__VA_ARGS__); \ + else \ + g_printerr(__VA_ARGS__); \ + } \ + G_STMT_END + void _nml_dbus_log(NMLDBusLogLevel level, gboolean use_stdout, const char *fmt, ...) { @@ -94,21 +191,13 @@ _nml_dbus_log(NMLDBusLogLevel level, gboolean use_stdout, const char *fmt, ...) pid = getpid(); - if (use_stdout) { - g_print("libnm-dbus[%lld]: %s[%" G_GINT64_FORMAT ".%05" G_GINT64_FORMAT "] %s\n", + _log_printf(use_stdout, + "libnm-dbus[%lld]: %s[%" G_GINT64_FORMAT ".%05" G_GINT64_FORMAT "] %s\n", (long long) pid, prefix, ts / NM_UTILS_NSEC_PER_SEC, (ts / (NM_UTILS_NSEC_PER_SEC / 100000)) % 100000, msg); - } else { - g_printerr("libnm-dbus[%lld]: %s[%" G_GINT64_FORMAT ".%05" G_GINT64_FORMAT "] %s\n", - (long long) pid, - prefix, - ts / NM_UTILS_NSEC_PER_SEC, - (ts / (NM_UTILS_NSEC_PER_SEC / 100000)) % 100000, - msg); - } } /*****************************************************************************/ @@ -693,6 +782,7 @@ const NMLDBusMetaIface *const _nml_dbus_meta_ifaces[] = { &_nml_dbus_meta_iface_nm_device_generic, &_nml_dbus_meta_iface_nm_device_iptunnel, &_nml_dbus_meta_iface_nm_device_infiniband, + &_nml_dbus_meta_iface_nm_device_loopback, &_nml_dbus_meta_iface_nm_device_lowpan, &_nml_dbus_meta_iface_nm_device_macsec, &_nml_dbus_meta_iface_nm_device_macvlan, @@ -752,11 +842,11 @@ nml_dbus_meta_iface_get(const char *dbus_iface_name) if (NM_STR_HAS_PREFIX(dbus_iface_name, COMMON_PREFIX)) { /* optimize, that in fact all our interfaces have the same prefix. */ - idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) _nml_dbus_meta_ifaces, - G_N_ELEMENTS(_nml_dbus_meta_ifaces), - &dbus_iface_name[NM_STRLEN(COMMON_PREFIX)], - _strcmp_common_prefix, - NULL); + idx = nm_ptrarray_find_bsearch((gconstpointer *) _nml_dbus_meta_ifaces, + G_N_ELEMENTS(_nml_dbus_meta_ifaces), + &dbus_iface_name[NM_STRLEN(COMMON_PREFIX)], + _strcmp_common_prefix, + NULL); } else return NULL; @@ -775,12 +865,12 @@ nml_dbus_meta_property_get(const NMLDBusMetaIface *meta_iface, nm_assert(meta_iface); nm_assert(dbus_property_name); - idx = nm_utils_array_find_binary_search(meta_iface->dbus_properties, - sizeof(meta_iface->dbus_properties[0]), - meta_iface->n_dbus_properties, - &dbus_property_name, - nm_strcmp_p_with_data, - NULL); + idx = nm_array_find_bsearch(meta_iface->dbus_properties, + meta_iface->n_dbus_properties, + sizeof(meta_iface->dbus_properties[0]), + &dbus_property_name, + nm_strcmp_p_with_data, + NULL); if (idx < 0) { NM_SET_OUT(out_idx, meta_iface->n_dbus_properties); return NULL; @@ -883,8 +973,10 @@ nm_utils_g_param_spec_is_default(const GParamSpec *pspec) /** * nm_utils_print: * @output_mode: if 1 it uses g_print(). If 2, it uses g_printerr(). - * If 0, it uses either g_print() or g_printerr(), depending - * on LIBNM_CLIENT_DEBUG (and the "stdout" flag). + * If 0, it uses the same output as internal libnm debug logging + * does. That is, depending on LIBNM_CLIENT_DEBUG's "stdout" flag + * it uses g_print() or g_printerr() and if LIBNM_CLIENT_DEBUG_FILE is + * set, it writes the output to file instead * @msg: the message to print. The function does not append * a trailing newline. * @@ -895,6 +987,11 @@ nm_utils_g_param_spec_is_default(const GParamSpec *pspec) * with these functions (it implements additional buffering). By * using nm_utils_print(), the same logging mechanisms can be used. * + * Also, libnm honors LIBNM_CLIENT_DEBUG_FILE environment. If this + * is set to a filename pattern (accepting "%p" for the process ID), + * then the debug log is written to that file instead. With @output_mode + * zero, the same location will be written. Since: 1.44. + * * Since: 1.30 */ void @@ -904,17 +1001,21 @@ nm_utils_print(int output_mode, const char *msg) g_return_if_fail(msg); - if (output_mode == 0) { + switch (output_mode) { + case 0: nml_dbus_log_enabled_full(NML_DBUS_LOG_LEVEL_ANY, &use_stdout); - output_mode = use_stdout ? 1 : 2; - } - - if (output_mode == 1) + _log_printf(use_stdout, "%s", msg); + break; + case 1: g_print("%s", msg); - else if (output_mode == 2) + break; + case 2: g_printerr("%s", msg); - else + break; + default: g_return_if_reached(); + break; + } } /*****************************************************************************/ |