Linux System Limits & Options

Linux System Limits & Options
Master sysconf(), pathconf(), fpathconf() and write truly portable Linux/UNIX programs
4
Core Concepts
3
Key Functions
10+
Code Examples
Free
Forever

What You Will Learn
sysconf() Linux pathconf() fpathconf() POSIX system limits NAME_MAX PATH_MAX OPEN_MAX file descriptors runtime invariant values SUSv3 limits getconf command portable Linux programs _POSIX_ constants limits.h unistd.h Linux programming interface

Why Does Any of This Matter?

Imagine you are writing a Linux program that opens many files at once, or creates filenames dynamically, or reads environment variables. You have a question: how many files can I actually open at the same time on this machine? How long can a filename be?

The wrong answer is to guess — for example, hardcoding 1024 as the max open files or 255 as the max filename length. On a different Linux kernel config, an embedded system, or a BSD machine, those numbers could be completely wrong. Your program silently misbehaves or crashes.

The right answer is what this tutorial is about: ask the OS itself at compile time or at runtime what the actual limits are. POSIX gives us a clean set of functions and constants to do exactly that.

Part 1 — The Problem With Hard-Coding Limits

Every UNIX/Linux system has internal limits. How many processes can run at once? How big can an argument list be when you call exec()? What is the largest integer you can store in an int? These are not universal — they depend on the hardware, the kernel version, the filesystem, and the compiler.

Here is a concrete problem. Suppose you write code like this:

Bad Practice — Hard-Coded Limit
/* BAD: Never do this */ char filename[255]; /* assumes 255 is always the max */ int fd_table[1024]; /* assumes 1024 is always the max open files */ /* On an embedded RTOS this might be 64. On some BSD configs it is 32768. Your program breaks silently on both ends. */

Limits can vary in two ways:

Two Sources of Limit Variation
Source of Variation Example Consequence
Different UNIX implementations Max int size on 32-bit vs 64-bit Same code gives different results on different machines
Same OS, different kernel config or runtime Admin raises OPEN_MAX via ulimit Binary compiled yesterday now uses wrong limit
Same OS, different filesystem FAT32 max filename = 8.3, ext4 = 255 bytes File creation fails when crossing filesystem boundary

The POSIX standard (SUSv3 and later SUSv4) gave us a proper solution: a set of standard constants, header files, and functions so a program can discover limits without guessing.

Part 2 — Two Ways to Get Limit Information

POSIX provides two complementary approaches depending on when the limit is known.

Compile-Time vs Runtime Limit Discovery
Approach When to Use How Example
Compile-Time Limit is fixed by hardware/compiler design Constants in <limits.h> INT_MAX, CHAR_BIT
Runtime Limit can change per kernel/filesystem/config sysconf(), pathconf(), fpathconf() OPEN_MAX, NAME_MAX

Compile-Time: limits.h and the _POSIX_ minimum values

The header <limits.h> defines two layers of constants for each limit:

  • _POSIX_XXX_MAX — the minimum value any conforming implementation must support. Think of it as the floor POSIX guarantees.
  • XXX_MAX — the actual value this implementation supports. It will be equal to or larger than the POSIX minimum.

Understanding the Confusing _MAX / _MIN Naming
Constant What It Means Mental Model
_POSIX_NAME_MAX = 14 Every POSIX system must support filenames of at least 14 bytes Guaranteed floor — your safe lower bound
NAME_MAX = 255 (Linux ext4) On this specific system, filenames up to 255 bytes work Actual ceiling on this machine
FLT_MIN = 1E-37 The largest smallest float an impl may use (note: _MIN here = lower limit) Every system must handle floats at least this small
Compile-Time Limit Example
#include <limits.h> #include <stdio.h> int main(void) { /* _POSIX_NAME_MAX is the POSIX floor: 14 bytes guaranteed everywhere */ printf(“POSIX minimum filename length : %d\n”, _POSIX_NAME_MAX); /* NAME_MAX is what THIS system actually supports */ printf(“This system’s max filename : %d\n”, NAME_MAX); /* On Linux ext4 you will see: POSIX minimum filename length : 14 This system’s max filename : 255 */ return 0; }

Part 3 — Three Categories of Runtime Limits

Not all limits behave the same way at runtime. SUSv3 defines three distinct categories. Understanding which category a limit falls into tells you how to query it and whether to expect it to change.

Three Categories of SUSv3 Runtime Limits
Category Fixed At? How To Query Can Be Indeterminate? Example
Runtime Invariant Value Fixed per implementation sysconf() Yes — may depend on available RAM MQ_PRIO_MAX
Pathname Variable Value Can vary per filesystem pathconf() / fpathconf() Yes NAME_MAX, PATH_MAX
Runtime Increasable Value Fixed floor, system may raise it sysconf() No NGROUPS_MAX

Category 1: Runtime Invariant Value — MQ_PRIO_MAX Example

Take POSIX message queue priority (MQ_PRIO_MAX). POSIX says every implementation must allow at least 32 priority levels (0 to 31). Linux goes far beyond that — it allows 32,768 priority levels. The actual number is fixed for a given kernel build, but you must query it to know what it is:

Querying MQ_PRIO_MAX with sysconf()
long prio_max = sysconf(_SC_MQ_PRIO_MAX); /* On Linux 2.6+: prio_max = 32768 On a bare POSIX: prio_max = at least 32 Always query — never assume. */

Category 2: Pathname Variable Value — NAME_MAX Example

This one is filesystem-dependent. If your program mounts an ext4 partition and a FAT32 USB drive, the max filename length is different on each. You must pass the actual path to pathconf() so the kernel can look at which filesystem that path lives on:

Filesystem-Dependent: NAME_MAX via pathconf()
long name_max_ext4 = pathconf(“/home/ravi”, _PC_NAME_MAX); /* ext4: 255 bytes */ long name_max_fat = pathconf(“/mnt/usb”, _PC_NAME_MAX); /* FAT32: 8 for base name (8.3 convention), or 255 with LFN enabled */ /* So if you are creating a file, always check the TARGET directory */

Category 3: Runtime Increasable Value — NGROUPS_MAX Example

NGROUPS_MAX defines how many supplementary groups a process can belong to simultaneously. POSIX guarantees at least 8. Linux default is 65536. The floor is fixed but a running system can increase it. You check with sysconf():

Runtime Increasable: NGROUPS_MAX
long max_groups = sysconf(_SC_NGROUPS_MAX); /* Linux default: 65536 Embedded minimal config: maybe just 8 (the POSIX floor) Query at runtime so your group-management code allocates the right sized array. */

Part 4 — sysconf() Deep Dive

sysconf() is your main tool for querying system-wide limits at runtime. Its signature is simple:

sysconf() Signature
#include <unistd.h> long sysconf(int name); /* Returns: the limit value (always a long integer) -1 if the limit is indeterminate OR an error occurred */

Interpreting sysconf() Return Values
Return Value errno After Call Meaning What To Do
Positive value unchanged Success — this is the actual limit Use the value
-1 still 0 Limit is indeterminate (genuinely unknown) Use a safe fallback or POSIX minimum
-1 EINVAL The name argument is invalid Fix the name constant you passed

The critical thing to notice: -1 has two different meanings. That is why you must set errno = 0 before the call, then check errno after if -1 is returned. Here is a reusable wrapper function you should always use:

Safe sysconf() Wrapper — Use This in Your Projects
#include <unistd.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> /* Returns the limit value, or -1 for indeterminate. Exits on genuine error. */ long safe_sysconf(const char *label, int name) { long val; errno = 0; /* MUST clear errno before the call */ val = sysconf(name); if (val != -1) { printf(“%-30s : %ld\n”, label, val); return val; } if (errno == 0) { /* -1 returned, errno still 0 → limit is genuinely indeterminate */ printf(“%-30s : (indeterminate)\n”, label); return -1; } /* -1 returned, errno is set → real error */ perror(“sysconf”); exit(EXIT_FAILURE); } int main(void) { safe_sysconf(“Max open files (OPEN_MAX)”, _SC_ARG_MAX); safe_sysconf(“Max open files (OPEN_MAX)”, _SC_OPEN_MAX); safe_sysconf(“Login name max length”, _SC_LOGIN_NAME_MAX); safe_sysconf(“Max supplementary groups”, _SC_NGROUPS_MAX); safe_sysconf(“Page size (bytes)”, _SC_PAGESIZE); safe_sysconf(“Max realtime signals”, _SC_RTSIG_MAX); safe_sysconf(“Max queued realtime signals”, _SC_SIGQUEUE_MAX); return 0; } /* Typical output on a modern Linux desktop: Max open files (OPEN_MAX) : 2097152 Max open files (OPEN_MAX) : 1024 Login name max length : 256 Max supplementary groups : 65536 Page size (bytes) : 4096 Max realtime signals : 32 Max queued realtime signals : 65536 */

Important: sysconf() values can change during a process lifetime (on Linux)

POSIX says sysconf() values should be constant for the life of a process. But Linux has three legitimate exceptions — cases where a process can change its own resource limits using setrlimit(), which then affects what sysconf() reports:

Linux: Three sysconf() Values That Can Change at Runtime
setrlimit() Resource Affects sysconf() Name What Changes
RLIMIT_NOFILE _SC_OPEN_MAX Max files this process can open
RLIMIT_NPROC _SC_CHILD_MAX Per-user process creation limit
RLIMIT_STACK _SC_ARG_MAX Size allowed for argv + environ in exec()

Part 5 — pathconf() and fpathconf()

While sysconf() handles system-wide limits, some limits are filesystem-specific. A filename limit on ext4 is different from one on FAT32 or NFS. For these, POSIX gives us pathconf() and fpathconf().

pathconf() and fpathconf() Signatures
#include <unistd.h> /* Specify file/dir by path name */ long pathconf(const char *pathname, int name); /* Specify file/dir by already-open file descriptor */ long fpathconf(int fd, int name); /* Both return: limit value, or -1 (indeterminate or error) Error handling: identical to sysconf() — set errno=0 first */

The Only Difference Between the Two

pathconf() takes a string path. fpathconf() takes an already-open file descriptor. Use fpathconf() when you have already opened the file (avoids a second path resolution), and pathconf() when you have only the path string.

Choosing Between pathconf() and fpathconf()
Do you have an open fd?
YES → use fpathconf(fd, _PC_...)
Avoids re-resolving the path. Safe if path was renamed after open.
NO → use pathconf("/some/dir", _PC_...)
Pass a directory path that lives on the filesystem you care about.

Practical Example: Allocating the Right Buffer for a Pathname

A very common real-world use case: you need to allocate a buffer large enough to hold the longest possible path on the filesystem where a given directory lives.

Real-World: Dynamic Buffer Allocation Using pathconf()
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <errno.h> char *alloc_path_buffer(const char *dir) { long path_max; errno = 0; path_max = pathconf(dir, _PC_PATH_MAX); if (path_max == -1) { if (errno != 0) { perror(“pathconf”); return NULL; } /* Indeterminate: use the POSIX floor as a safe fallback */ path_max = _POSIX_PATH_MAX; /* = 256 */ } /* path_max already includes the terminating null byte for PATH_MAX */ char *buf = malloc((size_t) path_max); if (!buf) { perror(“malloc”); return NULL; } return buf; } int main(void) { char *buf = alloc_path_buffer(“/home”); if (buf) { printf(“Buffer allocated for /home filesystem path queries\n”); free(buf); } return 0; } /* NOTE: PATH_MAX includes the null byte, NAME_MAX does not. So for a filename buffer you would use: char name_buf[NAME_MAX + 1]; (add 1 for the null byte) */

How _PC_PIPE_BUF Works — A Subtlety

_PC_PIPE_BUF is interesting because its meaning depends on what type of file you pass:

_PC_PIPE_BUF Behaviour by File Type
File Type Passed Value Returned
A pipe file descriptor Atomic write limit for that specific pipe
A FIFO (named pipe) path Atomic write limit for that FIFO
A directory path Limit that applies to FIFOs created in that directory
Complete fpathconf() Example — Check Limits on stdin’s Filesystem
#include <unistd.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> void print_fpathconf(const char *label, int fd, int name) { long val; errno = 0; val = fpathconf(fd, name); if (val != -1) printf(“%-20s : %ld\n”, label, val); else if (errno == 0) printf(“%-20s : (indeterminate)\n”, label); else { perror(“fpathconf”); exit(EXIT_FAILURE); } } int main(void) { /* Run as: ./prog < . (redirect a directory into stdin) */ print_fpathconf(“NAME_MAX”, STDIN_FILENO, _PC_NAME_MAX); print_fpathconf(“PATH_MAX”, STDIN_FILENO, _PC_PATH_MAX); print_fpathconf(“PIPE_BUF”, STDIN_FILENO, _PC_PIPE_BUF); return 0; } /* On an ext2/ext4 filesystem: NAME_MAX : 255 PATH_MAX : 4096 PIPE_BUF : 4096 */

Part 6 — The Key Limits Reference Table

Here is a combined reference of the most important limits you will encounter in daily Linux/embedded programming, their POSIX minimums, and how to query them.

Essential SUSv3 Limits — Quick Reference
Limit Name
(limits.h)
POSIX Min Linux Typical Query With What It Controls
ARG_MAX 4096 bytes ~2 MB _SC_ARG_MAX Total bytes for argv[] + environ[] passed to exec()
OPEN_MAX 20 1024 (soft), 1M+ hard _SC_OPEN_MAX Max simultaneously open file descriptors per process
NGROUPS_MAX 8 65536 _SC_NGROUPS_MAX Max supplementary group IDs a process can belong to
LOGIN_NAME_MAX 9 bytes 256 bytes _SC_LOGIN_NAME_MAX Max login/username length including null terminator
RTSIG_MAX 8 32 _SC_RTSIG_MAX Distinct realtime signal numbers available (SIGRTMIN to SIGRTMAX)
STREAM_MAX 8 16 (= FOPEN_MAX) _SC_STREAM_MAX Max stdio FILE* streams open simultaneously
NAME_MAX 14 bytes 255 (ext4) _PC_NAME_MAX Max filename bytes (excludes null terminator)
PATH_MAX 256 bytes 4096 (ext4) _PC_PATH_MAX Max pathname bytes (includes null terminator)
PIPE_BUF 512 bytes 4096 bytes _PC_PIPE_BUF Max bytes written atomically to a pipe/FIFO
NAME_MAX vs PATH_MAX null-byte inconsistency:

NAME_MAX does not include the terminating null byte — so you need NAME_MAX + 1 bytes for a filename buffer. PATH_MAX does include it — so allocating exactly PATH_MAX bytes is safe for a full path buffer. This is a deliberate POSIX inconsistency correction; older standards were ambiguous about PATH_MAX.

/* Correct buffer sizes */ char filename[NAME_MAX + 1]; /* +1 because NAME_MAX excludes null byte */ char pathname[PATH_MAX]; /* PATH_MAX already counts the null byte */

Part 7 — The getconf Shell Command

You do not always need a C program to check limits. The getconf command lets you query the same values from the shell. This is useful for shell scripting, quick checks, and debugging.

getconf Usage
$ getconf variable-name [pathname] # System-wide limits (no pathname needed): $ getconf ARG_MAX 131072 $ getconf OPEN_MAX 1024 $ getconf PAGESIZE 4096 # Filesystem-specific limits (pathname required): $ getconf NAME_MAX /boot 255 $ getconf NAME_MAX /proc 255 $ getconf PATH_MAX /home 4096 # Check a POSIX option: $ getconf _POSIX_JOB_CONTROL 1

In a shell script, you might use getconf to safely compute a buffer or loop limit:

Shell Script Using getconf
#!/bin/bash # Safely truncate a filename to fit the target filesystem TARGET_DIR=”/mnt/data” MAX_NAME=$(getconf NAME_MAX “$TARGET_DIR”) PROPOSED_NAME=”some_very_long_filename_that_might_exceed_limits.log” ACTUAL_LEN=${#PROPOSED_NAME} if [ “$ACTUAL_LEN” -gt “$MAX_NAME” ]; then echo “WARNING: filename too long for $TARGET_DIR (max=$MAX_NAME)” # Truncate (keeping extension) PROPOSED_NAME=”${PROPOSED_NAME:0:$MAX_NAME}” fi echo “Final name: $PROPOSED_NAME”

Part 8 — System Options (Feature Detection)

Beyond numeric limits, POSIX also defines a set of optional features — things like realtime signals, POSIX threads, job control, shared memory, etc. Not every UNIX/Linux system supports all of them (especially true for embedded systems or stripped-down configs).

POSIX options are advertised through constants in <unistd.h> that begin with _POSIX_ or _XOPEN_. Each constant has a specific value meaning:

POSIX Option Constant Values and Their Meaning
Value Meaning What Your Code Must Do
-1 Feature is definitely NOT supported Use #if to exclude code that depends on this feature
0 Support is uncertain at compile time — check at runtime Call sysconf(_SC_...) at runtime to confirm
> 0 (e.g. 200112L) Feature is guaranteed supported Safe to use unconditionally — all APIs are available

