On x86 the size of ino_t does not appear to be larger than long. It is 4 in 32-bit programs and 8 in 64-bit programs. On what platforms the size of ino_t is larger than long? Here is the beginning of memory taken by struct stat sb in 32-bit example program run on my file: (gdb) x/8xw &sb 0xffffd0d8: 0x00400080 0x00000000 0x00ca0000 0x006901c0 0xffffd0e8: 0x00008124 0x00000001 0x00000ab7 0x0000001e The first eight bytes is st_dev. 0x006901c0 are the lower 4 bytes of inode. I am not sure what 0x00ca0000 is. Is that just padding? For comparison, here is the beginning of memory taken by struct stat sb in 64-bit example programs run on the same file: (gdb) x/8xw &sb 0x7fffffffdf30: 0x00400080 0x00000000 0x006901c0 0x80cc2dc6 0x7fffffffdf40: 0x00000001 0x00000000 0x00008124 0x00000ab7 0x006901c0 and 0x80cc2dc6 are lower and upper 4 bytes of the inode. 0x80cc2dc6006901c0 is what “ls -li” reports, but in decimal. On Sun, Sep 13, 2020 at 8:16 AM Dmitry V. Levin <ldv@xxxxxxxxxxxx> wrote: > > On Sun, Sep 13, 2020 at 08:04:49AM -0700, Konstantin Bukin wrote: > > inode numbers are expected to be positive. Casting them to a signed type > > may result in printing negative values. E.g. running example program on > > the following file: > > > > $ ls -li test.txt > > 9280843260537405888 -r--r--r-- 1 kbukin hardware 300 Jul 21 06:36 test.txt > > > > resutls in the following output: > > > > $ ./example test.txt > > ID of containing device: [0,480] > > File type: regular file > > I-node number: -9165900813172145728 > > Mode: 100444 (octal) > > Link count: 1 > > Ownership: UID=2743 GID=30 > > Preferred I/O block size: 32768 bytes > > File size: 300 bytes > > Blocks allocated: 8 > > Last status change: Tue Jul 21 06:36:50 2020 > > Last file access: Sat Sep 12 14:13:38 2020 > > Last file modification: Tue Jul 21 06:36:50 2020 > > > > Such erroneous reporting happens for inode values greater than maximum > > value which can be stored in signed long. Casting does not seem to be > > necessary here. Printing inode as unsigned long fixes the issue. > > --- > > man2/stat.2 | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/man2/stat.2 b/man2/stat.2 > > index 7e5417480..76997bcbe 100644 > > --- a/man2/stat.2 > > +++ b/man2/stat.2 > > @@ -681,7 +681,7 @@ main(int argc, char *argv[]) > > default: printf("unknown?\en"); break; > > } > > > > - printf("I\-node number: %ld\en", (long) sb.st_ino); > > + printf("I\-node number: %lu\en", sb.st_ino); > > By the way, the type of st_ino is ino_t which might be larger than long, > so both the old and the new variants are not correct. > > > -- > ldv