What is RLIMIT_FSIZE?
RLIMIT_FSIZE limits the maximum size of any file that the process may create or extend, in bytes. If a process attempts to write data to a file that would push its size beyond the soft limit, the kernel intervenes with both a signal and an error return.
What Happens When the Limit is Exceeded
When a process tries to extend a file beyond the soft RLIMIT_FSIZE limit, two things happen simultaneously:
- The kernel sends a SIGXFSZ signal to the process.
- The system call that triggered the violation (write(), truncate(), etc.) fails and returns the error EFBIG.
The default action for SIGXFSZ is to terminate the process with a core dump. A process can instead install a signal handler for SIGXFSZ. If the handler returns normally, the process continues — but any further attempt to extend the file will produce the exact same SIGXFSZ + EFBIG combination. There is no way to continue extending the file without either raising the limit or accepting the truncation.
Affected operations:
write()— writing past the end of filetruncate()/ftruncate()— extending a file- Appending via lseek() + write()
Code Example — RLIMIT_FSIZE and SIGXFSZ
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/resource.h>
static void sigxfsz_handler(int sig)
{
printf("\nSIGXFSZ: File size limit exceeded!\n");
/* Cannot extend file further — must exit or accept truncation */
exit(1);
}
int main(void)
{
struct rlimit rl;
int fd;
char buf[4096];
ssize_t n;
/* Install SIGXFSZ handler */
signal(SIGXFSZ, sigxfsz_handler);
/* Limit file size to 10 KB */
rl.rlim_cur = 10 * 1024; /* 10 KB soft limit */
rl.rlim_max = 10 * 1024;
if (setrlimit(RLIMIT_FSIZE, &rl) == -1) {
perror("setrlimit"); exit(1);
}
printf("File size limit: 10 KB\n");
fd = open("/tmp/test_fsize.dat", O_WRONLY|O_CREAT|O_TRUNC, 0600);
if (fd == -1) { perror("open"); exit(1); }
memset(buf, 'A', sizeof(buf)); /* 4 KB of data per write */
/* Write 4 KB at a time — should fail after ~2.5 writes */
int writes = 0;
while (1) {
n = write(fd, buf, sizeof(buf));
if (n == -1) {
if (errno == EFBIG)
printf("write() failed: EFBIG (file size limit)\n");
else
perror("write");
break;
}
writes++;
printf("Wrote chunk %d (%zd bytes)\n", writes, n);
}
close(fd);
unlink("/tmp/test_fsize.dat");
return 0;
}
/* Compile: gcc -o rlimit_fsize rlimit_fsize.c */
Interview Questions
The kernel sends SIGXFSZ to the process AND the system call (write, truncate, etc.) fails with errno set to EFBIG. Both happen simultaneously.
The default action is to terminate the process and produce a core dump. This is the same destructive default as SIGXCPU.
No. Any further attempt to extend the file beyond the soft limit will produce the same SIGXFSZ + EFBIG combination. The limit has not changed. The process can only continue writing if it raises the limit (via setrlimit()) or accepts that writes will fail.
If RLIMIT_FSIZE is set lower than RLIMIT_CORE, core dump files are limited to RLIMIT_FSIZE bytes. RLIMIT_FSIZE is an absolute ceiling on the size of any file written by the process, including core dumps.