The value 200112L is the year-month the SUSv3 standard was approved (2001 December). SUSv4 uses 200809L.

Portable Feature Detection Pattern
#include <unistd.h> /* — Pattern 1: Compile-time check (preferred when the constant exists) — */ #if defined(_POSIX_REALTIME_SIGNALS) && (_POSIX_REALTIME_SIGNALS > 0) /* This implementation definitely supports realtime signals */ #include <signal.h> /* use sigqueue(), sigwaitinfo(), etc. safely */ #elif defined(_POSIX_REALTIME_SIGNALS) && (_POSIX_REALTIME_SIGNALS == 0) /* Uncertain at compile time; check at runtime */ #else /* Undefined → treat same as -1 → NOT supported (per SUSv4 clarification) */ #endif /* — Pattern 2: Runtime check (when compile constant is 0) — */ void check_realtime_signals(void) { long result = sysconf(_SC_REALTIME_SIGNALS); if (result > 0) { printf(“Realtime signals: SUPPORTED\n”); } else if (result == -1 && errno == 0) { printf(“Realtime signals: NOT SUPPORTED on this system\n”); } else { perror(“sysconf”); } }

Important Options You Will Encounter

Commonly Used POSIX Options
Option Constant sysconf() Name Feature Required by SUSv3?
_POSIX_JOB_CONTROL _SC_JOB_CONTROL Shell job control (bg, fg, Ctrl+Z) Yes (+)
_POSIX_THREADS _SC_THREADS POSIX thread support (pthreads) Optional
_POSIX_REALTIME_SIGNALS _SC_REALTIME_SIGNALS sigqueue(), sigwaitinfo() etc. Optional
_POSIX_SHARED_MEMORY_OBJECTS _SC_SHARED_MEMORY_OBJECTS shm_open(), mmap() shared memory Optional
_POSIX_SEMAPHORES _SC_SEMAPHORES sem_open(), sem_wait() etc. Optional
_POSIX_SAVED_IDS none Processes have saved set-user-ID/group-ID Yes (+)
_POSIX_CHOWN_RESTRICTED _PC_CHOWN_RESTRICTED Only root can chown files to arbitrary UIDs Must be defined (non -1) (*)
_POSIX_MESSAGE_PASSING _SC_MESSAGE_PASSING POSIX message queues (mq_open etc.) Optional

Part 9 — Dealing With Indeterminate Limits

Sometimes both the header constant is missing and sysconf()/pathconf() returns -1 with errno = 0. This means the system genuinely cannot tell you the limit. You have four strategies to handle this:

Four Strategies for Indeterminate Limits
# Strategy When Good Risk
1 Use the POSIX minimum (_POSIX_XXX_MAX) Maximum portability required Very conservative; may limit functionality unnecessarily
2 Try the operation and handle the error The operation itself fails cleanly with EAGAIN/ENAMETOOLONG etc. Adds retry logic complexity
3 Write a probe function to estimate the limit When a reasonable “good guess” is acceptable Guess may still be wrong on exotic systems
4 Use GNU Autoconf at build time Cross-platform library or tool distribution Build system complexity; not suitable for runtime-only decisions

Strategy 2 in Action — Try and Recover

For realtime signal queuing, the system imposes a limit. When you hit it, sigqueue() returns EAGAIN. Rather than trying to predict the limit, you handle the failure:

Strategy 2: Try-and-Retry Pattern for Signal Queuing
#include <signal.h> #include <errno.h> #include <time.h> int send_rtsig_with_retry(pid_t target, int signo, union sigval val) { int attempts = 0; const int MAX_ATTEMPTS = 5; while (attempts < MAX_ATTEMPTS) { if (sigqueue(target, signo, val) == 0) return 0; /* success */ if (errno == EAGAIN) { /* Queue is full — wait a bit and retry */ struct timespec delay = { 0, 10000000 }; /* 10ms */ nanosleep(&delay, NULL); attempts++; continue; } /* Any other error is a real failure */ return -1; } return -1; /* gave up after MAX_ATTEMPTS */ }

Strategy 3 — Probe Function for PATH_MAX

PATH_MAX is the classic case where both the header may be absent and pathconf() may return -1. Here is a robust probe function:

