[uClibc-cvs] uClibc/libc/sysdeps/linux/common xstatconv.c,NONE,1.1 syscalls.c,1.94,1.95

Erik Andersen andersen at codepoet.org
Fri Jan 24 11:44:38 UTC 2003


Update of /var/cvs/uClibc/libc/sysdeps/linux/common
In directory winder:/tmp/cvs-serv18234/libc/sysdeps/linux/common

Modified Files:
	syscalls.c 
Added Files:
	xstatconv.c 
Log Message:
Ok, people are probably going to hate me for this...  This commit changes the
type of 'struct stat' and 'struct stat64' so they use consistant types.  

This change is the result of a bug I found while trying to use GNU tar.  The
problem was caused by our using kernel types within struct stat and trying to
directly compare these values with standard types.  Trying an 'if (a < b)' when
'a' is an 'unsigned long' and 'b' is an 'int' leads to very different results
then when comparing entities of the same type (i.e. time_t values)....
Grumble.  Nasty stuff, but I'm glad I got this out of the way now.

As a result of this fix, uClibc 0.9.17 will not be binary compatible with
earlier releases.  I have always warned people this can and will happen.
 -Erik


--- NEW FILE: xstatconv.c ---
/* Convert between the kernel's `struct stat' format, and libc's.
   Copyright (C) 1991,1995,1996,1997,2000,2002 Free Software Foundation, Inc.
   This file is part of the GNU C Library.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA. 
   
   Modified for uClibc by Erik Andersen <andersen at codepoet.org>
   */

static inline void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf)
{
    /* Convert to current kernel version of `struct stat'.  */
    buf->st_dev = kbuf->st_dev;
#ifdef _HAVE_STAT___PAD1
    buf->__pad1 = 0;
#endif
    buf->st_ino = kbuf->st_ino;
    buf->st_mode = kbuf->st_mode;
    buf->st_nlink = kbuf->st_nlink;
    buf->st_uid = kbuf->st_uid;
    buf->st_gid = kbuf->st_gid;
    buf->st_rdev = kbuf->st_rdev;
#ifdef _HAVE_STAT___PAD2
    buf->__pad2 = 0;
#endif
    buf->st_size = kbuf->st_size;
    buf->st_blksize = kbuf->st_blksize;
    buf->st_blocks = kbuf->st_blocks;
    buf->st_atime = kbuf->st_atime;
#ifdef _HAVE_STAT___UNUSED1
    buf->__unused1 = 0;
#endif
    buf->st_mtime = kbuf->st_mtime;
#ifdef _HAVE_STAT___UNUSED2
    buf->__unused2 = 0;
#endif
    buf->st_ctime = kbuf->st_ctime;
#ifdef _HAVE_STAT___UNUSED3
    buf->__unused3 = 0;
#endif
#ifdef _HAVE_STAT___UNUSED4
    buf->__unused4 = 0;
#endif
#ifdef _HAVE_STAT___UNUSED5
    buf->__unused5 = 0;
#endif
}

static inline void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf)
{
    /* Convert to current kernel version of `struct stat64'.  */
    buf->st_dev = kbuf->st_dev;
#ifdef _HAVE_STAT64___PAD1
    buf->__pad1 = 0;
#endif
    buf->st_ino = kbuf->st_ino;
#ifdef _HAVE_STAT64___ST_INO
    buf->__st_ino = kbuf->st_ino;
#endif
    buf->st_mode = kbuf->st_mode;
    buf->st_nlink = kbuf->st_nlink;
    buf->st_uid = kbuf->st_uid;
    buf->st_gid = kbuf->st_gid;
    buf->st_rdev = kbuf->st_rdev;
#ifdef _HAVE_STAT64___PAD2
    buf->__pad2 = 0;
#endif
    buf->st_size = kbuf->st_size;
    buf->st_blksize = kbuf->st_blksize;
    buf->st_blocks = kbuf->st_blocks;
    buf->st_atime = kbuf->st_atime;
#ifdef _HAVE_STAT64___UNUSED1
    buf->__unused1 = 0;
#endif
    buf->st_mtime = kbuf->st_mtime;
#ifdef _HAVE_STAT64___UNUSED2
    buf->__unused2 = 0;
#endif
    buf->st_ctime = kbuf->st_ctime;
#ifdef _HAVE_STAT64___UNUSED3
    buf->__unused3 = 0;
#endif
#ifdef _HAVE_STAT64___UNUSED4
    buf->__unused4 = 0;
#endif
#ifdef _HAVE_STAT64___UNUSED5
    buf->__unused5 = 0;
#endif
}


Index: syscalls.c
===================================================================
RCS file: /var/cvs/uClibc/libc/sysdeps/linux/common/syscalls.c,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -d -r1.94 -r1.95
--- syscalls.c	22 Jan 2003 17:43:11 -0000	1.94
+++ syscalls.c	24 Jan 2003 11:44:03 -0000	1.95
@@ -156,9 +156,17 @@
 #endif
 
 //#define __NR_mknod            14
-#ifdef L_mknod
+#ifdef L___syscall_mknod
+#define __NR___syscall_mknod __NR_mknod
 #include <sys/stat.h>
-_syscall3(int, mknod, const char *, path, mode_t, mode, dev_t, dev);
+_syscall3(int, __syscall_mknod, const char *, path, __kernel_mode_t, mode, __kernel_dev_t, dev);
+int mknod(const char *path, mode_t mode, dev_t dev)
+{ 
+	__kernel_dev_t k_dev;
+	/* We must convert the dev_t value to a __kernel_dev_t */
+	k_dev = ((major(dev) & 0xff) << 8) | (minor(dev) & 0xff);
+	return __syscall_mknod(path, mode, k_dev);
+}
 #endif
 
 //#define __NR_chmod            15
