]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/machine/machinectl.c
coccinelle: make use of SYNTHETIC_ERRNO
[thirdparty/systemd.git] / src / machine / machinectl.c
index 47ccb352bf2549c6439e857c7bf24b797787aeb3..094ee9d360e508f7133241e69ec3b69dd7c689de 100644 (file)
@@ -22,6 +22,7 @@
 #include "cgroup-show.h"
 #include "cgroup-util.h"
 #include "copy.h"
+#include "def.h"
 #include "env-util.h"
 #include "fd-util.h"
 #include "format-table.h"
 #include "log.h"
 #include "logs-show.h"
 #include "macro.h"
+#include "main-func.h"
 #include "mkdir.h"
 #include "pager.h"
 #include "parse-util.h"
 #include "path-util.h"
+#include "pretty-print.h"
 #include "process-util.h"
 #include "ptyfwd.h"
+#include "rlimit-util.h"
 #include "sigbus.h"
 #include "signal-util.h"
 #include "spawn-polkit-agent.h"
@@ -55,12 +59,12 @@ static char **arg_property = NULL;
 static bool arg_all = false;
 static bool arg_value = false;
 static bool arg_full = false;
-static bool arg_no_pager = false;
+static PagerFlags arg_pager_flags = 0;
 static bool arg_legend = true;
 static const char *arg_kill_who = NULL;
 static int arg_signal = SIGTERM;
 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
-static char *arg_host = NULL;
+static const char *arg_host = NULL;
 static bool arg_read_only = false;
 static bool arg_mkdir = false;
 static bool arg_quiet = false;
@@ -74,6 +78,9 @@ static const char *arg_uid = NULL;
 static char **arg_setenv = NULL;
 static int arg_addrs = 1;
 
+STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
+STATIC_DESTRUCTOR_REGISTER(arg_setenv, strv_freep);
+
 static OutputFlags get_output_flags(void) {
         return
                 arg_all * OUTPUT_SHOW_ALL |
@@ -276,7 +283,7 @@ static int list_machines(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        (void) pager_open(arg_no_pager, false);
+        (void) pager_open(arg_pager_flags);
 
         r = sd_bus_call_method(bus,
                                "org.freedesktop.machine1",
@@ -356,7 +363,7 @@ static int list_images(int argc, char *argv[], void *userdata) {
 
         assert(bus);
 
-        (void) pager_open(arg_no_pager, false);
+        (void) pager_open(arg_pager_flags);
 
         r = sd_bus_call_method(bus,
                                "org.freedesktop.machine1",
@@ -540,7 +547,7 @@ typedef struct MachineStatusInfo {
         pid_t leader;
         struct dual_timestamp timestamp;
         int *netif;
-        unsigned n_netif;
+        size_t n_netif;
 } MachineStatusInfo;
 
 static void machine_status_info_clear(MachineStatusInfo *info) {
@@ -600,7 +607,7 @@ static void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
                 printf("\t    Root: %s\n", i->root_directory);
 
         if (i->n_netif > 0) {
-                unsigned c;
+                size_t c;
 
                 fputs("\t   Iface:", stdout);
 
@@ -751,7 +758,7 @@ static int show_machine(int argc, char *argv[], void *userdata) {
 
         properties = !strstr(argv[0], "status");
 
-        (void) pager_open(arg_no_pager, false);
+        (void) pager_open(arg_pager_flags);
 
         if (properties && argc <= 1) {
 
@@ -1089,7 +1096,7 @@ static int show_image(int argc, char *argv[], void *userdata) {
 
         properties = !strstr(argv[0], "status");
 
-        (void) pager_open(arg_no_pager, false);
+        (void) pager_open(arg_pager_flags);
 
         if (argc <= 1) {
 
@@ -1325,8 +1332,8 @@ static int process_forward(sd_event *event, PTYForward **forward, int master, PT
                         log_info("Connected to machine %s. Press ^] three times within 1s to exit session.", name);
         }
 
-        sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
-        sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
+        (void) sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
+        (void) sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
 
         r = pty_forward_new(event, master, flags, forward);
         if (r < 0)
@@ -1703,10 +1710,9 @@ static int make_service_name(const char *name, char **ret) {
         assert(name);
         assert(ret);
 
-        if (!machine_name_is_valid(name)) {
-                log_error("Invalid machine name %s.", name);
-                return -EINVAL;
-        }
+        if (!machine_name_is_valid(name))
+                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                       "Invalid machine name %s.", name);
 
         r = unit_name_build("systemd-nspawn", name, ".service", ret);
         if (r < 0)
@@ -1983,8 +1989,8 @@ static int transfer_image_common(sd_bus *bus, sd_bus_message *m) {
         if (!arg_quiet)
                 log_info("Enqueued transfer job %u. Press C-c to continue download in background.", id);
 
-        sd_event_add_signal(event, NULL, SIGINT, transfer_signal_handler, UINT32_TO_PTR(id));
-        sd_event_add_signal(event, NULL, SIGTERM, transfer_signal_handler, UINT32_TO_PTR(id));
+        (void) sd_event_add_signal(event, NULL, SIGINT, transfer_signal_handler, UINT32_TO_PTR(id));
+        (void) sd_event_add_signal(event, NULL, SIGTERM, transfer_signal_handler, UINT32_TO_PTR(id));
 
         r = sd_event_loop(event);
         if (r < 0)
@@ -2394,7 +2400,7 @@ static int list_transfers(int argc, char *argv[], void *userdata) {
         double progress;
         int r;
 
-        (void) pager_open(arg_no_pager, false);
+        (void) pager_open(arg_pager_flags);
 
         r = sd_bus_call_method(bus,
                                "org.freedesktop.import1",
@@ -2610,7 +2616,7 @@ static int help(int argc, char *argv[], void *userdata) {
         _cleanup_free_ char *link = NULL;
         int r;
 
-        (void) pager_open(arg_no_pager, false);
+        (void) pager_open(arg_pager_flags);
 
         r = terminal_urlify_man("machinectl", "1", &link);
         if (r < 0)
@@ -2642,7 +2648,8 @@ static int help(int argc, char *argv[], void *userdata) {
                "  -o --output=STRING          Change journal output mode (short, short-precise,\n"
                "                               short-iso, short-iso-precise, short-full,\n"
                "                               short-monotonic, short-unix, verbose, export,\n"
-               "                               json, json-pretty, json-sse, cat)\n"
+               "                               json, json-pretty, json-sse, json-seq, cat,\n"
+               "                               with-unit)\n"
                "     --verify=MODE            Verification mode for downloaded images (no,\n"
                "                              checksum, signature)\n"
                "     --force                  Download image even if already exists\n\n"
@@ -2829,10 +2836,9 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'n':
-                        if (safe_atou(optarg, &arg_lines) < 0) {
-                                log_error("Failed to parse lines '%s'", optarg);
-                                return -EINVAL;
-                        }
+                        if (safe_atou(optarg, &arg_lines) < 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Failed to parse lines '%s'", optarg);
                         break;
 
                 case 'o':
@@ -2842,14 +2848,13 @@ static int parse_argv(int argc, char *argv[]) {
                         }
 
                         arg_output = output_mode_from_string(optarg);
-                        if (arg_output < 0) {
-                                log_error("Unknown output '%s'.", optarg);
-                                return -EINVAL;
-                        }
+                        if (arg_output < 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Unknown output '%s'.", optarg);
                         break;
 
                 case ARG_NO_PAGER:
-                        arg_no_pager = true;
+                        arg_pager_flags |= PAGER_DISABLE;
                         break;
 
                 case ARG_NO_LEGEND:
@@ -2867,10 +2872,9 @@ static int parse_argv(int argc, char *argv[]) {
                         }
 
                         arg_signal = signal_from_string(optarg);
-                        if (arg_signal < 0) {
-                                log_error("Failed to parse signal string %s.", optarg);
-                                return -EINVAL;
-                        }
+                        if (arg_signal < 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Failed to parse signal string %s.", optarg);
                         break;
 
                 case ARG_NO_ASK_PASSWORD:
@@ -2906,10 +2910,9 @@ static int parse_argv(int argc, char *argv[]) {
                         }
 
                         arg_verify = import_verify_from_string(optarg);
-                        if (arg_verify < 0) {
-                                log_error("Failed to parse --verify= setting: %s", optarg);
-                                return -EINVAL;
-                        }
+                        if (arg_verify < 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Failed to parse --verify= setting: %s", optarg);
                         break;
 
                 case ARG_FORCE:
@@ -2917,10 +2920,9 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_FORMAT:
-                        if (!STR_IN_SET(optarg, "uncompressed", "xz", "gzip", "bzip2")) {
-                                log_error("Unknown format: %s", optarg);
-                                return -EINVAL;
-                        }
+                        if (!STR_IN_SET(optarg, "uncompressed", "xz", "gzip", "bzip2"))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Unknown format: %s", optarg);
 
                         arg_format = optarg;
                         break;
@@ -2930,10 +2932,9 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'E':
-                        if (!env_assignment_is_valid(optarg)) {
-                                log_error("Environment assignment invalid: %s", optarg);
-                                return -EINVAL;
-                        }
+                        if (!env_assignment_is_valid(optarg))
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Environment assignment invalid: %s", optarg);
 
                         r = strv_extend(&arg_setenv, optarg);
                         if (r < 0)
@@ -2943,13 +2944,12 @@ static int parse_argv(int argc, char *argv[]) {
                 case ARG_NUMBER_IPS:
                         if (streq(optarg, "all"))
                                 arg_addrs = ALL_IP_ADDRESSES;
-                        else if (safe_atoi(optarg, &arg_addrs) < 0) {
-                                log_error("Invalid number of IPs");
-                                return -EINVAL;
-                        } else if (arg_addrs < 0) {
-                                log_error("Number of IPs cannot be negative");
-                                return -EINVAL;
-                        }
+                        else if (safe_atoi(optarg, &arg_addrs) < 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Invalid number of IPs");
+                        else if (arg_addrs < 0)
+                                return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+                                                       "Number of IPs cannot be negative");
                         break;
 
                 case '?':
@@ -3022,38 +3022,30 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) {
         return dispatch_verb(argc, argv, verbs, bus);
 }
 
-int main(int argc, char*argv[]) {
-        sd_bus *bus = NULL;
+static int run(int argc, char*argv[]) {
+        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
         int r;
 
         setlocale(LC_ALL, "");
         log_parse_environment();
         log_open();
+
+        /* The journal merging logic potentially needs a lot of fds. */
+        (void) rlimit_nofile_bump(HIGH_RLIMIT_NOFILE);
+
         sigbus_install();
 
         r = parse_argv(argc, argv);
         if (r <= 0)
-                goto finish;
+                return r;
 
         r = bus_connect_transport(arg_transport, arg_host, false, &bus);
-        if (r < 0) {
-                log_error_errno(r, "Failed to create bus connection: %m");
-                goto finish;
-        }
+        if (r < 0)
+                return log_error_errno(r, "Failed to create bus connection: %m");
 
         (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
 
-        r = machinectl_main(argc, argv, bus);
-
-finish:
-        /* make sure we terminate the bus connection first, and then close the
-         * pager, see issue #3543 for the details. */
-        sd_bus_flush_close_unref(bus);
-        pager_close();
-        polkit_agent_close();
-
-        strv_free(arg_property);
-        strv_free(arg_setenv);
-
-        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+        return machinectl_main(argc, argv, bus);
 }
+
+DEFINE_MAIN_FUNCTION(run);