st_dev and st_rdev members of 'stat struct' are not of dev_t type on mips/mipsel
Hi guys,
(I'm not subscribed to the list, so please CC)
After digging through the buildd logs of libisoburn, we found out
interesting compiler warnings on mips and mipsel.
https://buildd.debian.org/status/fetch.php?pkg=libisoburn&arch=mips&ver=1.1.8-1&stamp=1321892998
xorriso/iso_tree.c: In function 'Xorriso_fake_stbuf':
xorriso/iso_tree.c:256:4: warning: passing argument 4 of
'Xorriso_node_get_dev' from incompatible pointer type [enabled by
default]
xorriso/iso_tree.c:204:5: note: expected 'dev_t *' but argument is of
type 'long unsigned int *'
xorriso/iso_tree.c:259:4: warning: passing argument 4 of
'Xorriso_node_get_dev' from incompatible pointer type [enabled by
default]
xorriso/iso_tree.c:204:5: note: expected 'dev_t *' but argument is of
type 'long unsigned int *'
Which basically means that st_rdev member of stat struct is not of type
dev_t on mips and mipsel, which of course deviates from man 2 stat, that
prescribes that st_rdev member (as well as st_dev member) of stat struct
must be of type dev_t.
I wonder what could be wrong with the definition of the stat struct on
mips/mipsel, it is a known flaw in libc, and whether it has anything to
do with the situation of having 64-bit kernel and 32 bit userland,
usually met on misp/mipsel.
Yes, the issue could be solved in the application side if one knows
about the problem on these particular architectures (mips/mipsel), but I
believe this is not the general case.
A simplified code demonstrating the issue:
~~~~~~~~~~~~~~~~~~~~~~~~~~
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void func(dev_t *dev) {
*dev=2;
}
int main() {
struct stat ss;
ss.st_rdev = 1;
printf("ss.st_rdev %ld\n", ss.st_rdev);
func( & (ss.st_rdev) ); // protested on mips{el}
dev_t dummy = ss.st_rdev; // work-around with a temp dev_t
object
func(&dummy);
printf("ss.st_rdev %ld\n", ss.st_rdev);
printf("sizeof st_rdev %u\n", sizeof(ss.st_rdev));
printf("sizeof dev_t %u\n", sizeof(dev_t));
printf("sizeof __dev_t %u\n", sizeof(__dev_t));
printf("sizeof ul int %u\n", sizeof(unsigned long int));
printf("sizeof ull int %u\n", sizeof(unsigned long long int));
printf("sizeof stat %u\n", sizeof(ss));
return 0;
}
mips{el}
~~~~~~
$ gcc test.c
test.c: In function ‘main’:
test.c:14:2: warning: passing argument 1 of ‘func’ from incompatible
pointer type [enabled by default]
test.c:6:6: note: expected ‘dev_t *’ but argument is of type ‘long
unsigned int *’
$ ./a.out
ss.st_rdev 1
ss.st_rdev 2
sizeof st_rdev 4
sizeof dev_t 8
sizeof __dev_t 8
sizeof ul int 4
sizeof ull int 8
sizeof stat 144
amd64
~~~~
$ gcc test.c
$ ./a.out
ss.st_rdev 1
ss.st_rdev 2
sizeof st_rdev 8
sizeof dev_t 8
sizeof __dev_t 8
sizeof ul int 8
sizeof ull int 8
sizeof stat 144
I tried to trace this type deviation of the stat dev_t members in the
headers, but gave up, and tried to look at gcc -E output, where I
realize that dev_t type is 'unsigned long long int', where stat.st_rdev
is of type 'unsigned long int'
$ grep dev_t gcc-E
__extension__ typedef __u_quad_t __dev_t;
typedef __dev_t dev_t;
$ grep quad_t gcc-E
__extension__ typedef long long int __quad_t;
__extension__ typedef unsigned long long int __u_quad_t;
__extension__ typedef __u_quad_t __dev_t;
__extension__ typedef __u_quad_t __ino64_t;
__extension__ typedef __quad_t __off64_t;
__extension__ typedef __u_quad_t __rlim64_t;
__extension__ typedef __quad_t __blkcnt64_t;
__extension__ typedef __u_quad_t __fsblkcnt64_t;
__extension__ typedef __u_quad_t __fsfilcnt64_t;
typedef __quad_t *__qaddr_t;
typedef __quad_t quad_t;
typedef __u_quad_t u_quad_t;
--
pub 4096R/0E4BD0AB <people.fccf.net/danchev/key pgp.mit.edu>
Reply to: