Statx Versus Stat

Statx is a newer version of the stat syscall. It has a few improvements including the ability to request specific information rather than the whole kit & kaboodle making it faster in certain cases than stat and also has support for showing attributes like whether or not a file is compressed, encrypted or immutable.

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

int main() {
    const char *filename = "test.txt";

    struct stat old_statbuf;

    if (stat(filename, &old_statbuf) == 0) {
        printf("[stat]  File Size: %lld bytes\n", (long long)old_statbuf.st_size);
    } else {
        perror("stat failed");
    }

    struct statx new_statbuf;

    int result = statx(AT_FDCWD, filename, AT_STATX_SYNC_AS_STAT, STATX_SIZE, &new_statbuf);

    if (result == 0) {
        if (new_statbuf.stx_mask & STATX_SIZE) {
            printf("[statx] File Size: %llu bytes\n", (unsigned long long)new_statbuf.stx_size);
        }
    } else {
        perror("statx failed");
    }

    return 0;
}

You can see the ability to single out individual fields in action if we turn on tracing and compare our newfstatat to the stx_mask as shown in statx:

[2] newfstatat(-100, "test.txt", [{st_ino=0xffffbcc000000880, st_mode=0x81ff, st_size=5}], 0) = 0
[2] fstat(1, [{st_ino=0x0, st_mode=0x21ff, st_size=0}]) = 0
[2] getrandom() = 8
[2] brk(0x0000000000000000) = 0x924000
[2] brk(0x0000000000945000) = 0x945000
[stat]  File Size: 5 bytes
[2] write(1, 0x00000000009242a0, 27) = 27
[2] statx(-100, "test.txt", 0x0, STATX_SIZE, [{stx_mask=STATX_TYPE|STATX_MODE|STATX_INO|STATX_SIZE|STATX_BLOCKS|STATX_DIOALIGN, stx_mode=0x81ff, stx_ino=18446670131552585856, stx_size=5, stx_blocks=1, stx_dio_mem_align=512, stx_dio_offset_align=512, stx_blksize=4096, stx_rdev_major=0, stx_rdev_minor=0}]) = 0

newfstatat is actually what glibc calls when you call stat.

We added statx a while back ago as node.js, deno and other javascript runtimes utilize libuv which started using it. Stat also has a so-called year 2038 problem but nanos has never supported 32 bit and even linux is starting to rid itself of 32 bit support. Statx now even has support for reporting direct i/o alignment details and subvolume identifers.

While you might never call statx yourself there's a good chance various higher level software you use might end up calling a library that does call it and now nanos supports it.

Stop Deploying 50 Year Old Systems

Introducing the future cloud.

Ready for the future cloud?

Ready for the revolution in operating systems we've all been waiting for?

Schedule a Demo