7.11. getrlimit and setrlimit FunctionsEvery process has a set of resource limits, some of which can be queried and changed by the geTRlimit and setrlimit functions.
Each call to these two functions specifies a single resource and a pointer to the following structure: struct rlimit { rlim_t rlim_cur; /* soft limit: current limit */ rlim_t rlim_max; /* hard limit: maximum value for rlim_cur */ }; Three rules govern the changing of the resource limits.
An infinite limit is specified by the constant RLIM_INFINITY. The resource argument takes on one of the following values. Figure 7.15 shows which limits are defined by the Single UNIX Specification and supported by each implementation.
The resource limits affect the calling process and are inherited by any of its children. This means that the setting of resource limits needs to be built into the shells to affect all our future processes. Indeed, the Bourne shell, the GNU Bourne-again shell, and the Korn shell have the built-in ulimit command, and the C shell has the built-in limit command. (The umask and chdir functions also have to be handled as shell built-ins.) ExampleThe program in Figure 7.16 prints out the current soft limit and hard limit for all the resource limits supported on the system. To compile this program on all the various implementations, we have conditionally included the resource names that differ. Note also that we must use a different printf format on platforms that define rlim_t to be an unsigned long long instead of an unsigned long. Note that we've used the ISO C string-creation operator (#) in the doit macro, to generate the string value for each resource name. When we say doit(RLIMIT_CORE); the C preprocessor expands this into pr_limits("RLIMIT_CORE", RLIMIT_CORE); Running this program under FreeBSD gives us the following:
$ ./a.out
RLIMIT_CORE (infinite) (infinite)
RLIMIT_CPU (infinite) (infinite)
RLIMIT_DATA 536870912 536870912
RLIMIT_FSIZE (infinite) (infinite)
RLIMIT_MEMLOCK (infinite) (infinite)
RLIMIT_NOFILE 1735 1735
RLIMIT_NPROC 867 867
RLIMIT_RSS (infinite) (infinite)
RLIMIT_SBSIZE (infinite) (infinite)
RLIMIT_STACK 67108864 67108864
RLIMIT_VMEM (infinite) (infinite)
Solaris gives us the following results:
$ ./a.out
RLIMIT_AS (infinite) (infinite)
RLIMIT_CORE (infinite) (infinite)
RLIMIT_CPU (infinite) (infinite)
RLIMIT_DATA (infinite) (infinite)
RLIMIT_FSIZE (infinite) (infinite)
RLIMIT_NOFILE 256 65536
RLIMIT_STACK 8388608 (infinite)
RLIMIT_VMEM (infinite) (infinite)
Figure 7.16. Print the current resource limits#include "apue.h" #if defined(BSD) || defined(MACOS) #include <sys/time.h> #define FMT "%10lld " #else #define FMT "%10ld " #endif #include <sys/resource.h> #define doit(name) pr_limits(#name, name) static void pr_limits(char *, int); int main(void) { #ifdef RLIMIT_AS doit(RLIMIT_AS); #endif doit(RLIMIT_CORE); doit(RLIMIT_CPU); doit(RLIMIT_DATA); doit(RLIMIT_FSIZE); #ifdef RLIMIT_LOCKS doit(RLIMIT_LOCKS); #endif #ifdef RLIMIT_MEMLOCK doit(RLIMIT_MEMLOCK); #endif doit(RLIMIT_NOFILE); #ifdef RLIMIT_NPROC doit(RLIMIT_NPROC); #endif #ifdef RLIMIT_RSS doit(RLIMIT_RSS); #endif #ifdef RLIMIT_SBSIZE doit(RLIMIT_SBSIZE); #endif doit(RLIMIT_STACK); #ifdef RLIMIT_VMEM doit(RLIMIT_VMEM); #endif exit(0); } static void pr_limits(char *name, int resource) { struct rlimit limit; if (getrlimit(resource, &limit) < 0) err_sys("getrlimit error for %s", name); printf("%-14s ", name); if (limit.rlim_cur == RLIM_INFINITY) printf("(infinite) "); else printf(FMT, limit.rlim_cur); if (limit.rlim_max == RLIM_INFINITY) printf("(infinite)"); else printf(FMT, limit.rlim_max); putchar((int)'\n'); } Exercise 10.11 continues the discussion of resource limits, after we've covered signals. |