vsis A bit fiddly, this. lseek(2)
should work on disk-type devices on the *BSDs and Linux, but, you'll have to open(2)
them first:
#ifdef USE_FSTAT
#include <sys/stat.h>
#endif
#include <err.h>
#include <fcntl.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char* argv[])
{
char* dev;
off_t sz;
int fd, rc = EXIT_FAILURE;
setlocale(LC_ALL, ""); /* %' fmt conv. */
if (argc != 2)
errx(rc, "Usage: %s blkdev", argv[0]);
dev = argv[1];
if ((fd = open(dev, O_RDONLY | O_NONBLOCK)) == -1)
err(rc, "%s: open failed", dev);
#ifdef USE_FSTAT /* on NetBSD 11+ */
struct stat st;
if (fstat(fd, &st) == -1)
err(rc, "%s: fstat failed", dev);
sz = st.st_size;
#else
if ((sz = lseek(fd, 0, SEEK_END)) == -1)
err(rc, "%s: lseek failed", dev);
#endif
close(fd);
printf("%'zd\n", sz);
return 0;
}
On -HEAD, you can stat -f %z /dev/rXXX
; that should return the sizes for all the devices on which open(2)
has been called (one way or another).