]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - sys-utils/prlimit.c
misc: consolidate smartcols error messages
[thirdparty/util-linux.git] / sys-utils / prlimit.c
index 9098e49760fd6fefc1ff5a2090ce8f964ebe8e7a..a62d457feb8875ca6ff2f0d31d89c6a5ca0baaaa 100644 (file)
 #include <unistd.h>
 #include <sys/resource.h>
 
+#include <libsmartcols.h>
+
 #include "c.h"
 #include "nls.h"
-#include "tt.h"
 #include "xalloc.h"
 #include "strutils.h"
 #include "list.h"
@@ -58,6 +59,10 @@ enum {
        STACK
 };
 
+/* basic output flags */
+static int no_headings;
+static int raw;
+
 struct prlimit_desc {
        const char *name;
        const char *help;
@@ -68,23 +73,25 @@ struct prlimit_desc {
 static struct prlimit_desc prlimit_desc[] =
 {
        [AS]         = { "AS",         N_("address space limit"),                N_("bytes"),     RLIMIT_AS },
-       [CORE]       = { "CORE",       N_("max core file size"),                 N_("blocks"),    RLIMIT_CORE },
+       [CORE]       = { "CORE",       N_("max core file size"),                 N_("bytes"),     RLIMIT_CORE },
        [CPU]        = { "CPU",        N_("CPU time"),                           N_("seconds"),   RLIMIT_CPU },
        [DATA]       = { "DATA",       N_("max data size"),                      N_("bytes"),     RLIMIT_DATA },
-       [FSIZE]      = { "FSIZE",      N_("max file size"),                      N_("blocks"),    RLIMIT_FSIZE },
-       [LOCKS]      = { "LOCKS",      N_("max number of file locks held"),      NULL,            RLIMIT_LOCKS },
+       [FSIZE]      = { "FSIZE",      N_("max file size"),                      N_("bytes"),     RLIMIT_FSIZE },
+       [LOCKS]      = { "LOCKS",      N_("max number of file locks held"),      N_("locks"),     RLIMIT_LOCKS },
        [MEMLOCK]    = { "MEMLOCK",    N_("max locked-in-memory address space"), N_("bytes"),     RLIMIT_MEMLOCK },
        [MSGQUEUE]   = { "MSGQUEUE",   N_("max bytes in POSIX mqueues"),         N_("bytes"),     RLIMIT_MSGQUEUE },
        [NICE]       = { "NICE",       N_("max nice prio allowed to raise"),     NULL,            RLIMIT_NICE },
-       [NOFILE]     = { "NOFILE",     N_("max number of open files"),           NULL,            RLIMIT_NOFILE },
-       [NPROC]      = { "NPROC",      N_("max number of processes"),            NULL,            RLIMIT_NPROC },
-       [RSS]        = { "RSS",        N_("max resident set size"),              N_("pages"),     RLIMIT_RSS },
+       [NOFILE]     = { "NOFILE",     N_("max number of open files"),           N_("files"),     RLIMIT_NOFILE },
+       [NPROC]      = { "NPROC",      N_("max number of processes"),            N_("processes"), RLIMIT_NPROC },
+       [RSS]        = { "RSS",        N_("max resident set size"),              N_("bytes"),     RLIMIT_RSS },
        [RTPRIO]     = { "RTPRIO",     N_("max real-time priority"),             NULL,            RLIMIT_RTPRIO },
        [RTTIME]     = { "RTTIME",     N_("timeout for real-time tasks"),        N_("microsecs"), RLIMIT_RTTIME },
-       [SIGPENDING] = { "SIGPENDING", N_("max number of pending signals"),      NULL,            RLIMIT_SIGPENDING },
+       [SIGPENDING] = { "SIGPENDING", N_("max number of pending signals"),      N_("signals"),   RLIMIT_SIGPENDING },
        [STACK]      = { "STACK",      N_("max stack size"),                     N_("bytes"),     RLIMIT_STACK }
 };
 
+#define MAX_RESOURCES ARRAY_SIZE(prlimit_desc)
+
 struct prlimit {
        struct list_head lims;
 
@@ -107,21 +114,23 @@ enum {
 struct colinfo {
        const char      *name;  /* header */
        double          whint;  /* width hint (N < 1 is in percent of termwidth) */
-       int             flags;  /* TT_FL_* */
+       int             flags;  /* SCOLS_FL_* */
        const char      *help;
 };
 
 /* columns descriptions */
-struct colinfo infos[] = {
-       [COL_RES]     = { "RESOURCE",    0.25, TT_FL_TRUNC, N_("resource name") },
-       [COL_HELP]    = { "DESCRIPTION", 0.1,  TT_FL_TRUNC, N_("resource description")},
-       [COL_SOFT]    = { "SOFT",        0.1,  TT_FL_RIGHT, N_("soft limit")},
-       [COL_HARD]    = { "HARD",        1,    TT_FL_RIGHT, N_("hard limit (ceiling)")},
-       [COL_UNITS]   = { "UNITS",       0.1,  TT_FL_TRUNC, N_("units")},
+static struct colinfo infos[] = {
+       [COL_RES]     = { "RESOURCE",    0.25, SCOLS_FL_TRUNC, N_("resource name") },
+       [COL_HELP]    = { "DESCRIPTION", 0.1,  SCOLS_FL_TRUNC, N_("resource description")},
+       [COL_SOFT]    = { "SOFT",        0.1,  SCOLS_FL_RIGHT, N_("soft limit")},
+       [COL_HARD]    = { "HARD",        1,    SCOLS_FL_RIGHT, N_("hard limit (ceiling)")},
+       [COL_UNITS]   = { "UNITS",       0.1,  SCOLS_FL_TRUNC, N_("units")},
 };
 
-#define NCOLS ARRAY_SIZE(infos)
-#define MAX_RESOURCES ARRAY_SIZE(prlimit_desc)
+static int columns[ARRAY_SIZE(infos) * 2];
+static int ncolumns;
+
+
 
 #define INFINITY_STR   "unlimited"
 #define INFINITY_STRLEN        (sizeof(INFINITY_STR) - 1)
@@ -129,8 +138,6 @@ struct colinfo infos[] = {
 #define PRLIMIT_SOFT   (1 << 1)
 #define PRLIMIT_HARD   (1 << 2)
 
-/* array with IDs of enabled columns */
-static int columns[NCOLS], ncolumns;
 static pid_t pid; /* calling process (default) */
 static int verbose;
 
@@ -144,8 +151,6 @@ static int prlimit(pid_t p, int resource,
 }
 #endif
 
-static void rem_prlim(struct prlimit *lim);
-
 static void __attribute__ ((__noreturn__)) usage(FILE * out)
 {
        size_t i;
@@ -157,6 +162,9 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
        fprintf(out,
                _(" %s [options] COMMAND\n"), program_invocation_short_name);
 
+       fputs(USAGE_SEPARATOR, out);
+       fputs(_("Show or change the resource limits of a process.\n"), out);
+
        fputs(_("\nGeneral Options:\n"), out);
        fputs(_(" -p, --pid <pid>        process id\n"
                " -o, --output <list>    define which output columns to use\n"
@@ -187,7 +195,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
 
        fputs(_("\nAvailable columns (for --output):\n"), out);
 
-       for (i = 0; i < NCOLS; i++)
+       for (i = 0; i < ARRAY_SIZE(infos); i++)
                fprintf(out, " %11s  %s\n", infos[i].name, _(infos[i].help));
 
        fprintf(out, USAGE_MAN_TAIL("prlimit(1)"));
@@ -197,9 +205,8 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
 
 static inline int get_column_id(int num)
 {
-       assert(ARRAY_SIZE(columns) == NCOLS);
        assert(num < ncolumns);
-       assert(columns[num] < (int) NCOLS);
+       assert(columns[num] < (int) ARRAY_SIZE(infos));
 
        return columns[num];
 }
@@ -209,39 +216,37 @@ static inline struct colinfo *get_column_info(unsigned num)
        return &infos[ get_column_id(num) ];
 }
 
-static void add_tt_line(struct tt *tt, struct prlimit *l)
+static void add_scols_line(struct libscols_table *table, struct prlimit *l)
 {
        int i;
-       struct tt_line *line;
+       struct libscols_line *line;
 
-       assert(tt);
+       assert(table);
        assert(l);
 
-       line = tt_add_line(tt, NULL);
-       if (!line) {
-               warn(_("failed to add line to output"));
-               return;
-       }
+       line = scols_table_new_line(table, NULL);
+       if (!line)
+               err(EXIT_FAILURE, _("failed to allocate output line"));
 
        for (i = 0; i < ncolumns; i++) {
                char *str = NULL;
 
                switch (get_column_id(i)) {
                case COL_RES:
-                       xasprintf(&str, "%s", l->desc->name);
+                       str = xstrdup(l->desc->name);
                        break;
                case COL_HELP:
-                       xasprintf(&str, "%s", l->desc->help);
+                       str = xstrdup(l->desc->help);
                        break;
                case COL_SOFT:
                        if (l->rlim.rlim_cur == RLIM_INFINITY)
-                               xasprintf(&str, "%s", "unlimited");
+                               str = xstrdup(_("unlimited"));
                        else
                                xasprintf(&str, "%llu", (unsigned long long) l->rlim.rlim_cur);
                        break;
                case COL_HARD:
                        if (l->rlim.rlim_max == RLIM_INFINITY)
-                               xasprintf(&str, "%s", "unlimited");
+                               str = xstrdup(_("unlimited"));
                        else
                                xasprintf(&str, "%llu", (unsigned long long) l->rlim.rlim_max);
                        break;
@@ -252,8 +257,8 @@ static void add_tt_line(struct tt *tt, struct prlimit *l)
                        break;
                }
 
-               if (str)
-                       tt_line_set_data(line, i, str);
+               if (str && scols_line_refer_data(line, i, str))
+                       err(EXIT_FAILURE, _("failed to add output data"));
        }
 }
 
@@ -263,7 +268,7 @@ static int column_name_to_id(const char *name, size_t namesz)
 
        assert(name);
 
-       for (i = 0; i < NCOLS; i++) {
+       for (i = 0; i < ARRAY_SIZE(infos); i++) {
                const char *cn = infos[i].name;
 
                if (!strncasecmp(name, cn, namesz) && !*(cn + namesz))
@@ -273,38 +278,43 @@ static int column_name_to_id(const char *name, size_t namesz)
        return -1;
 }
 
-static int show_limits(struct list_head *lims, int tt_flags)
+static void rem_prlim(struct prlimit *lim)
+{
+       if (!lim)
+               return;
+       list_del(&lim->lims);
+       free(lim);
+}
+
+static int show_limits(struct list_head *lims)
 {
        int i;
        struct list_head *p, *pnext;
-       struct tt *tt;
+       struct libscols_table *table;
 
-       tt = tt_new_table(tt_flags);
-       if (!tt) {
-               warn(_("failed to initialize output table"));
-               return -1;
-       }
+       table = scols_new_table();
+       if (!table)
+               err(EXIT_FAILURE, _("failed to allocate output table"));
+
+       scols_table_enable_raw(table, raw);
+       scols_table_enable_noheadings(table, no_headings);
 
        for (i = 0; i < ncolumns; i++) {
                struct colinfo *col = get_column_info(i);
 
-               if (!tt_define_column(tt, col->name, col->whint, col->flags)) {
-                       warnx(_("failed to initialize output column"));
-                       goto done;
-               }
+               if (!scols_table_new_column(table, col->name, col->whint, col->flags))
+                       err(EXIT_FAILURE, _("failed to allocate output column"));
        }
 
-
        list_for_each_safe(p, pnext, lims) {
                struct prlimit *lim = list_entry(p, struct prlimit, lims);
 
-               add_tt_line(tt, lim);
+               add_scols_line(table, lim);
                rem_prlim(lim);
        }
 
-       tt_print_table(tt);
-done:
-       tt_free_table(tt);
+       scols_print_table(table);
+       scols_unref_table(table);
        return 0;
 }
 
@@ -349,7 +359,8 @@ static void do_prlimit(struct list_head *lims)
                        old = &lim->rlim;
 
                if (verbose && new) {
-                       printf(_("New %s limit: "), lim->desc->name);
+                       printf(_("New %s limit for pid %d: "), lim->desc->name,
+                               pid ? pid : getpid());
                        if (new->rlim_cur == RLIM_INFINITY)
                                printf("<%s", _("unlimited"));
                        else
@@ -372,8 +383,6 @@ static void do_prlimit(struct list_head *lims)
        }
 }
 
-
-
 static int get_range(char *str, rlim_t *soft, rlim_t *hard, int *found)
 {
        char *end = NULL;
@@ -466,17 +475,9 @@ static int add_prlim(char *ops, struct list_head *lims, size_t id)
        return 0;
 }
 
-static void rem_prlim(struct prlimit *lim)
-{
-       if (!lim)
-               return;
-       list_del(&lim->lims);
-       free(lim);
-}
-
 int main(int argc, char **argv)
 {
-       int opt, tt_flags = 0;
+       int opt;
        struct list_head lims;
 
        enum {
@@ -597,17 +598,16 @@ int main(int argc, char **argv)
                        return EXIT_SUCCESS;
 
                case NOHEADINGS_OPTION:
-                       tt_flags |= TT_FL_NOHEADINGS;
+                       no_headings = 1;
                        break;
                case VERBOSE_OPTION:
                        verbose++;
                        break;
                case RAW_OPTION:
-                       tt_flags |= TT_FL_RAW;
+                       raw = 1;
                        break;
-
                default:
-                       usage(stderr);
+                       errtryhelp(EXIT_FAILURE);
                }
        }
        if (argc > optind && pid)
@@ -621,6 +621,8 @@ int main(int argc, char **argv)
                columns[ncolumns++] = COL_UNITS;
        }
 
+       scols_init_debug(0);
+
        if (list_empty(&lims)) {
                /* default is to print all resources */
                size_t n;
@@ -632,7 +634,7 @@ int main(int argc, char **argv)
        do_prlimit(&lims);
 
        if (!list_empty(&lims))
-               show_limits(&lims, tt_flags);
+               show_limits(&lims);
 
        if (argc > optind) {
                /* prlimit [options] COMMAND */