chiark / gitweb /
nss-myhostname: ensure that glibc's assert is used
[elogind.git] / src / cgls / cgls.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <limits.h>
23 #include <stdio.h>
24 #include <unistd.h>
25 #include <errno.h>
26 #include <getopt.h>
27 #include <string.h>
28
29 #include "cgroup-show.h"
30 #include "cgroup-util.h"
31 #include "log.h"
32 #include "path-util.h"
33 #include "util.h"
34 #include "pager.h"
35 #include "build.h"
36 #include "output-mode.h"
37
38 static bool arg_no_pager = false;
39 static bool arg_kernel_threads = false;
40 static bool arg_all = false;
41 static int arg_full = -1;
42
43 static void help(void) {
44
45         printf("%s [OPTIONS...] [CGROUP...]\n\n"
46                "Recursively show control group contents.\n\n"
47                "  -h --help           Show this help\n"
48                "     --version        Show package version\n"
49                "     --no-pager       Do not pipe output into a pager\n"
50                "  -a --all            Show all groups, including empty\n"
51                "  --full              Do not ellipsize output\n"
52                "  -k                  Include kernel threads in output\n",
53                program_invocation_short_name);
54 }
55
56 static int parse_argv(int argc, char *argv[]) {
57
58         enum {
59                 ARG_NO_PAGER = 0x100,
60                 ARG_VERSION,
61                 ARG_FULL,
62         };
63
64         static const struct option options[] = {
65                 { "help",      no_argument,       NULL, 'h'          },
66                 { "version",   no_argument,       NULL, ARG_VERSION  },
67                 { "no-pager",  no_argument,       NULL, ARG_NO_PAGER },
68                 { "all",       no_argument,       NULL, 'a'          },
69                 { "full",      no_argument,       NULL, ARG_FULL     },
70                 { NULL,        0,                 NULL, 0            }
71         };
72
73         int c;
74
75         assert(argc >= 1);
76         assert(argv);
77
78         while ((c = getopt_long(argc, argv, "hka", options, NULL)) >= 0) {
79
80                 switch (c) {
81
82                 case 'h':
83                         help();
84                         return 0;
85
86                 case ARG_VERSION:
87                         puts(PACKAGE_STRING);
88                         puts(SYSTEMD_FEATURES);
89                         return 0;
90
91                 case ARG_NO_PAGER:
92                         arg_no_pager = true;
93                         break;
94
95                 case 'a':
96                         arg_all = true;
97                         break;
98
99                 case ARG_FULL:
100                         arg_full = true;
101                         break;
102
103                 case 'k':
104                         arg_kernel_threads = true;
105                         break;
106
107                 case '?':
108                         return -EINVAL;
109
110                 default:
111                         log_error("Unknown option code %c", c);
112                         return -EINVAL;
113                 }
114         }
115
116         return 1;
117 }
118
119 int main(int argc, char *argv[]) {
120         int r = 0, retval = EXIT_FAILURE;
121         int output_flags;
122
123         log_parse_environment();
124         log_open();
125
126         r = parse_argv(argc, argv);
127         if (r < 0)
128                 goto finish;
129         else if (r == 0) {
130                 retval = EXIT_SUCCESS;
131                 goto finish;
132         }
133
134         if (!arg_no_pager) {
135                 r = pager_open(false);
136                 if (r > 0) {
137                         if (arg_full == -1)
138                                 arg_full = true;
139                 }
140         }
141
142         output_flags =
143                 arg_all * OUTPUT_SHOW_ALL |
144                 (arg_full > 0) * OUTPUT_FULL_WIDTH;
145
146         if (optind < argc) {
147                 unsigned i;
148
149                 for (i = (unsigned) optind; i < (unsigned) argc; i++) {
150                         int q;
151                         printf("%s:\n", argv[i]);
152
153                         q = show_cgroup_by_path(argv[i], NULL, 0,
154                                                 arg_kernel_threads, output_flags);
155                         if (q < 0)
156                                 r = q;
157                 }
158
159         } else {
160                 _cleanup_free_ char *p;
161
162                 p = get_current_dir_name();
163                 if (!p) {
164                         log_error("Cannot determine current working directory: %m");
165                         goto finish;
166                 }
167
168                 if (path_startswith(p, "/sys/fs/cgroup")) {
169                         printf("Working Directory %s:\n", p);
170                         r = show_cgroup_by_path(p, NULL, 0,
171                                                 arg_kernel_threads, output_flags);
172                 } else {
173                         _cleanup_free_ char *root = NULL;
174
175                         r = cg_get_root_path(&root);
176                         if (r < 0) {
177                                 log_error("Failed to get root path: %s", strerror(-r));
178                                 goto finish;
179                         }
180
181                         r = show_cgroup(SYSTEMD_CGROUP_CONTROLLER, root, NULL, 0,
182                                         arg_kernel_threads, output_flags);
183                 }
184         }
185
186         if (r < 0)
187                 log_error("Failed to list cgroup tree: %s", strerror(-r));
188
189         retval = EXIT_SUCCESS;
190
191 finish:
192         pager_close();
193
194         return retval;
195 }