Strategy 3: Best-Effort PATH_MAX Probe
#include <unistd.h> #include <limits.h> #include <errno.h> /* Returns a usable PATH_MAX guess for the given directory. Never returns less than _POSIX_PATH_MAX (256). */ long get_path_max(const char *dir) { long pm; errno = 0; pm = pathconf(dir, _PC_PATH_MAX); if (pm != -1) return pm; /* Got a real value */ if (errno != 0) return _POSIX_PATH_MAX; /* pathconf() error: use safe floor */ /* Indeterminate: try the compile-time constant if defined */ #ifdef PATH_MAX return PATH_MAX; #else return 4096; /* Educated guess; ext4, XFS, btrfs all use 4096 */ #endif }

Part 10 — Complete Worked Example: Portable File Lister

Let us tie everything together. Here is a small program that lists files in a directory, properly using system limit queries instead of any hard-coded values. This is the kind of portable code you should write in production:

Portable Directory File Lister — Full Example
#include <unistd.h> #include <limits.h> #include <dirent.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> /* — Step 1: Get max filename length for this directory — */ static size_t get_name_max(const char *dir) { long nm; errno = 0; nm = pathconf(dir, _PC_NAME_MAX); if (nm == -1) { if (errno != 0) return NAME_MAX; /* pathconf failed: use compile-time */ return _POSIX_NAME_MAX; /* indeterminate: use POSIX floor (14) */ } return (size_t) nm; } /* — Step 2: Get max open files so we know our fd budget — */ static long get_open_max(void) { long om; errno = 0; om = sysconf(_SC_OPEN_MAX); if (om == -1) return 20; /* POSIX minimum if indeterminate */ return om; } int main(int argc, char *argv[]) { const char *target = (argc > 1) ? argv[1] : “.”; size_t name_max = get_name_max(target); long open_max = get_open_max(); printf(“Listing: %s\n”, target); printf(” Max filename length on this filesystem : %zu bytes\n”, name_max); printf(” Max open file descriptors this process : %ld\n\n”, open_max); /* Allocate dirent buffer sized correctly for this filesystem */ /* (struct dirent d_name is at least NAME_MAX+1 on Linux anyway, but the query approach is correct for strict portability) */ DIR *dp = opendir(target); if (!dp) { perror(“opendir”); return 1; } struct dirent *entry; int count = 0; while ((entry = readdir(dp)) != NULL) { if (entry->d_name[0] == ‘.’) continue; /* skip hidden */ size_t len = strlen(entry->d_name); const char *type = (entry->d_type == DT_DIR) ? “[DIR]” : “[FILE]”; printf(” %-10s %s (%zu bytes)\n”, type, entry->d_name, len); /* Warn if name is suspiciously close to the limit */ if (len >= name_max – 4) printf(” WARNING: filename near filesystem limit!\n”); count++; } closedir(dp); printf(“\nTotal entries: %d\n”, count); return 0; } /* Build: gcc -Wall -o lister lister.c Run: ./lister /home/ravi/projects */

Part 11 — Summary: The Full Picture

Linux System Limits — Decision Flow
Question Answer Tool to Use Header
Fixed by architecture/compiler? Yes (e.g. INT_MAX) Compile-time constant <limits.h>
System-wide, may vary per kernel? Yes (OPEN_MAX, NGROUPS_MAX) sysconf(_SC_...) <unistd.h>
Varies per filesystem/path? Yes (NAME_MAX, PATH_MAX) pathconf(path, _PC_...) <unistd.h>
Have an open fd, want fs limit? Yes (fd already open) fpathconf(fd, _PC_...) <unistd.h>
Optional POSIX feature present? Check compile + runtime #if _POSIX_THREADS > 0 or sysconf(_SC_THREADS) <unistd.h>
From the shell quickly? Yes getconf ARG_MAX CLI only

Five Rules to Remember

  1. Never hard-code limits — they change across kernels, filesystems, and hardware.
  2. Set errno = 0 before every sysconf/pathconf call — the only way to tell indeterminate from error.
  3. Use _PC_* with pathconf, _SC_* with sysconf — wrong prefix = EINVAL.
  4. NAME_MAX excludes the null byte, PATH_MAX includes it — add 1 to NAME_MAX for your buffer.
  5. POSIX option constant = 0 means “ask at runtime”; undefined or -1 means not supported.

Keep Learning Linux Systems Programming

This is part of the free Linux Systems Programming course on EmbeddedPathashala. Next up: process resource limits with setrlimit() and getrlimit().

Back to Course Index Linux Track →

Leave a Reply

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