#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"
STACK
};
+/* basic output flags */
+static int no_headings;
+static int raw;
+
struct prlimit_desc {
const char *name;
const char *help;
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;
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)
#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;
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"
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)"));
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];
}
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;
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"));
}
}
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))
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;
}
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
int main(int argc, char **argv)
{
- int opt, tt_flags = 0;
+ int opt;
struct list_head lims;
enum {
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)
columns[ncolumns++] = COL_UNITS;
}
+ scols_init_debug(0);
+
if (list_empty(&lims)) {
/* default is to print all resources */
size_t n;
do_prlimit(&lims);
if (!list_empty(&lims))
- show_limits(&lims, tt_flags);
+ show_limits(&lims);
if (argc > optind) {
/* prlimit [options] COMMAND */