On raspbian, I am trying to do stat/stat64
a large file: 5.4G /tmp/some.mpg
. Here's the code:
#include <stdio.h>
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <sys/stat.h>
int main(){
char filename[] = "/tmp/some.mpg";
struct stat64 myst;
int x = stat64(filename, &myst );
if ( x < 0 ){
printf("x is %d\n", x);
perror("stat failure");
}
printf("%s size: %ld\n", filename, myst.st_size);
return 0;
}
It it however displaying erroneous info when I run it:
$ gcc bigsize.c -D_FILE_OFFSET_BITS=64 -o bigsize
$ ./bigsize
/tmp/some.mpg size: 1435916040
$ ls -ltr /tmp/some.mpg
-rw-r--r-- 1 XXX YYYY 5730883336 Jul 27 08:44 /tmp/some.mpg
On x86_64
this seems to work OK, not on armv7l
Please show me the right way to accomplish this, thanks!
Update 1
this seems to work, after changing printf from ld
to llu
#include <stdio.h>
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <sys/stat.h>
int main(){
char filename[] = "/tmp/some.mpg";
struct stat64 myst;
int x = stat64(filename, &myst );
if ( x < 0 ){
printf("x is %d\n", x);
perror("stat failure");
}
printf("%s size: %llu\n", filename, myst.st_size);
return 0;
}
Update 2
This works, after reading up the answers:
#include <stdio.h>
#include <inttypes.h>
#define __USE_LARGEFILE64
#define _LARGEFILE_SOURCE
#define _LARGEFILE64_SOURCE
#include <sys/stat.h>
int main(){
char filename[] = "/tmp/some.mpg";
struct stat64 myst;
int x = stat64(filename, &myst );
if ( x < 0 ){
printf("x is %d\n", x);
perror("stat failure");
}
printf("%s size: %llu\n", filename, myst.st_size);
printf("%s size: %jd\n", filename, (intmax_t)myst.st_size);
printf("file %s is %" PRIdMAX " bytes.\n", filename, (intmax_t)myst.st_size);
return 0;
}
Compiled thusly:
$ gcc bigsize.c -o bigsize -Wall -Wextra ; echo $?
0
Run:
$ ./bigsize
/tmp/some.mpg size: 5730883336
/tmp/some.mpg size: 5730883336
file /tmp/some.mpg is 5730883336 bytes.
Thanks to all!
The issue is you telling printf()
that you're giving it an argument that's a long
, but then actually passing it an argument that is in this case a long long
, causing undefined behavior when the two types are different sizes. It works on the x86_64 system because long
and long long
are both 64-bit, but I bet the arm system uses 32-bit long
s and 64-bit long long
s.
One portable approach when you don't know the exact type to print out is to cast it to the largest possible one (intmax_t
from <stdint.h>
, and use the print macros from <inttypes.h>
to display it:
printf("file %s is %" PRIdMAX " bytes.\n", filename, (intmax_t)myst.st_size);