#include <sys/resource.h> int getrlimit(int resource, struct rlimit *rlptr); int setrlimit(int resource, const struct rlimit *rlptr); /* Return value: if successful, return 0; otherwise, return non-0 */ struct rlimit{ rlim_t rlim_cur; // soft limit: current limit rlim_t rlim_max; // hard limit: maximum value for rlim_cur };
There are 3 rules to follow when changing resource limits.
(1) Any process can change a soft limit value to be less than or equal to its hard limit value.
(2) Any process can reduce its hard limit value, but it must not be less than its soft limit value. This reduction is irreversible for ordinary users.
(3) Only the superuser process can raise the hard limit value.
The constant RLIM_INFINITY specifies an infinite limit.
The following figure shows which of the optional values for the resource parameter are defined by the Single UNIX Specification and supported by common UNIX systems.
A description of each of these values follows.
* RLIMIT_AS: The maximum length (bytes) of the total available storage space of the process. This affects the sbrk function and the mmap function.
* RLIMIT_CORE: The maximum number of bytes of the core file, if its value is 0, it will prevent the creation of the core file.
* RLIMIT_CPU: The maximum amount of CPU time (seconds), when this soft limit is exceeded, a SIGXCPU signal is sent to the process.
* RLIMIT_DATA: The maximum byte length of the data segment. This is the sum of initialized data, uninitialized, and heap.
* RLIMIT_FSIZE: The maximum length in bytes of a file that can be created. When this soft limit is exceeded, the process is sent a SIGXFSZ signal.
* RLIMIT_MEMLOCK: The maximum length in bytes that a process can lock in memory using mlock(2).
* RLIMIT_MSQQUEUE: The maximum number of bytes of storage that a process can allocate for a POSIX message queue.
* RLIMIT_NICE: In order to affect the scheduling priority of the process, the maximum limit that the nice value can be set.
* RLIMIT_NOFILE: The maximum number of files each process can open. Changing this limit will affect the value returned by the sysconf function in the parameter _SC_OPEN_MAX.
* RLIMIT_NPROC: The maximum number of child processes each real user ID can have. Changing this limit will affect the value returned by the sysconf function in the parameter _SC_CHILD_MAX.
* RLIMIT_NPTS: The maximum number of pseudo-terminals that a user can open at the same time.
* RLIMIT_RSS: The maximum resident set size in bytes (RSS). If very little physical memory is available, the kernel will fetch more than RSS from the process.
* RLIMIT_SBSIZE: The maximum length (in bytes) of the socket buffer that a user can occupy at any given moment.
* RLIMIT_SIGPENDING: The maximum number of signals a process can queue. This restriction is enforced by the sigqueue function.
* RLIMIT_STACK: The maximum byte length of the stack.
* RLIMIT_SWAP: The maximum number of bytes of swap space that the user can consume.
* RLIMIT_VMEM: Synonym for RLIMIT_AS.
Resource limits affect the calling process and are inherited by its child processes. This means that, in order to affect all subsequent processes of a user, the setting of the resource limit needs to be constructed in the shell, such as the Bourne shell, GNU Bourne-again shell and Kom shell have built-in ulimit command, C shell has built-in limit command .
The following program prints the current soft and hard limits for all resources supported by the system (note that some platforms define rlim_t as unsigned long long instead of unsigned long. Some limits apply to file size, so the rlim_t type must be large enough to represent the file size limit .. to avoid compiler warnings for using the wrong format specification, usually the limit is first copied to a 64-bit int, so that only one format needs to be processed).
#include <stdio.h> #include <stdlib.h> #include <sys/resource.h> #define doit(name) pr_limits(#name, name); static void pr_limits(char *, int); int main(void){ #ifdef RLIMIT_AS must(RLIMIT_AS); #endif must(RLIMIT_CORE); must(RLIMIT_CPU); must(RLIMIT_DATA); must(RLIMIT_FSIZE); #ifdef RLIMIT_MEMLOCK must(RLIMIT_MEMLOCK); #endif #ifdef RLIMIT_MSGQUEUE must(RLIMIT_MSGQUEUE); #endif #ifdef RLIMIT_NICE must(RLIMIT_NICE); #endif must (RLIMIT_NOFILE); #ifdef RLIMIT_NPROC must(RLIMIT_NPROC); #endif #ifdef RLIMIT_NPTS must(RLIMIT_NPTS); #endif #ifdef RLIMIT_RSS must(RLIMIT_RSS); #endif #ifdef RLIMIT_SBSIZE must(RLIMIT_SBSIZE); #endif #ifdef RLIMIT_SIGPENDING must(RLIMIT_SIGPENDING); #endif must(RLIMIT_STACK); #ifdef RLIMIT_SWAP must(RLIMIT_SWAP); #endif #ifdef RLIMIT_VMEM must(RLIMIT_VMEM); #endif exit(0); } static void pr_limits(char *name, int resource){ struct rlimit limit; unsigned long long lim; if(getrlimit(resource, &limit) < 0){ printf("getrlimit error for %s\n", name); return; } printf("%-14s ", name); if(limit.rlim_cur == RLIM_INFINITY){ printf("(infinite) "); }else{ lim = limit.rlim_cur; printf("%10lld ", lim); } if(limit.rlim_max == RLIM_INFINITY){ printf("(infinite)"); }else{ lim = limit.rlim_max; printf("%10lld", lim); } putchar((int)'\n'); }
Note that the ISO C string creation operator "#" is used in the doit macro to produce a string value for each resource name.
The result of running on the Linux system is as follows.
$ ./resourceLimit.out RLIMIT_AS (infinite) (infinite) RLIMIT_CORE 0 (infinite) RLIMIT_CPU (infinite) (infinite) RLIMIT_DATA (infinite) (infinite) RLIMIT_FSIZE (infinite) (infinite) RLIMIT_MEMLOCK 65536 65536 RLIMIT_MSGQUEUE 819200 819200 RLIMIT_NICE 0 0 RLIMIT_NOFILE 65535 65535 RLIMIT_NPROC 1024 65535 RLIMIT_RSS (infinite) (infinite) RLIMIT_SIGPENDING 3810 3810 RLIMIT_STACK 10485760 (infinite)