The fstat system call retrieves file status information from open file descriptors, helping processes verify attributes such as size, permissions, and timestamps. This mechanism is essential for filesystem integrity checks, access control, and efficient resource management across modern operating systems.
Understanding how fstat integrates with the broader I/O and process management stack clarifies why it appears in performance-sensitive paths and security-sensitive logic. The following sections dissect its behavior, performance aspects, and real-world implications for developers and system administrators.
| Field | Description | Typical Use | Related Structures |
|---|---|---|---|
| st_mode | File type and permission bits | Access control, file-type dispatch | S_ISREG, S_ISDIR macros |
| st_size | File size in bytes | I/O sizing, memory mapping | off_t type |
| st_atime | Last access timestamp | Caching, audit trails | struct timespec |
| st_mtime | Last modification timestamp | Build systems, synchronization | struct timespec |
| st_dev and st_ino | Device ID and inode number | File uniqueness, hard-link detection | Unique file identification |
Behavior in Single-Threaded Applications
Direct Descriptor Usage
In single-threaded programs, fstat operates directly on an open file descriptor, returning a snapshot of metadata without race conditions introduced by concurrent updates. The calling thread blocks only for the copy_from_kernel phase, making latency predictable.
Error Handling Paths
Applications must check for EBADF when descriptors originate from dynamic pools, and handle ENOTSUP for special files that do not support traditional metadata. Robust wrappers centralize these checks to simplify debugging.
Concurrency and Multi-Threaded Contexts
Shared Descriptor Table
In multi-threaded environments, file descriptors are shared across threads, so fstat reflects the state at the instant the kernel copies metadata. Threads should synchronize descriptor reuse to avoid closing a descriptor while another is executing fstat.
Stat Race Mitigations
To reduce TOCTOU risks, prefer using the file descriptor returned by open instead of path-based operations, and consider atomic check-then-act patterns via fcntl locks or dedicated I/O control commands where supported.
Security Considerations and Sandboxing
Privilege Boundaries
fstat can reveal sensitive information such as device numbers and inode identifiers, which may aid privilege escalation if exposed to less-trusted code. Sandboxed environments often restrict access or sanitize returned data before exposing it to untrusted components.
Capability-Based Access Control
Linux capabilities and file capabilities interact with fstat by allowing processes to perform operations beyond traditional permission checks. Security modules can further constrain which metadata fields a process is allowed to query.
Performance Profiling and System Tuning
Cost in Context Switches
Each fstat invocation triggers at least one user-to-kernel transition, and possibly additional cache lookups if the underlying inode is not hot in page cache. In latency-sensitive paths, batching or caching metadata can reduce overhead.
Filesystem-Specific Variance
Local filesystems typically complete fstat in microseconds, while network filesystems may exhibit higher and more variable latency. Tuning mount options such as actimeo or using client-side caching can influence observed performance characteristics.
Best Practices and Operational Recommendations
- Prefer file-descriptor-based metadata queries (fstat) over pathname-based lookups (stat) in security-sensitive or concurrency-sensitive code to reduce TOCTOU risk.
- Centralize error handling for EBADF, ENOTDIR, and ENOTSUP to keep permission and special-file logic consistent across the application.
- Cache stat data judiciously, and pair it with versioning via st_dev and st_ino to detect file replacement in long-running processes.
- Consider mount options and filesystem characteristics when designing latency-sensitive workflows that rely on fstat performance.
- Audit sandboxed or containerized environments for metadata leakage and apply least-privilege principles to filesystem access.
FAQ
Reader questions
Can fstat detect if a file has been deleted after opening it?
Yes, an open file descriptor remains valid after unlink on most Unix-like systems, and fstat on that descriptor will continue to return metadata. The nlink count in the stat structure will reflect the removal, and writing to the descriptor will still succeed until the last reference is closed.
What does a negative st_size indicate in fstat results?
Negative st_size values do not occur for regular files; a signed-off interpretation is unnecessary. If code mistakenly treats the field as unsigned, special file types such as pipes or sockets may expose unexpected bit patterns, which is a bug in interpretation rather than in the kernel output.
How does fstat differ from stat at the system call level?
fstat accepts a file descriptor, allowing metadata queries on open file references including those obtained via dup or inheritance. stat and lstat operate on pathnames, resolving symbolic links according to their specific semantics, while fstat bypasses path lookup entirely.
Is fstat safe to use with memory-mapped files across fork?
Yes, fstat on a descriptor for a memory-mapped file returns consistent metadata visible to mmap. After fork, both parent and child share the same descriptor unless close-on-exec is set, and changes to the underlying file size may or may not be visible depending on the filesystem and mapping flags.