@@ -958,30 +966,69 @@
 #endif
 
 //#define __NR_stat             106
-#ifdef L_stat
+#ifdef L___syscall_stat
+#define __NR___syscall_stat __NR_stat
 #include <unistd.h>
 #include <sys/stat.h>
-_syscall2(int, stat, const char *, file_name, struct stat *, buf);
+#include <bits/kernel_stat.h>
+#include "xstatconv.c"
+_syscall2(int, __syscall_stat, const char *, file_name, struct kernel_stat *, buf);
+int stat(const char * file_name, struct stat * buf)
+{
+	int result;
+	struct kernel_stat kbuf;
+	result = __syscall_stat(file_name, &kbuf);
+	if (result == 0) {
+		__xstat_conv(&kbuf, buf);
+	}
+	return result;
+}
 #if ! defined __NR_stat64 && defined __UCLIBC_HAS_LFS__
 weak_alias(stat, stat64);
 #endif
 #endif
 
 //#define __NR_lstat            107
-#ifdef L_lstat
+#ifdef L___syscall_lstat
+#define __NR___syscall_lstat __NR_lstat
 #include <unistd.h>
 #include <sys/stat.h>
-_syscall2(int, lstat, const char *, file_name, struct stat *, buf);
+#include <bits/kernel_stat.h>
+#include "xstatconv.c"
+_syscall2(int, __syscall_lstat, const char *, file_name, struct kernel_stat *, buf);
+int lstat(const char * file_name, struct stat * buf)
+{
+	int result;
+	struct kernel_stat kbuf;
+	result = __syscall_lstat(file_name, &kbuf);
+	if (result == 0) {
+		__xstat_conv(&kbuf, buf);
+	}
+	return result;
+}
 #if ! defined __NR_lstat64 && defined __UCLIBC_HAS_LFS__
 weak_alias(lstat, lstat64);
 #endif
 #endif
 
 //#define __NR_fstat            108
-#ifdef L_fstat
+#ifdef L___syscall_fstat
+#define __NR___syscall_fstat __NR_fstat
 #include <unistd.h>
 #include <sys/stat.h>
-_syscall2(int, fstat, int, filedes, struct stat *, buf);
+#include <bits/kernel_stat.h>
+#include "xstatconv.c"
+_syscall2(int, __syscall_fstat, int, fd, struct kernel_stat *, buf);
+int fstat(int fd, struct stat * buf)
+{
+	int result;
+	struct kernel_stat kbuf;
+	result = __syscall_fstat(fd, &kbuf);
+	if (result == 0) {
+		__xstat_conv(&kbuf, buf);
+	}
+	return result;
+}
 #if ! defined __NR_fstat64 && defined __UCLIBC_HAS_LFS__
 weak_alias(fstat, fstat64);
 #endif
@@ -1623,29 +1670,68 @@
 
 
 //#define __NR_stat64             195
-#ifdef L_stat64
+#ifdef L___syscall_stat64
 #if defined __NR_stat64 && defined __UCLIBC_HAS_LFS__
+#define __NR___syscall_stat64 __NR_stat64
 #include <unistd.h>
 #include <sys/stat.h>
-_syscall2(int, stat64, const char *, file_name, struct stat64 *, buf);
+#include <bits/kernel_stat.h>
+#include "xstatconv.c"
+_syscall2(int, __syscall_stat64, const char *, file_name, struct kernel_stat64 *, buf);
+int stat64(const char * file_name, struct stat64 * buf)
+{
+	int result;
+	struct kernel_stat64 kbuf;
+	result = __syscall_stat64(file_name, &kbuf);
+	if (result == 0) {
+		__xstat64_conv(&kbuf, buf);
+	}
+	return result;
+}
 #endif /* __UCLIBC_HAS_LFS__ */
 #endif
 
 //#define __NR_lstat64            196
-#ifdef L_lstat64
+#ifdef L___syscall_lstat64
 #if defined __NR_lstat64 && defined __UCLIBC_HAS_LFS__
+#define __NR___syscall_lstat64 __NR_lstat64
 #include <unistd.h>
 #include <sys/stat.h>
-_syscall2(int, lstat64, const char *, file_name, struct stat64 *, buf);
+#include <bits/kernel_stat.h>
+#include "xstatconv.c"
+_syscall2(int, __syscall_lstat64, const char *, file_name, struct kernel_stat64 *, buf);
+int lstat64(const char * file_name, struct stat64 * buf)
+{
+	int result;
+	struct kernel_stat64 kbuf;
+	result = __syscall_lstat64(file_name, &kbuf);
+	if (result == 0) {
+		__xstat64_conv(&kbuf, buf);
+	}
+	return result;
+}
 #endif /* __UCLIBC_HAS_LFS__ */
 #endif
 
 //#define __NR_fstat64            197
-#ifdef L_fstat64
+#ifdef L___syscall_fstat64
 #if defined __NR_fstat64 && defined __UCLIBC_HAS_LFS__
+#define __NR___syscall_fstat64 __NR_fstat64
 #include <unistd.h>
 #include <sys/stat.h>
-_syscall2(int, fstat64, int, filedes, struct stat64 *, buf);
+#include <bits/kernel_stat.h>
+#include "xstatconv.c"
+_syscall2(int, __syscall_fstat64, int, filedes, struct kernel_stat64 *, buf);
+int fstat64(int fd, struct stat64 * buf)
+{
+	int result;
+	struct kernel_stat64 kbuf;
+	result = __syscall_fstat64(fd, &kbuf);
+	if (result == 0) {
+		__xstat64_conv(&kbuf, buf);
+	}
+	return result;
+}
 #endif /* __UCLIBC_HAS_LFS__ */
 #endif
 




More information about the uClibc-cvs mailing list