diff options
32 files changed, 711 insertions, 259 deletions
@@ -1,7 +1,7 @@ List of known bugs (certainly very incomplete) ---------------------------------------------- -Time-stamp: <1997-10-25T06:32:15+0200 drepper> +Time-stamp: <1997-10-31T16:49:39+0100 drepper> This following list contains those bugs which I'm aware of. Please make sure that bugs you report are not listed here. If you can fix one @@ -36,12 +36,6 @@ Severity: [ *] to [***] flag was given. [PR libc/72] -[ *] On Linux, the <linux/posix_types.h> is not clean enough to satisfy - the C++ namespace rules. Declaring `struct fd_set' also makes - `fd_set' available in the global namespace which conflicts with - the definition of `fd_set' in glibc. - [PR libc/79] - [ *] On Linux, there should be a way to prevent defining the symbol NGROUPS_MAX in the <linux/limits.h> header file. In glibc it is defined in <posix1_lim.h> which must not make the other @@ -69,13 +63,6 @@ Severity: [ *] to [***] with gcc. This seems to be a bug in gcc 2.7.2.x (egcs doesn't have this bug). [PR libc/245] - -[ *] gethostbyname returns HOST_NOT_FOUND if the nameserver is - unreachable and nsswitch.conf contains a line with: - hosts: files dns - If the only method is dns gethostbyname return - TRY_AGAIN. gethostbyname should return in both cases TRY_AGAIN. - [PR libc/244] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Ulrich Drepper drepper@cygnus.com @@ -1,3 +1,85 @@ +1997-10-31 23:16 Ulrich Drepper <drepper@cygnus.com> + + * posix/glob.c (glob): If calling glob_in_dir for a list which was + generated by a glob call disable GLOB_ERR since there might be + non-directories in the list (PR203). + + * posix/glob.h (GLOB_ONLYDIR): New flag. + (__GLOB_FLAGS): Add GLOB_ONLYDIR. + * posix/glob.c: Define HAVE_D_TYPE if _DIRENT_HAVE_D_TYPE is defined. + (glob): Add GLOB_ONLYDIR to recursive call to match dirname. + (glob_in_dir) [HAVE_D_TYPE]: While reading directory entries test + whether they are directories if GLOB_ONLYDIR flag is given. + * manual/pattern.texi: Document GLOB_ONLYDIR. + + * misc/Makefile (tests): Add tst-fdset. + + * sysdeps/i386/bits/select.h: Rewrite asm macros to be cleaner. + + * sysdeps/unix/sysv/linux/Dist: Add xstatconv.c. + * sysdeps/unix/sysv/linux/alpha/Dist: Likewise. + + * time/strptime.c (strptime_internal): In %y format, regard years + >= 69 as of twentieth century, all other as of twenty-first. + + * time/tzset.c: Correct typo and little optimization. + +1997-10-31 16:01 Ulrich Drepper <drepper@cygnus.com> + + * inet/getnetgrent.c: Allocate buffer dynamically if needed. + Suggested by Joe Keane <jgk@jgk.org>. + +1997-10-31 Andreas Jaeger <aj@arthur.rhein-neckar.de> + + * io/ftw.h: Declare __ftw64_func_t and __nftw64_func_t only when + __USE_FILE_OFFSET64 || __USE_LARGEFILE64 is true. + +1997-10-30 05:47 Ulrich Drepper <drepper@cygnus.com> + + * misc/mntent.c: Don't use statically allocated buffer. Allocate + it dynamically if necessary. + * misc/efgcvt.c: Likewise. + Patch by Joe Keane <jgk@jgk.org>. + + * misc/mntent.c: Allow freeing of allocated buffer in + __libc_subfreeres. + * misc/efgcvt.c: Likewise. + + * misc/efgcvt.c: Call correct reentrant functions. + Use better values for MAXDIG. + * misc/qefgcvt.c: Use better values for MAXDIG. + +1997-10-29 18:48 Richard Henderson <rth@cygnus.com> + + * sysdeps/unix/sysv/linux/Makefile [io]: Add xstatconv. + * sysdeps/unix/sysv/linux/alpha/xstatconv.c: New file. Convert + between kernel_stat and the userland version indicated. + * sysdeps/unix/sysv/linux/xstatconv.c: Likewise. + * sysdeps/unix/sysv/linux/bits/stat.h: Define _STAT_VER_KERNEL. + + * sysdeps/unix/sysv/linux/fxstat.c: Defer to __xstat_conv. Alias + to __*xstat64 if requested. + * sysdeps/unix/sysv/linux/lxstat.c: Likewise. + * sysdeps/unix/sysv/linux/xstat.c: Likewise. + + * sysdeps/unix/sysv/linux/alpha/bits/stat.h: Add struct stat64. + Increment _STAT_VER, and make struct stat the same. + * sysdeps/unix/sysv/linux/alpha/bits/types.h: Add __ino64_t, and + __off64_t. Reorganize. + * sysdeps/unix/sysv/linux/alpha/kernel_stat.h: Add struct glibc2_stat + for backward compatibility. Define XSTAT_IS_XSTAT64. + + * sysdeps/unix/sysv/linux/alpha/fxstat64.c: Empty file. + * sysdeps/unix/sysv/linux/alpha/lxstat64.c: Likewise. + * sysdeps/unix/sysv/linux/alpha/xstat64.c: Likewise. + + * sysdeps/unix/sysv/linux/alpha/bits/dirent.h (struct dirent): For + consistency, force d_ino to use ino_t and supply padding. + +1997-10-29 18:47 Richard Henderson <rth@cygnus.com> + + * libio/iofopen.c: Correct weak_alias. + 1997-10-29 Andreas Jaeger <aj@arthur.rhein-neckar.de> * Makerules (install): Correct last patch. @@ -100,6 +100,10 @@ please let me know. [Q28] ``After upgrading to a glibc 2.1 with symbol versioning I get errors about undefined symbols. What went wrong?'' + +[Q29] ``I don't include any kernel header myself but still the + compiler complains about type redeclarations of types in the + kernel headers.'' ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ [Q1] ``What systems does the GNU C Library run on?'' @@ -116,6 +120,8 @@ in the future are: m68k-*-linux-gnu Linux-2.0 on Motorola 680x0 alpha-*-linux-gnu Linux-2.0 on DEC Alpha powerpc-*-linux-gnu Linux and MkLinux on PowerPC systems + sparc-*-linux-gnu Linux-2.0 on SPARC + sparc64-*-linux-gnu Linux-2.0 on UltraSPARC Other Linux platforms are also on the way to be supported but I need some success reports first. @@ -756,6 +762,21 @@ with symbol versioning. ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ +[Q29] ``I don't include any kernel header myself but still the + compiler complains about type redeclarations of types in the + kernel headers.'' + +[A29] {UD} The kernel headers before Linux 2.1.61 don't work correctly with +glibc since they pollute the name space in a not acceptable way. Compiling +C programs is possible in most cases but especially C++ programs have (due +to the change of the name lookups for `struct's) problem. One prominent +example is `struct fd_set'. + +There might be some more problems left but 2.1.61 fixes some of the known +ones. See the BUGS file for other known problems. + + +~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Answers were given by: {UD} Ulrich Drepper, <drepper@cygnus.com> diff --git a/inet/getnetgrent.c b/inet/getnetgrent.c index c310e01..88b06ff 100644 --- a/inet/getnetgrent.c +++ b/inet/getnetgrent.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1996 Free Software Foundation, Inc. +/* Copyright (C) 1996, 1997 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 @@ -16,13 +16,48 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include <errno.h> #include <netdb.h> +#include <stdlib.h> +#include <bits/libc-lock.h> +/* Statis buffer for return value. We allocate it when needed. */ +static char *buffer; +/* All three strings should fit in a block of 1kB size. */ +#define BUFSIZE 1024 + + + +static void +allocate (void) +{ + buffer = (char *) malloc (BUFSIZE); +} int getnetgrent (char **hostp, char **userp, char **domainp) { - static char buffer[1024]; /* All three strings shouldn't use 1kB. */ + __libc_once_define (static, once); + __libc_once (once, allocate); + + if (buffer == NULL) + { + __set_errno (ENOMEM); + return -1; + } - return __getnetgrent_r (hostp, userp, domainp, buffer, sizeof (buffer)); + return __getnetgrent_r (hostp, userp, domainp, buffer, BUFSIZE); } + + +/* Make sure the memory is freed if the programs ends while in + memory-debugging mode and something actually was allocated. */ +static void +__attribute__ ((unused)) +free_mem (void) +{ + if (buffer != NULL) + free (buffer); +} + +text_set_element (__libc_subfreeres, free_mem); @@ -88,16 +88,20 @@ struct FTW /* Convenient types for callback functions. */ typedef int (*__ftw_func_t) __P ((__const char *__filename, __const struct stat *__status, int __flag)); +#if defined __USE_LARGEFILE64 || defined __USE_FILE_OFFSET64 typedef int (*__ftw64_func_t) __P ((__const char *__filename, __const struct stat64 *__status, int __flag)); +#endif #ifdef __USE_XOPEN_EXTENDED typedef int (*__nftw_func_t) __P ((__const char *__filename, __const struct stat *__status, int __flag, struct FTW *__info)); +# if defined __USE_LARGEFILE64 || defined __USE_FILE_OFFSET64 typedef int (*__nftw64_func_t) __P ((__const char *__filename, __const struct stat64 *__status, int __flag, struct FTW *__info)); +# endif #endif /* Call a function on every element in a directory tree. */ diff --git a/libio/iofopen.c b/libio/iofopen.c index b74b692..59d1ce5 100644 --- a/libio/iofopen.c +++ b/libio/iofopen.c @@ -65,7 +65,7 @@ default_symbol_version (_IO_new_fopen, _IO_fopen, GLIBC_2.1); default_symbol_version (__new_fopen, fopen, GLIBC_2.1); #else # ifdef weak_alias -weak_symbol (_IO_new_fopen, _IO_fopen) -weak_symbol (_IO_new_fopen, fopen) +weak_alias (_IO_new_fopen, _IO_fopen) +weak_alias (_IO_new_fopen, fopen) # endif #endif diff --git a/manual/pattern.texi b/manual/pattern.texi index 596b72d..0fc5e81 100644 --- a/manual/pattern.texi +++ b/manual/pattern.texi @@ -466,6 +466,21 @@ glob ("~homer/bin/*", GLOB_TILDE, NULL, &result) @end smallexample This functionality is equivalent to what is available in C-shells. + +@comment glob.h +@comment GNU +@item GLOB_ONLYDIR +If this flag is used the globbing function takes this as a +@strong{hint} that the caller is only interested in directories +matching the pattern. If the information about the type of the file +is easily available non-directories will be rejected but no extra +work will be done to determine the information for each file. I.e., +the caller must still be able to filter directories out. + +This functionality is only available witht eh GNU @code{glob} +implementation. It is mainly used internally to increase the +performance but might be useful for a user as well and therefore is +documented here. @end table Calling @code{glob} will in most cases allocate resources which are used diff --git a/misc/Makefile b/misc/Makefile index 4cca2f3..7975964 100644 --- a/misc/Makefile +++ b/misc/Makefile @@ -64,7 +64,7 @@ install-lib := libbsd-compat.a libg.a non-lib.a := libbsd-compat.a gpl2lgpl := error.c error.h -tests := tst-dirname tst-tsearch +tests := tst-dirname tst-tsearch tst-fdset include ../Rules diff --git a/misc/efgcvt.c b/misc/efgcvt.c index 24d6317..8c92766 100644 --- a/misc/efgcvt.c +++ b/misc/efgcvt.c @@ -20,28 +20,60 @@ #include <stdio.h> #include <stdlib.h> #include <float.h> +#include <bits/libc-lock.h> #ifndef FLOAT_TYPE -#define FLOAT_TYPE double -#define FUNC_PREFIX -#define FLOAT_FMT_FLAG -#define MAXDIG (DBL_DIG + DBL_MAX_10_EXP) +# define FLOAT_TYPE double +# define FUNC_PREFIX +# define FLOAT_FMT_FLAG +/* Actually we have to write (DBL_DIG + log10 (DBL_MAX_10_EXP)) but we + don't have log10 available in the preprocessor. */ +# define MAXDIG (DBL_DIG + 3) #endif #define APPEND(a, b) APPEND2 (a, b) #define APPEND2(a, b) a##b +#define FCVT_BUFFER APPEND (FUNC_PREFIX, fcvt_buffer) +#define ECVT_BUFFER APPEND (FUNC_PREFIX, ecvt_buffer) + + +static char *FCVT_BUFFER; +static char *ECVT_BUFFER; + + +static void +APPEND (FUNC_PREFIX, fcvt_allocate) (void) +{ + FCVT_BUFFER = (char *) malloc (MAXDIG); +} + char * APPEND (FUNC_PREFIX, fcvt) (value, ndigit, decpt, sign) FLOAT_TYPE value; int ndigit, *decpt, *sign; { - static char buf[MAXDIG]; + __libc_once_define (static, once); + __libc_once (once, APPEND (FUNC_PREFIX, fcvt_allocate)); - (void) fcvt_r (value, ndigit, decpt, sign, buf, sizeof buf); + if (FCVT_BUFFER == NULL) + /* If no core is available we don't have a chance to run the + program successfully and so returning NULL is an acceptable + result. */ + return NULL; - return buf; + (void) APPEND (FUNC_PREFIX, fcvt_r) (value, ndigit, decpt, sign, + FCVT_BUFFER, MAXDIG); + + return FCVT_BUFFER; +} + + +static void +APPEND (FUNC_PREFIX, ecvt_allocate) (void) +{ + ECVT_BUFFER = (char *) malloc (MAXDIG); } char * @@ -49,11 +81,19 @@ APPEND (FUNC_PREFIX, ecvt) (value, ndigit, decpt, sign) FLOAT_TYPE value; int ndigit, *decpt, *sign; { - static char buf[MAXDIG]; + __libc_once_define (static, once); + __libc_once (once, APPEND (FUNC_PREFIX, ecvt_allocate)); - (void) ecvt_r (value, ndigit, decpt, sign, buf, sizeof buf); + if (ECVT_BUFFER == NULL) + /* If no core is available we don't have a chance to run the + program successfully and so returning NULL is an acceptable + result. */ + return NULL; - return buf; + (void) APPEND (FUNC_PREFIX, ecvt_r) (value, ndigit, decpt, sign, + ECVT_BUFFER, MAXDIG); + + return ECVT_BUFFER; } char * @@ -65,3 +105,18 @@ APPEND (FUNC_PREFIX, gcvt) (value, ndigit, buf) sprintf (buf, "%.*" FLOAT_FMT_FLAG "g", ndigit, value); return buf; } + + +/* Make sure the memory is freed if the programs ends while in + memory-debugging mode and something actually was allocated. */ +static void +__attribute__ ((unused)) +free_mem (void) +{ + if (FCVT_BUFFER != NULL) + free (FCVT_BUFFER); + if (ECVT_BUFFER != NULL) + free (ECVT_BUFFER); +} + +text_set_element (__libc_subfreeres, free_mem); diff --git a/misc/mntent.c b/misc/mntent.c index 95f745e..b21f24e 100644 --- a/misc/mntent.c +++ b/misc/mntent.c @@ -18,12 +18,50 @@ Boston, MA 02111-1307, USA. */ #include <mntent.h> +#include <stdlib.h> +#include <bits/libc-lock.h> + +/* We don't want to allocate the static buffer all the time since it + is not always used (in fact, rather infrequently). Accept the + extra cost of a `malloc'. */ +static char *getmntent_buffer; + +/* This is the size of the buffer. This is really big. */ +#define BUFFER_SIZE 4096 + + +static void +allocate (void) +{ + getmntent_buffer = (char *) malloc (BUFFER_SIZE); +} + struct mntent * getmntent (FILE *stream) { - static char buf[8192]; static struct mntent m; + __libc_once_define (static, once); + __libc_once (once, allocate); - return __getmntent_r (stream, &m, buf, sizeof buf); + if (getmntent_buffer == NULL) + /* If no core is available we don't have a chance to run the + program successfully and so returning NULL is an acceptable + result. */ + return NULL; + + return __getmntent_r (stream, &m, getmntent_buffer, BUFFER_SIZE); +} + + +/* Make sure the memory is freed if the programs ends while in + memory-debugging mode and something actually was allocated. */ +static void +__attribute__ ((unused)) +free_mem (void) +{ + if (getmntent_buffer != NULL) + free (getmntent_buffer); } + +text_set_element (__libc_subfreeres, free_mem); diff --git a/misc/qefgcvt.c b/misc/qefgcvt.c index 2729dce..853252c 100644 --- a/misc/qefgcvt.c +++ b/misc/qefgcvt.c @@ -20,6 +20,9 @@ #define FLOAT_TYPE long double #define FUNC_PREFIX q #define FLOAT_FMT_FLAG "L" -#define MAXDIG (LDBL_DIG + LDBL_MAX_10_EXP) +/* Actually we have to write (LDBL_DIG + log10 (LDBL_MAX_10_EXP)) but + we don't have log10 available in the preprocessor. Since we cannot + assume anything on the used `long double' format be generous. */ +#define MAXDIG (LDBL_DIG + 12) #include "efgcvt.c" diff --git a/misc/tst-fdset.c b/misc/tst-fdset.c new file mode 100644 index 0000000..ddd25c3 --- /dev/null +++ b/misc/tst-fdset.c @@ -0,0 +1,65 @@ +/* Test FD* macros. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Robert Bihlmeyer <robbe@orcus.priv.at>. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <stdio.h> +#include <sys/types.h> + +int +main (void) +{ + int retval = 0; + int i; + fd_set set; + + FD_ZERO (&set); + for (i=0; i < FD_SETSIZE; ++i) + { + printf ("%d => check:", i); + if (FD_ISSET (i, &set) == 0) + fputs ("ok", stdout); + else + { + fputs ("nok", stdout); + retval = 1; + } + fputs (", set", stdout); + FD_SET (i, &set); + fputs (", check:", stdout); + if (FD_ISSET (i, &set) == 1) + fputs ("ok", stdout); + else + { + fputs ("nok", stdout); + retval = 1; + } + fputs (", clear", stdout); + FD_CLR (i, &set); + fputs (", check:", stdout); + if (FD_ISSET (i, &set) == 0) + puts ("ok"); + else + { + puts ("nok"); + retval = 1; + } + } + + return retval; +} diff --git a/posix/glob.c b/posix/glob.c index 6a601ee..909b4f1 100644 --- a/posix/glob.c +++ b/posix/glob.c @@ -114,6 +114,12 @@ extern int errno; # define NAMLEN(d) _D_NAMLEN(d) #endif +/* When used in the GNU libc the symbol _DIRENT_HAVE_D_TYPE is available + if the `d_type' member for `struct dirent' is available. */ +#ifdef _DIRENT_HAVE_D_TYPE +# define HAVE_D_TYPE 1 +#endif + #if (defined POSIX || defined WINDOWS32) && !defined __GNU_LIBRARY__ /* Posix does not require that the d_ino field be present, and some @@ -661,8 +667,8 @@ glob (pattern, flags, errfunc, pglob) register int i; status = glob (dirname, - ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) | - GLOB_NOSORT), + ((flags & (GLOB_ERR | GLOB_NOCHECK | GLOB_NOESCAPE)) + | GLOB_NOSORT | GLOB_ONLYDIR), errfunc, &dirs); if (status != 0) return status; @@ -690,7 +696,8 @@ glob (pattern, flags, errfunc, pglob) oldcount = pglob->gl_pathc; status = glob_in_dir (filename, dirs.gl_pathv[i], - (flags | GLOB_APPEND) & ~GLOB_NOCHECK, + ((flags | GLOB_APPEND) + & ~(GLOB_NOCHECK | GLOB_ERR)), errfunc, pglob); if (status == GLOB_NOMATCH) /* No matches in this directory. Try the next. */ @@ -981,6 +988,14 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) if (! REAL_DIR_ENTRY (d)) continue; +#ifdef HAVE_D_TYPE + /* If we shall match only directories use the information + provided by the dirent if possible. */ + if ((flags & GLOB_ONLYDIR) + && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR) + continue; +#endif + if (strcmp (pattern, d->d_name) == 0) { size_t len = NAMLEN (d); @@ -1030,6 +1045,14 @@ glob_in_dir (pattern, directory, flags, errfunc, pglob) name = d->d_name; +#ifdef HAVE_D_TYPE + /* If we shall match only directories use the information + provided by the dirent if possible. */ + if ((flags & GLOB_ONLYDIR) + && d->d_type != DT_UNKNOWN && d->d_type != DT_DIR) + continue; +#endif + if (fnmatch (pattern, name, (!(flags & GLOB_PERIOD) ? FNM_PERIOD : 0) | ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) diff --git a/posix/glob.h b/posix/glob.h index 713117b..a15d8ef 100644 --- a/posix/glob.h +++ b/posix/glob.h @@ -57,11 +57,12 @@ extern "C" # define GLOB_ALTDIRFUNC (1 << 9)/* Use gl_opendir et al functions. */ # define GLOB_BRACE (1 << 10)/* Expand "{a,b}" to "a" "b". */ # define GLOB_NOMAGIC (1 << 11)/* If no magic chars, return the pattern. */ -# define GLOB_TILDE (1 <<12)/* Expand ~user and ~ to home directories. */ +# define GLOB_TILDE (1 << 12)/* Expand ~user and ~ to home directories. */ +# define GLOB_ONLYDIR (1 << 13)/* Match only directories. */ # define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ GLOB_PERIOD|GLOB_ALTDIRFUNC|GLOB_BRACE| \ - GLOB_NOMAGIC|GLOB_TILDE) + GLOB_NOMAGIC|GLOB_TILDE|GLOB_ONLYDIR) #else # define __GLOB_FLAGS (GLOB_ERR|GLOB_MARK|GLOB_NOSORT|GLOB_DOOFFS| \ GLOB_NOESCAPE|GLOB_NOCHECK|GLOB_APPEND| \ diff --git a/sysdeps/i386/bits/select.h b/sysdeps/i386/bits/select.h index f2107e9..f2ab43e 100644 --- a/sysdeps/i386/bits/select.h +++ b/sysdeps/i386/bits/select.h @@ -25,29 +25,28 @@ # define __FD_ZERO(fdsetp) \ __asm__ __volatile__ ("cld; rep; stosl" \ - : "=m" (((__fd_mask *) \ - (fdsetp))[__FDELT (__FD_SETSIZE)]) \ + : "=m" ((fdsetp)->fds_bits[__FDELT (__FD_SETSIZE)]) \ : "a" (0), "c" (sizeof (__fd_set) \ / sizeof (__fd_mask)), \ - "D" ((__fd_set *) (fdsetp)) \ - :"cx","di") + "D" (&(fdsetp)->fds_bits[0]) \ + :"cx","di","memory") # define __FD_SET(fd, fdsetp) \ __asm__ __volatile__ ("btsl %1,%0" \ - : "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)]) \ + : "=m" ((fdsetp)->fds_bits[__FDELT (fd)]) \ : "r" (((int) (fd)) % __NFDBITS) \ - : "cc") + : "cc","memory") # define __FD_CLR(fd, fdsetp) \ __asm__ __volatile__ ("btrl %1,%0" \ - : "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)]) \ + : "=m" ((fdsetp)->fds_bits[__FDELT (fd)]) \ : "r" (((int) (fd)) % __NFDBITS) \ - : "cc") + : "cc","memory") # define __FD_ISSET(fd, fdsetp) \ (__extension__ \ ({register char __result; \ __asm__ __volatile__ ("btl %1,%2 ; setcb %b0" \ : "=q" (__result) \ : "r" (((int) (fd)) % __NFDBITS), \ - "m" (((__fd_mask *) (fdsetp))[__FDELT (fd)]) \ + "m" ((fdsetp)->fds_bits[__FDELT (fd)]) \ : "cc"); \ __result; })) diff --git a/sysdeps/unix/sysv/linux/Dist b/sysdeps/unix/sysv/linux/Dist index bdc333a..cfe5202 100644 --- a/sysdeps/unix/sysv/linux/Dist +++ b/sysdeps/unix/sysv/linux/Dist @@ -48,3 +48,4 @@ sys/sysmacros.h sys/timex.h sys/user.h sys/vt.h +xstatconv.c diff --git a/sysdeps/unix/sysv/linux/alpha/Dist b/sysdeps/unix/sysv/linux/alpha/Dist index ae71c2f..ebbf300 100644 --- a/sysdeps/unix/sysv/linux/alpha/Dist +++ b/sysdeps/unix/sysv/linux/alpha/Dist @@ -12,3 +12,4 @@ kernel_termios.h sys/acct.h sys/io.h sys/procfs.h +xstatconv.c
\ No newline at end of file diff --git a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h index 4d717e4..a371a55 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/dirent.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/dirent.h @@ -19,10 +19,14 @@ #ifndef _BITS_DIRENT_H #define _BITS_DIRENT_H 1 -/* We don't have to make a difference for __USE_FILE_OFFSET64. */ struct dirent { - long int d_ino; +#ifdef __USE_FILE_OFFSET64 + __ino64_t d_ino; +#else + __ino_t d_ino; + int __pad; +#endif __off_t d_off; unsigned short int d_reclen; unsigned char d_type; @@ -30,6 +34,7 @@ struct dirent }; #ifdef __USE_LARGEFILE64 +/* Note dirent64 is the same as dirent. */ struct dirent64 { __ino64_t d_ino; diff --git a/sysdeps/unix/sysv/linux/alpha/bits/stat.h b/sysdeps/unix/sysv/linux/alpha/bits/stat.h index cc2a2ea..de8752e 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/stat.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/stat.h @@ -24,9 +24,10 @@ #define _BITS_STAT_H 1 /* Versions of the `struct stat' data structure. */ -#define _STAT_VER_LINUX_OLD 0 -#define _STAT_VER_LINUX 1 -#define _STAT_VER _STAT_VER_LINUX +#define _STAT_VER_KERNEL 0 +#define _STAT_VER_GLIBC2 1 +#define _STAT_VER_GLIBC2_1 2 +#define _STAT_VER _STAT_VER_GLIBC2_1 /* Versions of the `xmknod' interface. */ #define _MKNOD_VER_LINUX 0 @@ -34,7 +35,12 @@ struct stat { __dev_t st_dev; /* Device. */ +#ifdef __USE_FILE_OFFSET64 + __ino64_t st_ino; /* File serial number. */ +#else __ino_t st_ino; /* File serial number. */ + int __pad1; +#endif __mode_t st_mode; /* File mode. */ __nlink_t st_nlink; /* Link count. */ __uid_t st_uid; /* User ID of the file's owner. */ @@ -44,13 +50,45 @@ struct stat __time_t st_atime; /* Time of last access. */ __time_t st_mtime; /* Time of last modification. */ __time_t st_ctime; /* Time of last status change. */ +#ifdef __USE_FILE_OFFSET64 + __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ +#else + __blkcnt_t st_blocks; /* Nr. 512-byte blocks allocated. */ + int __pad2; +#endif unsigned int st_blksize; /* Optimal block size for I/O. */ -#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ - __blkcnt_t st_blocks; /* Nr. of 512-byte blocks allocated. */ unsigned int st_flags; unsigned int st_gen; + int __pad3; + long __unused[4]; }; +#ifdef __USE_LARGEFILE64 +/* Note stat64 is the same shape as stat. */ +struct stat64 + { + __dev_t st_dev; /* Device. */ + __ino64_t st_ino; /* File serial number. */ + __mode_t st_mode; /* File mode. */ + __nlink_t st_nlink; /* Link count. */ + __uid_t st_uid; /* User ID of the file's owner. */ + __gid_t st_gid; /* Group ID of the file's group.*/ + __dev_t st_rdev; /* Device number, if device. */ + __off_t st_size; /* Size of file, in bytes. */ + __time_t st_atime; /* Time of last access. */ + __time_t st_mtime; /* Time of last modification. */ + __time_t st_ctime; /* Time of last status change. */ + __blkcnt64_t st_blocks; /* Nr. 512-byte blocks allocated. */ + unsigned int st_blksize; /* Optimal block size for I/O. */ + unsigned int st_flags; + unsigned int st_gen; + int __pad3; + long __unused[4]; + }; +#endif + +#define _STATBUF_ST_BLKSIZE /* Tell code we have this member. */ + /* Encoding of the file mode. */ #define __S_IFMT 0170000 /* These bits determine file type. */ diff --git a/sysdeps/unix/sysv/linux/alpha/bits/types.h b/sysdeps/unix/sysv/linux/alpha/bits/types.h index cf2668a..b9e6dd7 100644 --- a/sysdeps/unix/sysv/linux/alpha/bits/types.h +++ b/sysdeps/unix/sysv/linux/alpha/bits/types.h @@ -42,18 +42,26 @@ typedef signed long int __int64_t; typedef unsigned long int __uint64_t; typedef __quad_t *__qaddr_t; -typedef __u_long __dev_t; /* Type of device numbers. */ -typedef __u_int __uid_t; /* Type of user identifications. */ -typedef __u_int __gid_t; /* Type of group identifications. */ -typedef __u_int __ino_t; /* Type of file serial numbers. */ -typedef __u_int __mode_t; /* Type of file attribute bitmasks. */ -typedef __u_int __nlink_t; /* Type of file link counts. */ -typedef long int __off_t; /* Type of file sizes and offsets. */ -typedef __quad_t __loff_t; /* Type of file sizes and offsets. */ -typedef int __pid_t; /* Type of process identifications. */ -typedef long int __ssize_t; /* Type of a byte count, or error. */ -typedef long int __rlim_t; /* Type of resource counts. */ -typedef long int __rlim64_t; /* Type of resource counts (LFS). */ +typedef __uint64_t __dev_t; /* Type of device numbers. */ +typedef __uint32_t __uid_t; /* Type of user identifications. */ +typedef __uint32_t __gid_t; /* Type of group identifications. */ +typedef __uint32_t __ino_t; /* Type of file serial numbers. */ +typedef __uint64_t __ino64_t; /* "" (LFS) */ +typedef __uint32_t __mode_t; /* Type of file attribute bitmasks. */ +typedef __uint32_t __nlink_t; /* Type of file link counts. */ +typedef __int64_t __off_t; /* Type of file sizes and offsets. */ +typedef __int64_t __off64_t; /* "" (LFS) */ +typedef __int64_t __loff_t; /* Type of file sizes and offsets. */ +typedef __int32_t __pid_t; /* Type of process identifications. */ +typedef __int64_t __ssize_t; /* Type of a byte count, or error. */ +typedef __int64_t __rlim_t; /* Type of resource counts. */ +typedef __int64_t __rlim64_t; /* "" (LFS) */ +typedef __int32_t __blkcnt_t; /* Type to count nr disk blocks. */ +typedef __int64_t __blkcnt64_t; /* "" (LFS) */ +typedef __uint32_t __fsblkcnt_t; /* Type to count file system blocks. */ +typedef __uint64_t __fsblkcnt64_t; /* "" (LFS) */ +typedef __uint64_t __fsfilcnt_t; /* Type to count file system inodes. */ +typedef __uint64_t __fsfilcnt64_t; /* "" (LFS) */ typedef struct { @@ -61,12 +69,12 @@ typedef struct } __fsid_t; /* Type of file system IDs. */ /* Everythin' else. */ -typedef int __daddr_t; /* The type of a disk address. */ -typedef char *__caddr_t; +typedef int __daddr_t; /* Type of a disk address. */ +typedef char *__caddr_t; /* Type of a core address. */ typedef long int __time_t; typedef long int __swblk_t; /* Type of a swap block maybe? */ - typedef long int __clock_t; +typedef int __key_t; /* Type of a SYSV IPC key. */ /* One element in the file descriptor mask array. */ typedef unsigned long int __fd_mask; @@ -91,22 +99,4 @@ typedef struct __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; } __fd_set; - -typedef int __key_t; - - -/* Types from the Large File Support interface. */ - -/* Type to count number os disk blocks. */ -typedef int __blkcnt_t; -typedef __quad_t __blkcnt64_t; - -/* Type to count file system blocks. */ -typedef unsigned int __fsblkcnt_t; -typedef __u_quad_t __fsblkcnt64_t; - -/* Type to count file system inodes. */ -typedef unsigned long int __fsfilcnt_t; -typedef __u_quad_t __fsfilcnt64_t; - #endif /* bits/types.h */ diff --git a/sysdeps/unix/sysv/linux/alpha/fxstat64.c b/sysdeps/unix/sysv/linux/alpha/fxstat64.c new file mode 100644 index 0000000..9eff9eb --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/fxstat64.c @@ -0,0 +1 @@ +/* fxstat64 is in fxstat.c */ diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h index 7109677..2633b42 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel_stat.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel_stat.h @@ -1,4 +1,4 @@ -/* Definition of `struct stat' used in the kernel.. */ +/* Definition of `struct stat' used in the kernel. */ struct kernel_stat { unsigned int st_dev; @@ -17,3 +17,27 @@ struct kernel_stat unsigned int st_flags; unsigned int st_gen; }; + +/* Definition of `struct stat' used by glibc 2.0. */ +struct glibc2_stat + { + __dev_t st_dev; + __ino_t st_ino; + __mode_t st_mode; + __nlink_t st_nlink; + __uid_t st_uid; + __gid_t st_gid; + __dev_t st_rdev; + __off_t st_size; + __time_t st_atime; + __time_t st_mtime; + __time_t st_ctime; + unsigned int st_blksize; + int st_blocks; + unsigned int st_flags; + unsigned int st_gen; + }; + +extern int __xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf); + +#define XSTAT_IS_XSTAT64 1 diff --git a/sysdeps/unix/sysv/linux/alpha/lxstat64.c b/sysdeps/unix/sysv/linux/alpha/lxstat64.c new file mode 100644 index 0000000..bb5dbd0 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/lxstat64.c @@ -0,0 +1 @@ +/* lxstat64 is in lxstat.c */ diff --git a/sysdeps/unix/sysv/linux/alpha/xstat64.c b/sysdeps/unix/sysv/linux/alpha/xstat64.c new file mode 100644 index 0000000..e7acd3b --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/xstat64.c @@ -0,0 +1 @@ +/* xstat64 is in xstat.c */ diff --git a/sysdeps/unix/sysv/linux/alpha/xstatconv.c b/sysdeps/unix/sysv/linux/alpha/xstatconv.c new file mode 100644 index 0000000..d1005e7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/alpha/xstatconv.c @@ -0,0 +1,90 @@ +/* Convert between the kernel's `struct stat' format, and libc's. + Copyright (C) 1997 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <string.h> + + +static inline int +xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) +{ + switch (vers) + { + case _STAT_VER_KERNEL: + /* Nothing to do. The struct is in the form the kernel expects. + We should have short-circuted before we got here, but for + completeness... */ + memcpy ((struct kernel_stat *) ubuf, kbuf, sizeof (*kbuf)); + break; + + case _STAT_VER_GLIBC2: + { + struct glibc2_stat *buf = ubuf; + + buf->st_dev = kbuf->st_dev; + 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; + buf->st_size = kbuf->st_size; + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; + buf->st_blksize = kbuf->st_blksize; + buf->st_blocks = kbuf->st_blocks; + buf->st_flags = kbuf->st_flags; + buf->st_gen = kbuf->st_gen; + } + break; + + case _STAT_VER_GLIBC2_1: + { + struct stat64 *buf = ubuf; + + buf->st_dev = kbuf->st_dev; + 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; + buf->st_size = kbuf->st_size; + buf->st_atime = kbuf->st_atime; + buf->st_mtime = kbuf->st_mtime; + buf->st_ctime = kbuf->st_ctime; + buf->st_blocks = kbuf->st_blocks; + buf->st_blksize = kbuf->st_blksize; + buf->st_flags = kbuf->st_flags; + buf->st_gen = kbuf->st_gen; + buf->__pad3 = 0; + buf->__unused[0] = 0; + buf->__unused[1] = 0; + buf->__unused[2] = 0; + buf->__unused[3] = 0; + } + break; + + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} diff --git a/sysdeps/unix/sysv/linux/bits/stat.h b/sysdeps/unix/sysv/linux/bits/stat.h index aab0258..1b98448 100644 --- a/sysdeps/unix/sysv/linux/bits/stat.h +++ b/sysdeps/unix/sysv/linux/bits/stat.h @@ -25,6 +25,7 @@ /* Versions of the `struct stat' data structure. */ #define _STAT_VER_LINUX_OLD 1 +#define _STAT_VER_KERNEL 1 #define _STAT_VER_SVR4 2 #define _STAT_VER_LINUX 3 #define _STAT_VER _STAT_VER_LINUX /* The one defined below. */ diff --git a/sysdeps/unix/sysv/linux/fxstat.c b/sysdeps/unix/sysv/linux/fxstat.c index 5aa02dc..afed300 100644 --- a/sysdeps/unix/sysv/linux/fxstat.c +++ b/sysdeps/unix/sysv/linux/fxstat.c @@ -17,76 +17,38 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc + will complain since they don't strictly match. */ +#define __fxstat64 __fxstat64_disable + #include <errno.h> #include <stddef.h> #include <sys/stat.h> - #include <kernel_stat.h> +#include <xstatconv.c> + extern int __syscall_fstat (int, struct kernel_stat *); -/* Get information about the file descriptor FD in BUF. */ +/* Get information about the file FD in BUF. */ int __fxstat (int vers, int fd, struct stat *buf) { struct kernel_stat kbuf; int result; - switch (vers) - { - case _STAT_VER_LINUX_OLD: - /* Nothing to do. The struct is in the form the kernel expects - it to be. */ - result = __syscall_fstat (fd, (struct kernel_stat *) buf); - break; - - case _STAT_VER_LINUX: - /* Do the system call. */ - result = __syscall_fstat (fd, &kbuf); - - /* Convert to current kernel version of `struct stat'. */ - buf->st_dev = kbuf.st_dev; -#ifdef _HAVE___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___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___UNUSED1 - buf->__unused1 = 0; -#endif - buf->st_mtime = kbuf.st_mtime; -#ifdef _HAVE___UNUSED2 - buf->__unused2 = 0; -#endif - buf->st_ctime = kbuf.st_ctime; -#ifdef _HAVE___UNUSED3 - buf->__unused3 = 0; -#endif -#ifdef _HAVE___UNUSED4 - buf->__unused4 = 0; -#endif -#ifdef _HAVE___UNUSED5 - buf->__unused5 = 0; -#endif - break; + if (vers == _STAT_VER_KERNEL) + return __syscall_fstat (fd, (struct kernel_stat *) buf); - default: - __set_errno (EINVAL); - result = -1; - break; - } + result = __syscall_fstat (fd, &kbuf); + if (result == 0) + result = xstat_conv (vers, &kbuf, buf); return result; } -weak_alias (__fxstat, _fxstat) + +weak_alias (__fxstat, _fxstat); +#ifdef XSTAT_IS_XSTAT64 +#undef __fxstat64 +strong_alias (__fxstat, __fxstat64); +#endif diff --git a/sysdeps/unix/sysv/linux/lxstat.c b/sysdeps/unix/sysv/linux/lxstat.c index 11c9038..7fbe14e 100644 --- a/sysdeps/unix/sysv/linux/lxstat.c +++ b/sysdeps/unix/sysv/linux/lxstat.c @@ -1,4 +1,4 @@ -/* lxstat using old-style Unix fstat system call. +/* lxstat using old-style Unix lstat system call. Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,12 +17,17 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc + will complain since they don't strictly match. */ +#define __lxstat64 __lxstat64_disable + #include <errno.h> #include <stddef.h> #include <sys/stat.h> - #include <kernel_stat.h> +#include <xstatconv.c> + extern int __syscall_lstat (const char *, struct kernel_stat *); /* Get information about the file NAME in BUF. */ @@ -32,61 +37,18 @@ __lxstat (int vers, const char *name, struct stat *buf) struct kernel_stat kbuf; int result; - switch (vers) - { - case _STAT_VER_LINUX_OLD: - /* Nothing to do. The struct is in the form the kernel expects - it to be. */ - result = __syscall_lstat (name, (struct kernel_stat *) buf); - break; - - case _STAT_VER_LINUX: - /* Do the system call. */ - result = __syscall_lstat (name, &kbuf); - - /* Convert to current kernel version of `struct stat'. */ - buf->st_dev = kbuf.st_dev; -#ifdef _HAVE___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___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___UNUSED1 - buf->__unused1 = 0; -#endif - buf->st_mtime = kbuf.st_mtime; -#ifdef _HAVE___UNUSED2 - buf->__unused2 = 0; -#endif - buf->st_ctime = kbuf.st_ctime; -#ifdef _HAVE___UNUSED3 - buf->__unused3 = 0; -#endif -#ifdef _HAVE___UNUSED4 - buf->__unused4 = 0; -#endif -#ifdef _HAVE___UNUSED5 - buf->__unused5 = 0; -#endif - break; + if (vers == _STAT_VER_KERNEL) + return __syscall_lstat (name, (struct kernel_stat *) buf); - default: - __set_errno (EINVAL); - result = -1; - break; - } + result = __syscall_lstat (name, &kbuf); + if (result == 0) + result = xstat_conv (vers, &kbuf, buf); return result; } -weak_alias (__lxstat, _lxstat) + +weak_alias (__lxstat, _lxstat); +#ifdef XSTAT_IS_XSTAT64 +#undef __lxstat64 +strong_alias (__lxstat, __lxstat64); +#endif diff --git a/sysdeps/unix/sysv/linux/xstat.c b/sysdeps/unix/sysv/linux/xstat.c index aa120f5..8532857 100644 --- a/sysdeps/unix/sysv/linux/xstat.c +++ b/sysdeps/unix/sysv/linux/xstat.c @@ -1,4 +1,4 @@ -/* xstat using old-style Unix fstat system call. +/* xstat using old-style Unix stat system call. Copyright (C) 1991, 1995, 1996, 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -17,12 +17,17 @@ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* Ho hum, if xstat == xstat64 we must get rid of the prototype or gcc + will complain since they don't strictly match. */ +#define __xstat64 __xstat64_disable + #include <errno.h> #include <stddef.h> #include <sys/stat.h> - #include <kernel_stat.h> +#include <xstatconv.c> + extern int __syscall_stat (const char *, struct kernel_stat *); /* Get information about the file NAME in BUF. */ @@ -32,61 +37,18 @@ __xstat (int vers, const char *name, struct stat *buf) struct kernel_stat kbuf; int result; - switch (vers) - { - case _STAT_VER_LINUX_OLD: - /* Nothing to do. The struct is in the form the kernel expects - it to be. */ - result = __syscall_stat (name, (struct kernel_stat *) buf); - break; - - case _STAT_VER_LINUX: - /* Do the system call. */ - result = __syscall_stat (name, &kbuf); - - /* Convert to current kernel version of `struct stat'. */ - buf->st_dev = kbuf.st_dev; -#ifdef _HAVE___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___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___UNUSED1 - buf->__unused1 = 0; -#endif - buf->st_mtime = kbuf.st_mtime; -#ifdef _HAVE___UNUSED2 - buf->__unused2 = 0; -#endif - buf->st_ctime = kbuf.st_ctime; -#ifdef _HAVE___UNUSED3 - buf->__unused3 = 0; -#endif -#ifdef _HAVE___UNUSED4 - buf->__unused4 = 0; -#endif -#ifdef _HAVE___UNUSED5 - buf->__unused5 = 0; -#endif - break; + if (vers == _STAT_VER_KERNEL) + return __syscall_stat (name, (struct kernel_stat *) buf); - default: - __set_errno (EINVAL); - result = -1; - break; - } + result = __syscall_stat (name, &kbuf); + if (result == 0) + result = xstat_conv (vers, &kbuf, buf); return result; } -weak_alias (__xstat, _xstat) + +weak_alias (__xstat, _xstat); +#ifdef XSTAT_IS_XSTAT64 +#undef __xstat64 +strong_alias (__xstat, __xstat64); +#endif diff --git a/sysdeps/unix/sysv/linux/xstatconv.c b/sysdeps/unix/sysv/linux/xstatconv.c new file mode 100644 index 0000000..06a28cc --- /dev/null +++ b/sysdeps/unix/sysv/linux/xstatconv.c @@ -0,0 +1,83 @@ +/* Convert between the kernel's `struct stat' format, and libc's. + Copyright (C) 1991, 1995, 1996, 1997 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 Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <string.h> + + +static inline int +xstat_conv (int vers, struct kernel_stat *kbuf, void *ubuf) +{ + switch (vers) + { + case _STAT_VER_KERNEL: + /* Nothing to do. The struct is in the form the kernel expects. + We should have short-circuted before we got here, but for + completeness... */ + memcpy ((struct kernel_stat *) ubuf, kbuf, sizeof (*kbuf)); + break; + + case _STAT_VER_LINUX: + { + struct stat *buf = ubuf; + + /* Convert to current kernel version of `struct stat'. */ + buf->st_dev = kbuf->st_dev; +#ifdef _HAVE___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___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___UNUSED1 + buf->__unused1 = 0; +#endif + buf->st_mtime = kbuf->st_mtime; +#ifdef _HAVE___UNUSED2 + buf->__unused2 = 0; +#endif + buf->st_ctime = kbuf->st_ctime; +#ifdef _HAVE___UNUSED3 + buf->__unused3 = 0; +#endif +#ifdef _HAVE___UNUSED4 + buf->__unused4 = 0; +#endif +#ifdef _HAVE___UNUSED5 + buf->__unused5 = 0; +#endif + } + break; + + default: + __set_errno (EINVAL); + return -1; + } + + return 0; +} diff --git a/time/strptime.c b/time/strptime.c index 4e91a71..30b0156 100644 --- a/time/strptime.c +++ b/time/strptime.c @@ -543,7 +543,9 @@ strptime_internal (buf, format, tm, decided) case 'y': /* Match year within century. */ get_number (0, 99); - tm->tm_year = val >= 50 ? val : val + 100; + /* The "Year 2000 :The Millennium Rollover" paper suggests that + values in the range 69-99 refer to the twentieth century. */ + tm->tm_year = val >= 69 ? val : val + 100; break; case 'Y': /* Match year including century number. */ diff --git a/time/tzset.c b/time/tzset.c index 385e7f7..0793027 100644 --- a/time/tzset.c +++ b/time/tzset.c @@ -548,7 +548,7 @@ tz_compute (timer, tm) return 0; __daylight = timer >= tz_rules[0].change && timer < tz_rules[1].change; - __timezone = -tz_rules[__daylight ? 1 : 0].offset; + __timezone = -tz_rules[__daylight].offset; __tzname[0] = (char *) tz_rules[0].name; __tzname[1] = (char *) tz_rules[1].name; @@ -629,7 +629,7 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp) { tp->tm_isdst = __daylight; tp->tm_zone = __tzname[__daylight]; - tp->tm_gmtoff = __timezone; + tp->tm_gmtoff = -__timezone; } else { |