Section 36.3 — What This Section Covers
Section 36.3 of TLPI is the main body of Chapter 36. It covers each of the 15 resource limit constants individually — what resource each one controls, what happens when a process exceeds its soft limit, what signals or errors are generated, and which kernel version introduced each limit.
Before diving into each limit one by one, it is worth having the complete picture in one place. This file gives you the Section 36.3 introduction and the full Table 36-1 so you can orient yourself before reading the per-limit detail pages.
Think of resource limits like budget allocations in a company. Each department (process) has a budget (resource limit). The soft limit is the normal operating budget — go over it and you get a warning (a signal). The hard limit is the absolute ceiling — the CFO (kernel) terminates you if you go past it.
How Limits Get Set in Practice
There are three ways a process can have resource limits:
In bash: ulimit -n 1024 sets RLIMIT_NOFILE. In C shell: limit. These limits are inherited by all child processes the shell spawns. This is the most common way to set limits for interactive users.
Since kernel 2.6.24, every process has a readable file at /proc/PID/limits showing all its current soft and hard limits. Owned by the real UID of the process; only that user (or root) can read it.
A process can call setrlimit() to change its own limits programmatically. Common in daemons, servers, or sandboxing tools that want to restrict a child process before exec()ing it.
Table 36-1: All 15 Resource Limit Constants
Grouping the Limits by Category
What Happens When a Limit Is Exceeded?
The behaviour when a process exceeds a soft limit depends on the resource type. There are three patterns:
The process receives a signal (SIGXCPU or SIGXFSZ) AND the system call returns an error (SIGKILL eventually for RLIMIT_CPU). The signal gives the process a chance to clean up before being killed.
The system call that would exceed the limit simply fails with an appropriate errno (ENOMEM, EMFILE, EAGAIN, etc.). No signal is sent.
Growing the stack beyond the limit generates a SIGSEGV. Since the stack itself is exhausted, you need an alternate signal stack to catch it at all.
Code Example — Checking All Resource Limits
This helper loops through all 15 constants and prints their current soft and hard limits. Useful as a diagnostic tool:
#include <stdio.h>
#include <sys/resource.h>
static void print_limit(const char *name, int resource)
{
struct rlimit rl;
if (getrlimit(resource, &rl) == -1) {
perror(name);
return;
}
printf("%-22s soft=", name);
if (rl.rlim_cur == RLIM_INFINITY)
printf("unlimited");
else
printf("%lld", (long long)rl.rlim_cur);
printf(" hard=");
if (rl.rlim_max == RLIM_INFINITY)
printf("unlimited\n");
else
printf("%lld\n", (long long)rl.rlim_max);
}
int main(void)
{
printf("Resource Limit Summary\n");
printf("======================\n");
print_limit("RLIMIT_AS", RLIMIT_AS);
print_limit("RLIMIT_CORE", RLIMIT_CORE);
print_limit("RLIMIT_CPU", RLIMIT_CPU);
print_limit("RLIMIT_DATA", RLIMIT_DATA);
print_limit("RLIMIT_FSIZE", RLIMIT_FSIZE);
print_limit("RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
print_limit("RLIMIT_MSGQUEUE", RLIMIT_MSGQUEUE);
print_limit("RLIMIT_NICE", RLIMIT_NICE);
print_limit("RLIMIT_NOFILE", RLIMIT_NOFILE);
print_limit("RLIMIT_NPROC", RLIMIT_NPROC);
print_limit("RLIMIT_RSS", RLIMIT_RSS);
print_limit("RLIMIT_RTPRIO", RLIMIT_RTPRIO);
print_limit("RLIMIT_RTTIME", RLIMIT_RTTIME);
print_limit("RLIMIT_SIGPENDING", RLIMIT_SIGPENDING);
print_limit("RLIMIT_STACK", RLIMIT_STACK);
return 0;
}
/* Compare against: ulimit -a (bash) or cat /proc/self/limits */
Interview Questions
Linux defines 15 resource limit constants as of kernel 2.6.25 (when RLIMIT_RTTIME was added). They are listed in Table 36-1 of TLPI and fully documented in the getrlimit(2) man page. The header <sys/resource.h> defines all the RLIMIT_* constants.
Six of the 15 limits are in SUSv3: RLIMIT_AS, RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_NOFILE, and RLIMIT_STACK. The rest are Linux-specific or BSD-derived extensions.
Since kernel 2.6.24, the file /proc/PID/limits displays all soft and hard resource limits of any process. This file is readable by the process’s real user ID or by root. The equivalent shell command is ulimit -a for your own shell’s limits.
Historical convention. Shell commands typically display memory limits in kilobytes for human readability, while the kernel system calls work in bytes for precision. For example, ulimit -s shows stack size in KB, but RLIMIT_STACK via getrlimit() returns bytes. Always verify which unit a tool uses before interpreting values.
RLIMIT_RSS — the resident set size limit. It was inherited from BSD but has never been enforced by the Linux kernel. Processes can set it, and getrlimit() will return it, but the kernel never actually limits the process’s physical memory based on this value.
First, through the shell using ulimit (bash/ksh) or limit (csh) before running a program — these limits are inherited. Second, programmatically using setrlimit() to change the process’s own limits at runtime. Third, by reading /proc/PID/limits to inspect any process’s current limits (since kernel 2.6.24).
