summaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-11-20 15:42:57 +0100
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2018-11-20 18:40:02 +0100
commit294bf0c34a53caa25709b794bfeee6a00a2b6ecd (patch)
treea429db1ca92924ac73959a0ed9954161e22612dd /src/basic
parent0166c42868813d5d96b500277f6f819eef498b95 (diff)
downloadsystemd-294bf0c34a53caa25709b794bfeee6a00a2b6ecd.tar.gz
Split out pretty-print.c and move pager.c and main-func.h to shared/
This is high-level functionality, and fits better in shared/ (which is for our executables), than in basic/ (which is also for libraries).
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/conf-files.c33
-rw-r--r--src/basic/conf-files.h1
-rw-r--r--src/basic/main-func.h27
-rw-r--r--src/basic/meson.build2
-rw-r--r--src/basic/pager.c270
-rw-r--r--src/basic/pager.h17
-rw-r--r--src/basic/terminal-util.c182
-rw-r--r--src/basic/terminal-util.h12
8 files changed, 0 insertions, 544 deletions
diff --git a/src/basic/conf-files.c b/src/basic/conf-files.c
index d03366077d..7b44ae277d 100644
--- a/src/basic/conf-files.c
+++ b/src/basic/conf-files.c
@@ -328,36 +328,3 @@ int conf_files_list_with_replacement(
*replace_file = TAKE_PTR(p);
return 0;
}
-
-int conf_files_cat(const char *root, const char *name) {
- _cleanup_strv_free_ char **dirs = NULL, **files = NULL;
- _cleanup_free_ char *path = NULL;
- const char *dir;
- char **t;
- int r;
-
- NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) {
- assert(endswith(dir, "/"));
- r = strv_extendf(&dirs, "%s%s.d", dir, name);
- if (r < 0)
- return log_error_errno(r, "Failed to build directory list: %m");
- }
-
- r = conf_files_list_strv(&files, ".conf", root, 0, (const char* const*) dirs);
- if (r < 0)
- return log_error_errno(r, "Failed to query file list: %m");
-
- path = path_join(root, "/etc", name);
- if (!path)
- return log_oom();
-
- if (DEBUG_LOGGING) {
- log_debug("Looking for configuration in:");
- log_debug(" %s", path);
- STRV_FOREACH(t, dirs)
- log_debug(" %s/*.conf", *t);
- }
-
- /* show */
- return cat_files(path, files, CAT_FLAGS_MAIN_FILE_OPTIONAL);
-}
diff --git a/src/basic/conf-files.h b/src/basic/conf-files.h
index 81ebcd46b6..f31f17de9d 100644
--- a/src/basic/conf-files.h
+++ b/src/basic/conf-files.h
@@ -22,4 +22,3 @@ int conf_files_list_with_replacement(
const char *replacement,
char ***files,
char **replace_file);
-int conf_files_cat(const char *root, const char *name);
diff --git a/src/basic/main-func.h b/src/basic/main-func.h
deleted file mode 100644
index 24bf6c99bf..0000000000
--- a/src/basic/main-func.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdlib.h>
-
-#include "pager.h"
-#include "static-destruct.h"
-
-#define _DEFINE_MAIN_FUNCTION(impl, ret) \
- int main(int argc, char *argv[]) { \
- int r; \
- r = impl(argc, argv); \
- static_destruct(); \
- pager_close(); \
- return ret; \
- }
-
-/* Negative return values from impl are mapped to EXIT_FAILURE, and
- * everything else means success! */
-#define DEFINE_MAIN_FUNCTION(impl) \
- _DEFINE_MAIN_FUNCTION(impl, r < 0 ? EXIT_FAILURE : EXIT_SUCCESS)
-
-/* Zero is mapped to EXIT_SUCCESS, negative values are mapped to EXIT_FAILURE,
- * and postive values are propagated.
- * Note: "true" means failure! */
-#define DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(impl) \
- _DEFINE_MAIN_FUNCTION(impl, r < 0 ? EXIT_FAILURE : r)
diff --git a/src/basic/meson.build b/src/basic/meson.build
index abd54db8cc..0b27ffda7d 100644
--- a/src/basic/meson.build
+++ b/src/basic/meson.build
@@ -99,8 +99,6 @@ basic_sources = files('''
nss-util.h
ordered-set.c
ordered-set.h
- pager.c
- pager.h
parse-util.c
parse-util.h
path-util.c
diff --git a/src/basic/pager.c b/src/basic/pager.c
deleted file mode 100644
index 88d9ef349e..0000000000
--- a/src/basic/pager.c
+++ /dev/null
@@ -1,270 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-
-#include <errno.h>
-#include <signal.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/prctl.h>
-#include <unistd.h>
-
-#include "copy.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "io-util.h"
-#include "locale-util.h"
-#include "log.h"
-#include "macro.h"
-#include "pager.h"
-#include "process-util.h"
-#include "signal-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "terminal-util.h"
-
-static pid_t pager_pid = 0;
-
-static int stored_stdout = -1;
-static int stored_stderr = -1;
-static bool stdout_redirected = false;
-static bool stderr_redirected = false;
-
-_noreturn_ static void pager_fallback(void) {
- int r;
-
- r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (uint64_t) -1, 0);
- if (r < 0) {
- log_error_errno(r, "Internal pager failed: %m");
- _exit(EXIT_FAILURE);
- }
-
- _exit(EXIT_SUCCESS);
-}
-
-static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) {
- _cleanup_fclose_ FILE *file = NULL;
- _cleanup_free_ char *line = NULL;
- int r;
-
- assert(exe_name_fd >= 0);
- assert(less_opts);
-
- /* This takes ownership of exe_name_fd */
- file = fdopen(exe_name_fd, "r");
- if (!file) {
- safe_close(exe_name_fd);
- return log_debug_errno(errno, "Failed to create FILE object: %m");
- }
-
- /* Find the last line */
- for (;;) {
- _cleanup_free_ char *t = NULL;
-
- r = read_line(file, LONG_LINE_MAX, &t);
- if (r < 0)
- return r;
- if (r == 0)
- break;
-
- free_and_replace(line, t);
- }
-
- /* We only treat "less" specially.
- * Return true whenever option K is *not* set. */
- r = streq_ptr(line, "less") && !strchr(less_opts, 'K');
-
- log_debug("Pager executable is \"%s\", options \"%s\", quit_on_interrupt: %s",
- strnull(line), less_opts, yes_no(!r));
- return r;
-}
-
-int pager_open(PagerFlags flags) {
- _cleanup_close_pair_ int fd[2] = { -1, -1 }, exe_name_pipe[2] = { -1, -1 };
- _cleanup_strv_free_ char **pager_args = NULL;
- const char *pager, *less_opts;
- int r;
-
- if (flags & PAGER_DISABLE)
- return 0;
-
- if (pager_pid > 0)
- return 1;
-
- if (terminal_is_dumb())
- return 0;
-
- if (!is_main_thread())
- return -EPERM;
-
- pager = getenv("SYSTEMD_PAGER");
- if (!pager)
- pager = getenv("PAGER");
-
- if (pager) {
- pager_args = strv_split(pager, WHITESPACE);
- if (!pager_args)
- return -ENOMEM;
-
- /* If the pager is explicitly turned off, honour it */
- if (strv_isempty(pager_args) || strv_equal(pager_args, STRV_MAKE("cat")))
- return 0;
- }
-
- /* Determine and cache number of columns/lines before we spawn the pager so that we get the value from the
- * actual tty */
- (void) columns();
- (void) lines();
-
- if (pipe2(fd, O_CLOEXEC) < 0)
- return log_error_errno(errno, "Failed to create pager pipe: %m");
-
- /* This is a pipe to feed the name of the executed pager binary into the parent */
- if (pipe2(exe_name_pipe, O_CLOEXEC) < 0)
- return log_error_errno(errno, "Failed to create exe_name pipe: %m");
-
- /* Initialize a good set of less options */
- less_opts = getenv("SYSTEMD_LESS");
- if (!less_opts)
- less_opts = "FRSXMK";
- if (flags & PAGER_JUMP_TO_END)
- less_opts = strjoina(less_opts, " +G");
-
- r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG|FORK_LOG, &pager_pid);
- if (r < 0)
- return r;
- if (r == 0) {
- const char *less_charset, *exe;
-
- /* In the child start the pager */
-
- (void) dup2(fd[0], STDIN_FILENO);
- safe_close_pair(fd);
-
- if (setenv("LESS", less_opts, 1) < 0)
- _exit(EXIT_FAILURE);
-
- /* Initialize a good charset for less. This is
- * particularly important if we output UTF-8
- * characters. */
- less_charset = getenv("SYSTEMD_LESSCHARSET");
- if (!less_charset && is_locale_utf8())
- less_charset = "utf-8";
- if (less_charset &&
- setenv("LESSCHARSET", less_charset, 1) < 0)
- _exit(EXIT_FAILURE);
-
- if (pager_args) {
- if (loop_write(exe_name_pipe[1], pager_args[0], strlen(pager_args[0]) + 1, false) < 0)
- _exit(EXIT_FAILURE);
-
- execvp(pager_args[0], pager_args);
- }
-
- /* Debian's alternatives command for pagers is
- * called 'pager'. Note that we do not call
- * sensible-pagers here, since that is just a
- * shell script that implements a logic that
- * is similar to this one anyway, but is
- * Debian-specific. */
- FOREACH_STRING(exe, "pager", "less", "more") {
- if (loop_write(exe_name_pipe[1], exe, strlen(exe) + 1, false) < 0)
- _exit(EXIT_FAILURE);
- execlp(exe, exe, NULL);
- }
-
- if (loop_write(exe_name_pipe[1], "(built-in)", strlen("(built-in") + 1, false) < 0)
- _exit(EXIT_FAILURE);
- pager_fallback();
- /* not reached */
- }
-
- /* Return in the parent */
- stored_stdout = fcntl(STDOUT_FILENO, F_DUPFD_CLOEXEC, 3);
- if (dup2(fd[1], STDOUT_FILENO) < 0) {
- stored_stdout = safe_close(stored_stdout);
- return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
- }
- stdout_redirected = true;
-
- stored_stderr = fcntl(STDERR_FILENO, F_DUPFD_CLOEXEC, 3);
- if (dup2(fd[1], STDERR_FILENO) < 0) {
- stored_stderr = safe_close(stored_stderr);
- return log_error_errno(errno, "Failed to duplicate pager pipe: %m");
- }
- stderr_redirected = true;
-
- exe_name_pipe[1] = safe_close(exe_name_pipe[1]);
-
- r = no_quit_on_interrupt(TAKE_FD(exe_name_pipe[0]), less_opts);
- if (r < 0)
- return r;
- if (r > 0)
- (void) ignore_signals(SIGINT, -1);
-
- return 1;
-}
-
-void pager_close(void) {
-
- if (pager_pid <= 0)
- return;
-
- /* Inform pager that we are done */
- (void) fflush(stdout);
- if (stdout_redirected)
- if (stored_stdout < 0 || dup2(stored_stdout, STDOUT_FILENO) < 0)
- (void) close(STDOUT_FILENO);
- stored_stdout = safe_close(stored_stdout);
- (void) fflush(stderr);
- if (stderr_redirected)
- if (stored_stderr < 0 || dup2(stored_stderr, STDERR_FILENO) < 0)
- (void) close(STDERR_FILENO);
- stored_stderr = safe_close(stored_stderr);
- stdout_redirected = stderr_redirected = false;
-
- (void) kill(pager_pid, SIGCONT);
- (void) wait_for_terminate(pager_pid, NULL);
- pager_pid = 0;
-}
-
-bool pager_have(void) {
- return pager_pid > 0;
-}
-
-int show_man_page(const char *desc, bool null_stdio) {
- const char *args[4] = { "man", NULL, NULL, NULL };
- char *e = NULL;
- pid_t pid;
- size_t k;
- int r;
-
- k = strlen(desc);
-
- if (desc[k-1] == ')')
- e = strrchr(desc, '(');
-
- if (e) {
- char *page = NULL, *section = NULL;
-
- page = strndupa(desc, e - desc);
- section = strndupa(e + 1, desc + k - e - 2);
-
- args[1] = section;
- args[2] = page;
- } else
- args[1] = desc;
-
- r = safe_fork("(man)", FORK_RESET_SIGNALS|FORK_DEATHSIG|(null_stdio ? FORK_NULL_STDIO : 0)|FORK_LOG, &pid);
- if (r < 0)
- return r;
- if (r == 0) {
- /* Child */
- execvp(args[0], (char**) args);
- log_error_errno(errno, "Failed to execute man: %m");
- _exit(EXIT_FAILURE);
- }
-
- return wait_for_terminate_and_check(NULL, pid, 0);
-}
diff --git a/src/basic/pager.h b/src/basic/pager.h
deleted file mode 100644
index 8299e23856..0000000000
--- a/src/basic/pager.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
-#pragma once
-
-#include <stdbool.h>
-
-#include "macro.h"
-
-typedef enum PagerFlags {
- PAGER_DISABLE = 1 << 0,
- PAGER_JUMP_TO_END = 1 << 1,
-} PagerFlags;
-
-int pager_open(PagerFlags flags);
-void pager_close(void);
-bool pager_have(void) _pure_;
-
-int show_man_page(const char *page, bool null_stdio);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 41789598f7..2c7b4508ce 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -32,7 +32,6 @@
#include "io-util.h"
#include "log.h"
#include "macro.h"
-#include "pager.h"
#include "parse-util.h"
#include "path-util.h"
#include "proc-cmdline.h"
@@ -1272,184 +1271,3 @@ int vt_reset_keyboard(int fd) {
return 0;
}
-
-static bool urlify_enabled(void) {
- static int cached_urlify_enabled = -1;
-
- /* Unfortunately 'less' doesn't support links like this yet 😭, hence let's disable this as long as there's a
- * pager in effect. Let's drop this check as soon as less got fixed a and enough time passed so that it's safe
- * to assume that a link-enabled 'less' version has hit most installations. */
-
- if (cached_urlify_enabled < 0) {
- int val;
-
- val = getenv_bool("SYSTEMD_URLIFY");
- if (val >= 0)
- cached_urlify_enabled = val;
- else
- cached_urlify_enabled = colors_enabled() && !pager_have();
- }
-
- return cached_urlify_enabled;
-}
-
-int terminal_urlify(const char *url, const char *text, char **ret) {
- char *n;
-
- assert(url);
-
- /* Takes an URL and a pretty string and formats it as clickable link for the terminal. See
- * https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda for details. */
-
- if (isempty(text))
- text = url;
-
- if (urlify_enabled())
- n = strjoin("\x1B]8;;", url, "\a", text, "\x1B]8;;\a");
- else
- n = strdup(text);
- if (!n)
- return -ENOMEM;
-
- *ret = n;
- return 0;
-}
-
-int terminal_urlify_path(const char *path, const char *text, char **ret) {
- _cleanup_free_ char *absolute = NULL;
- struct utsname u;
- const char *url;
- int r;
-
- assert(path);
-
- /* Much like terminal_urlify() above, but takes a file system path as input
- * and turns it into a proper file:// URL first. */
-
- if (isempty(path))
- return -EINVAL;
-
- if (isempty(text))
- text = path;
-
- if (!urlify_enabled()) {
- char *n;
-
- n = strdup(text);
- if (!n)
- return -ENOMEM;
-
- *ret = n;
- return 0;
- }
-
- if (uname(&u) < 0)
- return -errno;
-
- if (!path_is_absolute(path)) {
- r = path_make_absolute_cwd(path, &absolute);
- if (r < 0)
- return r;
-
- path = absolute;
- }
-
- /* As suggested by https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda, let's include the local
- * hostname here. Note that we don't use gethostname_malloc() or gethostname_strict() since we are interested
- * in the raw string the kernel has set, whatever it may be, under the assumption that terminals are not overly
- * careful with validating the strings either. */
-
- url = strjoina("file://", u.nodename, path);
-
- return terminal_urlify(url, text, ret);
-}
-
-int terminal_urlify_man(const char *page, const char *section, char **ret) {
- const char *url, *text;
-
- url = strjoina("man:", page, "(", section, ")");
- text = strjoina(page, "(", section, ") man page");
-
- return terminal_urlify(url, text, ret);
-}
-
-static int cat_file(const char *filename, bool newline) {
- _cleanup_fclose_ FILE *f = NULL;
- _cleanup_free_ char *urlified = NULL;
- int r;
-
- f = fopen(filename, "re");
- if (!f)
- return -errno;
-
- r = terminal_urlify_path(filename, NULL, &urlified);
- if (r < 0)
- return r;
-
- printf("%s%s# %s%s\n",
- newline ? "\n" : "",
- ansi_highlight_blue(),
- urlified,
- ansi_normal());
- fflush(stdout);
-
- for (;;) {
- _cleanup_free_ char *line = NULL;
-
- r = read_line(f, LONG_LINE_MAX, &line);
- if (r < 0)
- return log_error_errno(r, "Failed to read \"%s\": %m", filename);
- if (r == 0)
- break;
-
- puts(line);
- }
-
- return 0;
-}
-
-int cat_files(const char *file, char **dropins, CatFlags flags) {
- char **path;
- int r;
-
- if (file) {
- r = cat_file(file, false);
- if (r == -ENOENT && (flags & CAT_FLAGS_MAIN_FILE_OPTIONAL))
- printf("%s# config file %s not found%s\n",
- ansi_highlight_magenta(),
- file,
- ansi_normal());
- else if (r < 0)
- return log_warning_errno(r, "Failed to cat %s: %m", file);
- }
-
- STRV_FOREACH(path, dropins) {
- r = cat_file(*path, file || path != dropins);
- if (r < 0)
- return log_warning_errno(r, "Failed to cat %s: %m", *path);
- }
-
- return 0;
-}
-
-void print_separator(void) {
-
- /* Outputs a separator line that resolves to whitespace when copied from the terminal. We do that by outputting
- * one line filled with spaces with ANSI underline set, followed by a second (empty) line. */
-
- if (underline_enabled()) {
- size_t i, c;
-
- c = columns();
-
- flockfile(stdout);
- fputs_unlocked(ANSI_UNDERLINE, stdout);
-
- for (i = 0; i < c; i++)
- fputc_unlocked(' ', stdout);
-
- fputs_unlocked(ANSI_NORMAL "\n\n", stdout);
- funlockfile(stdout);
- } else
- fputs("\n\n", stdout);
-}
diff --git a/src/basic/terminal-util.h b/src/basic/terminal-util.h
index 436951be98..2d64afaee6 100644
--- a/src/basic/terminal-util.h
+++ b/src/basic/terminal-util.h
@@ -154,15 +154,3 @@ int open_terminal_in_namespace(pid_t pid, const char *name, int mode);
int vt_default_utf8(void);
int vt_reset_keyboard(int fd);
-
-int terminal_urlify(const char *url, const char *text, char **ret);
-int terminal_urlify_path(const char *path, const char *text, char **ret);
-int terminal_urlify_man(const char *page, const char *section, char **ret);
-
-typedef enum CatFlags {
- CAT_FLAGS_MAIN_FILE_OPTIONAL = 1 << 0,
-} CatFlags;
-
-int cat_files(const char *file, char **dropins, CatFlags flags);
-
-void print_separator(void);