Please commit Cheers Carmelo Inviato da iPod
Il giorno 04/feb/2012, alle ore 05:42, Khem Raj <[email protected]> ha scritto: > This is needed for stat'ing loop devices > 255 > since otherwise kernel returns EOVERFLOW becasue > it needs st_rdev/st_dev to be larger than 16bits but > in kernel it uses __old_kernel_stat for stat > syscall which has st_rdev/st_dev as unsigned short > > Add a testcase > > Signed-off-by: Khem Raj <[email protected]> > --- > libc/sysdeps/linux/common/fstat.c | 18 ++++++++++++++---- > libc/sysdeps/linux/common/lstat.c | 19 ++++++++++++++----- > libc/sysdeps/linux/common/stat.c | 18 ++++++++++++++---- > test/stat/stat-loop256.c | 32 ++++++++++++++++++++++++++++++++ > 4 files changed, 74 insertions(+), 13 deletions(-) > create mode 100644 test/stat/stat-loop256.c > > diff --git a/libc/sysdeps/linux/common/fstat.c > b/libc/sysdeps/linux/common/fstat.c > index acc639b..4726a68 100644 > --- a/libc/sysdeps/linux/common/fstat.c > +++ b/libc/sysdeps/linux/common/fstat.c > @@ -12,18 +12,28 @@ > #include <sys/stat.h> > #include "xstatconv.h" > > -#define __NR___syscall_fstat __NR_fstat > -static __inline__ _syscall2(int, __syscall_fstat, int, fd, struct > kernel_stat *, buf) > - > int fstat(int fd, struct stat *buf) > { > int result; > +#ifdef __NR_fstat64 > + /* normal stat call has limited values for various stat elements > + * e.g. uid device major/minor etc. > + * so we use 64 variant if available > + * in order to get newer versions of stat elements > + */ > + struct kernel_stat64 kbuf; > + result = INLINE_SYSCALL(fstat64, 2, fd, &kbuf); > + if (result == 0) { > + __xstat32_conv(&kbuf, buf); > + } > +#else > struct kernel_stat kbuf; > > - result = __syscall_fstat(fd, &kbuf); > + result = INLINE_SYSCALL(fstat, 2, fd, &kbuf); > if (result == 0) { > __xstat_conv(&kbuf, buf); > } > +#endif > return result; > } > libc_hidden_def(fstat) > diff --git a/libc/sysdeps/linux/common/lstat.c > b/libc/sysdeps/linux/common/lstat.c > index aa77447..db72d1f 100644 > --- a/libc/sysdeps/linux/common/lstat.c > +++ b/libc/sysdeps/linux/common/lstat.c > @@ -12,19 +12,28 @@ > #include <sys/stat.h> > #include "xstatconv.h" > > -#define __NR___syscall_lstat __NR_lstat > -static __inline__ _syscall2(int, __syscall_lstat, > - const char *, file_name, struct kernel_stat *, buf) > - > int lstat(const char *file_name, struct stat *buf) > { > int result; > +#ifdef __NR_lstat64 > + /* normal stat call has limited values for various stat elements > + * e.g. uid device major/minor etc. > + * so we use 64 variant if available > + * in order to get newer versions of stat elements > + */ > + struct kernel_stat64 kbuf; > + result = INLINE_SYSCALL(lstat64, 2, file_name, &kbuf); > + if (result == 0) { > + __xstat32_conv(&kbuf, buf); > + } > +#else > struct kernel_stat kbuf; > > - result = __syscall_lstat(file_name, &kbuf); > + result = INLINE_SYSCALL(lstat, 2, file_name, &kbuf); > if (result == 0) { > __xstat_conv(&kbuf, buf); > } > +#endif > return result; > } > libc_hidden_def(lstat) > diff --git a/libc/sysdeps/linux/common/stat.c > b/libc/sysdeps/linux/common/stat.c > index a6ab291..829f35a 100644 > --- a/libc/sysdeps/linux/common/stat.c > +++ b/libc/sysdeps/linux/common/stat.c > @@ -12,20 +12,30 @@ > #include <sys/stat.h> > #include "xstatconv.h" > > -#define __NR___syscall_stat __NR_stat > #undef stat > -static __inline__ _syscall2(int, __syscall_stat, > - const char *, file_name, struct kernel_stat *, buf) > > int stat(const char *file_name, struct stat *buf) > { > int result; > +#ifdef __NR_stat64 > + /* normal stat call has limited values for various stat elements > + * e.g. uid device major/minor etc. > + * so we use 64 variant if available > + * in order to get newer versions of stat elements > + */ > + struct kernel_stat64 kbuf; > + result = INLINE_SYSCALL(stat64, 2, file_name, &kbuf); > + if (result == 0) { > + __xstat32_conv(&kbuf, buf); > + } > +#else > struct kernel_stat kbuf; > > - result = __syscall_stat(file_name, &kbuf); > + result = INLINE_SYSCALL(stat, 2, file_name, &kbuf); > if (result == 0) { > __xstat_conv(&kbuf, buf); > } > +#endif > return result; > } > libc_hidden_def(stat) > diff --git a/test/stat/stat-loop256.c b/test/stat/stat-loop256.c > new file mode 100644 > index 0000000..14284c1 > --- /dev/null > +++ b/test/stat/stat-loop256.c > @@ -0,0 +1,32 @@ > +#include <stdio.h> > +#include <unistd.h> > +#include <stdlib.h> > +#include <sys/stat.h> > +int main() > +{ > + struct stat statbuf; > + int ret = 0; > + char* loop255 = "/dev/loop255"; > + char* loop256 = "/dev/loop256"; > + mode_t mode = 0660; > + mknod(loop255, mode, 0x7ff); > + mknod(loop256, mode, 0x100700); > + ret = stat(loop255, &statbuf); > + if(ret < 0) { > + printf("stat: Cant stat %s\n",loop255); > + unlink(loop255); > + exit(1); > + } > + ret = stat(loop256, &statbuf); > + if(ret < 0) { > + printf("stat: Cant stat %s\n",loop256); > + unlink(loop255); > + unlink(loop256); > + exit(1); > + } > + > + unlink(loop255); > + unlink(loop256); > + exit(0); > +} > + > -- > 1.7.5.4 > > _______________________________________________ > uClibc mailing list > [email protected] > http://lists.busybox.net/mailman/listinfo/uclibc _______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
