Linux – Determine free space available on a USB flash drive in C (linux)

clinuxsystem-callsusbusb-drive

I would like to figure out the available free space on a USB flash drive in a C program in Linux. I have earlier used system("df -h /dev/sda1") to figure it out but using system command in a Linux C application is causing some timing issues. Hence need to know how to determine available free space using any other kind of system call/library function.

Best Answer

For a mounted USB flash drive, you can do this via statvfs(3) function, where you need to provide path to the mountpoint, and you basically have a small version of df (which also btw only operates on mounted filesystems):

$ cat fs_usage.c 
#include <stdio.h>
#include <sys/statvfs.h>

int main(int argc, char **argv){

    struct statvfs fs_usage;
    statvfs(argv[1],&fs_usage);
    printf("%s:%f bytes available, %f bytes used\n",argv[1],
                fs_usage.f_frsize*(double)fs_usage.f_bavail,
                fs_usage.f_frsize * (double)(fs_usage.f_blocks - fs_usage.f_bfree));
    return 0;
}
$ gcc fs_usage.c -o fs_usage
$ df -B 1 /mnt/ubuntu
Filesystem        1B-blocks         Used  Available Use% Mounted on
/dev/sdb1      118013599744 105134329856 6860865536  94% /mnt/ubuntu
$ ./fs_usage /mnt/ubuntu/
/mnt/ubuntu/:6860865536.000000 bytes available, 105134329856.000000 bytes used

Note also that statvfs() takes const char *path as one of the parameters, and that can be pathname of any file within the filesystem, e.g. /dev/sda7 will return usage of /dev filesystem ( because it is in fact one of virtual filesystems ), and not the sda7 partition of a device.

Note that I am using f_frsize here, which is equivalent to f_bsize, however in some filesystems fragment size may be smaller than block size. See https://unix.stackexchange.com/a/463370/85039 for details


If your C library (usually glibc but on an embedded platform might be something else) implements statvfs(3) in a way that's too slow for you, then you should probably use the underlying statfs(2) or fstatfs(2) system calls directly instead.

Related Question