RLIMIT_FSIZE Maximum File Size: SIGXFSZ & EFBIG

 

36.3 — RLIMIT_FSIZE
Maximum File Size: SIGXFSZ & EFBIG | EmbeddedPathashala

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:

  1. The kernel sends a SIGXFSZ signal to the process.
  2. 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 file
  • truncate() / 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

Q1. What two things happen when a process tries to extend a file beyond RLIMIT_FSIZE?

The kernel sends SIGXFSZ to the process AND the system call (write, truncate, etc.) fails with errno set to EFBIG. Both happen simultaneously.

Q2. What is the default action for SIGXFSZ?

The default action is to terminate the process and produce a core dump. This is the same destructive default as SIGXCPU.

Q3. If a process catches SIGXFSZ and returns from the handler, can it then continue writing to the file?

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.

Q4. How does RLIMIT_FSIZE interact with RLIMIT_CORE?

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.

Leave a Reply

Your email address will not be published. Required fields are marked *