0

I'm writing a C program that accepts a system resource name (e.g. RLIMIT_NOFILE) and prints some resource limit info for it.

The resource constants are defined in <sys/resource.h>, e.g.

#define RLIMIT_NOFILE   5

I'm looking for a good way to map the command-line argument (e.g. RLIMIT_NOFILE) to the corresponding numeric value (e.g. 5).

I originally planned to do something like:

int resource = -1;
char *resource_names[] = {
    "RLIMIT_NOFILE", "RLIMIT_NPROC", "RLIMIT_RSS"
};

for (i = 0; i < sizeof(resource_names)/sizeof(char *); i++) {
    if (strcmp(argv[1], resource_names[i]) == 0) {
        resource = eval(resource_names[i]);
        break;
    }
}

But C doesn't seem to have anything like eval, and even if it did, the compile-time constants wouldn't be available at run-time.

For now, I'm doing the following, but I'm curious if there's a better approach.

#include <stdio.h>
#include <string.h>
#include <sys/resource.h>

int main(int argc, char *argv[])
{
    if (argc != 2) {
        printf("Usage: %s <resource>\n", argv[0]);
        return 1;
    }

    char *resource_names[] = {
        "RLIMIT_NOFILE", "RLIMIT_NPROC", "RLIMIT_RSS"
    };
    int resources[] = {
        RLIMIT_NOFILE, RLIMIT_NPROC, RLIMIT_RSS
    };
    int i, resource = -1;

    for (i = 0; i < sizeof(resources)/sizeof(int); i++) {
        if (strcmp(argv[1], resource_names[i]) == 0) {
            resource = resources[i];
            break;
        }
    }
    if (resource == -1) {
        printf("Invalid resource.\n");
        return 1;
    }

    struct rlimit rlim;
    getrlimit(resource, &rlim);
    printf("%s: %ld / %ld\n", argv[1], rlim.rlim_cur, rlim.rlim_max);

    return 0;
}
ivan
  • 6,032
  • 9
  • 42
  • 65

1 Answers1

2

The RLIMIT_x constants are all low-value integers that can be used as indexes into an array, or (for your problem) use an array to find the index and it will correspond to the value you want.

Or you could have an array of structures, containing both the value and the string. Something like

static const struct
{
    int limit;
    char *name;
} rlimits[] = {
    { RLIMIT_NOFILE, "RLIMIT_NOFILE" },
    { RLIMIT_NPROC, "RLIMIT_NPROC" },
    // Etc.
};

Then it's easy to iterate over the array and "map" a string to a value (or do the opposite).

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621