Hi Alex, On 9/23/20 4:54 PM, Alejandro Colomar wrote: > These variables are either of an unsigned integer type per POSIX; > or of an integer type per POSIX, that Linux defines as an unsigned integer type. > > Print them with 'uintmax_t' instead of 'intmax_t' to avoid > big positive numbers being printed as negative numbers. > > Bug report: > From: Konstantin Bukin @ 2020-09-13 15:04 UTC > To: mtk.manpages; +Cc: Konstantin Bukin, linux-man > > 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. > > Reported-by: Konstantin Bukin <kbukin@xxxxxxxxx> > Signed-off-by: Alejandro Colomar <colomar.6.4.3@xxxxxxxxx> Thanks! Patch applied. Cheers, Michael > --- > > Hi Michael, > > I wrote a patch similar to Konstantin's patch, > but using `uintmax_t` as we discussed. > I further fixed a few more cases of incorrect casts. > I found all of those related to `struct stat`'s members, > but there may be more incorrect casts out there. > > Cheers, > > Alex > > man2/ioctl_ns.2 | 8 ++++---- > man2/stat.2 | 8 ++++---- > 2 files changed, 8 insertions(+), 8 deletions(-) > > diff --git a/man2/ioctl_ns.2 b/man2/ioctl_ns.2 > index b83db74e0..87b5168a7 100644 > --- a/man2/ioctl_ns.2 > +++ b/man2/ioctl_ns.2 > @@ -317,10 +317,10 @@ main(int argc, char *argv[]) > exit(EXIT_FAILURE); > } > printf("Device/Inode of owning user namespace is: " > - "[%jx,%jx] / %jd\en", > + "[%jx,%jx] / %ju\en", > (uintmax_t) major(sb.st_dev), > (uintmax_t) minor(sb.st_dev), > - (intmax_t) sb.st_ino); > + (uintmax_t) sb.st_ino); > > close(userns_fd); > } > @@ -347,10 +347,10 @@ main(int argc, char *argv[]) > perror("fstat\-parentns"); > exit(EXIT_FAILURE); > } > - printf("Device/Inode of parent namespace is: [%jx,%jx] / %jd\en", > + printf("Device/Inode of parent namespace is: [%jx,%jx] / %ju\en", > (uintmax_t) major(sb.st_dev), > (uintmax_t) minor(sb.st_dev), > - (intmax_t) sb.st_ino); > + (uintmax_t) sb.st_ino); > > close(parent_fd); > } > diff --git a/man2/stat.2 b/man2/stat.2 > index f71cc3831..13a1f37f7 100644 > --- a/man2/stat.2 > +++ b/man2/stat.2 > @@ -682,14 +682,14 @@ main(int argc, char *argv[]) > default: printf("unknown?\en"); break; > } > > - printf("I\-node number: %jd\en", (intmax_t) sb.st_ino); > + printf("I\-node number: %ju\en", (uintmax_t) sb.st_ino); > > printf("Mode: %jo (octal)\en", > (uintmax_t) sb.st_mode); > > - printf("Link count: %jd\en", (intmax_t) sb.st_nlink); > - printf("Ownership: UID=%jd GID=%jd\en", > - (intmax_t) sb.st_uid, (intmax_t) sb.st_gid); > + printf("Link count: %ju\en", (uintmax_t) sb.st_nlink); > + printf("Ownership: UID=%ju GID=%ju\en", > + (uintmax_t) sb.st_uid, (uintmax_t) sb.st_gid); > > printf("Preferred I/O block size: %jd bytes\en", > (intmax_t) sb.st_blksize); > -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Linux/UNIX System Programming Training: http://man7.org/training/