]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - sys-utils/prlimit.c
su: change error message
[thirdparty/util-linux.git] / sys-utils / prlimit.c
index 5bb99d1ec5fdd986a662b1b7b8cb5f97fce33592..6f806362d1f0662e9930b071fb22b85b8b348dcf 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,9 @@ static int prlimit(pid_t p, int resource,
 }
 #endif
 
-static void __attribute__ ((__noreturn__)) usage(FILE * out)
+static void __attribute__((__noreturn__)) usage(void)
 {
+       FILE *out = stdout;
        size_t i;
 
        fputs(USAGE_HEADER, out);
@@ -155,14 +163,17 @@ 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"
                "     --noheadings       don't print headings\n"
                "     --raw              use the raw output format\n"
                "     --verbose          verbose output\n"
-               " -h, --help             display this help and exit\n"
-               " -V, --version          output version information and exit\n"), out);
+               ), out);
+       printf(USAGE_HELP_OPTIONS(24));
 
        fputs(_("\nResources Options:\n"), out);
        fputs(_(" -c, --core             maximum size of core files created\n"
@@ -183,21 +194,19 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
                " -y, --rttime           CPU time in microseconds a process scheduled\n"
                "                        under real-time scheduling\n"), out);
 
-       fputs(_("\nAvailable columns (for --output):\n"), out);
-
-       for (i = 0; i < NCOLS; i++)
+       fputs(USAGE_COLUMNS, out);
+       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)"));
+       printf(USAGE_MAN_TAIL("prlimit(1)"));
 
-       exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+       exit(EXIT_SUCCESS);
 }
 
 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];
 }
@@ -207,19 +216,17 @@ 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;
@@ -250,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"));
        }
 }
 
@@ -261,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))
@@ -279,38 +286,35 @@ static void rem_prlim(struct prlimit *lim)
        free(lim);
 }
 
-static int show_limits(struct list_head *lims, int tt_flags)
+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 | TT_FL_FREEDATA);
-       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;
 }
 
@@ -355,16 +359,17 @@ 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
-                               printf("<%ju", new->rlim_cur);
+                               printf("<%ju", (uintmax_t)new->rlim_cur);
 
                        if (new->rlim_max == RLIM_INFINITY)
                                printf(":%s>\n", _("unlimited"));
                        else
-                               printf(":%ju>\n", new->rlim_max);
+                               printf(":%ju>\n", (uintmax_t)new->rlim_max);
                }
 
                if (prlimit(pid, lim->desc->resource, new, old) == -1)
@@ -472,7 +477,7 @@ static int add_prlim(char *ops, struct list_head *lims, size_t id)
 
 int main(int argc, char **argv)
 {
-       int opt, tt_flags = 0;
+       int opt;
        struct list_head lims;
 
        enum {
@@ -580,7 +585,7 @@ int main(int argc, char **argv)
                        pid = strtos32_or_err(optarg, _("invalid PID argument"));
                        break;
                case 'h':
-                       usage(stdout);
+                       usage();
                case 'o':
                        ncolumns = string_to_idarray(optarg,
                                                     columns, ARRAY_SIZE(columns),
@@ -593,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)
@@ -617,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;
@@ -628,12 +634,12 @@ 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 */
                execvp(argv[optind], &argv[optind]);
-               err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+               errexec(argv[optind]);
        }
 
        return EXIT_SUCCESS;