autoconf-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Fix for AC_HEADER_MAJOR for glibc + non-gcc


From: Paul Eggert
Subject: Re: Fix for AC_HEADER_MAJOR for glibc + non-gcc
Date: Tue, 16 Oct 2001 12:01:53 -0700 (PDT)

> Date: Tue, 16 Oct 2001 04:13:52 -0400 (EDT)
> From: Pavel Roskin <address@hidden>

> If some standard functions, such as stat(), require "long long" to be 
> supported, it should be reasonable to assume that is supported. 

But in that case, why isn't it also reasonable to assume that a
POSIX-conforming dev_t is also supported, since it's "long long" on Linux?

> > I used to worry about hosts with brain damaged system types like that.
> > However, I stopped worrying about them a few years ago, and have never
> > regretted it.  It's such a hassle dealing with systems where you can't
> > compare dev_t values with == (or even with memcmp, for that matter).
> 
> It's very late as I'm writing it, so let me ask a dumb question - what's
> wrong with memcmp?

If I recall correctly, it's because on some older nonstandard hosts,
dev_t is a structure with holes, and the holes contain garbage.
(Admittedly this is pretty obscure -- it's been a while.)

> I think that supporting more than on compiler on GNU/Linux is very 
> important - it means more choice and new (potentially useful) warnings 
> about unportable or nonstandard code.

If our goal is to check for unportable or nonstandard code, we can do
that just as easily by running on other systems like Solaris and BSD.
After all, we're not porting for the fun of it; we're porting because
people need applications on particular platforms.

If our goal is to support more than one compiler on GNU/Linux, then
the problem here seems to be with glibc, not Autoconf.  How about if
we patch glibc instead of futzing with Autoconf?  We can tell people
to use GCC in the meantime, since glibc hasn't been fully ported yet
to other compilers.

Here's the sort of patch I'm thinking of, relative to glibc 2.2.4.
Obviously this is just part of the patch -- we also need to typedef
dev_t to double on older compilers, etc.  It just gives you an idea of
how glibc might be fixed.

2001-10-16  Paul Eggert  <address@hidden>

        * sysdeps/unix/sysv/linux/sys/sysmacros.h (major, minor, makedev):
        If it's a C99 compiler, assume it has 'long long'.
        Also, if 'long long' is not supported, use 'double' instead.
        This works with all compilers.  POSIX allows dev_t to be 'double',
        so this conforms to POSIX.

--- sysdeps/unix/sysv/linux/sys/sysmacros.h     Mon Jul 23 10:57:55 2001
+++ /tmp/sysmacros.h    Tue Oct 16 11:56:17 2001
@@ -22,28 +22,24 @@
 
 /* For compatibility we provide alternative names.
 
-   The problem here is that compilers other than GCC probably don't
-   have the `long long' type and so `dev_t' is actually an array.  */
-#if defined __GNUC__ && __GNUC__ >= 2
-# define major(dev) ((int)(((dev) >> 8) & 0xff))
-# define minor(dev) ((int)((dev) & 0xff))
-# define makedev(major, minor) ((((unsigned int) (major)) << 8) \
-                               | ((unsigned int) (minor)))
+/* Convert DEV to an integer.  The problem here is that pre-C99
+   compilers other than GCC probably don't have the `long long' type
+   and so we use `double' instead.  When considered as a `double',
+   the device number is an integer multiple of DBL_MIN.  */
+#if ((defined __GNUC__ && __GNUC__ >= 2) \
+     || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+# define __dev_to_int(d) ((int) (d))
+# define __int_to_dev(i) ((dev_t) (i))
 #else
-/* We need to know the word order here.  This assumes that the word order
-   is consistent with the byte order.  */
-# include <endian.h>
-# if __BYTE_ORDER == __BIG_ENDIAN
-#  define major(dev) (((dev).__val[1] >> 8) & 0xff)
-#  define minor(dev) ((dev).__val[1] & 0xff)
-#  define makedev(major, minor) { 0, ((((unsigned int) (major)) << 8) \
-                                     | ((unsigned int) (minor))) }
-# else
-#  define major(dev) (((dev).__val[0] >> 8) & 0xff)
-#  define minor(dev) ((dev).__val[0] & 0xff)
-#  define makedev(major, minor) { ((((unsigned int) (major)) << 8) \
-                                  | ((unsigned int) (minor))), 0 }
-# endif
+# include <float.h>
+# define __dev_to_int(dev) ((int) ((dev) / DBL_MIN))
+# define __int_to_dev(i) ((i) * DBL_MIN)
+#endif
+
+#define major(dev) ((__dev_to_int (dev) >> 8) & 0xff)
+#define minor(dev) (__dev_to_int (dev) & 0xff)
+#define makedev(major, minor) __int_to_dev ((((unsigned int) (major)) << 8) \
+                                           | ((unsigned int) (minor)))
 #endif
 
 #endif /* sys/sysmacros.h */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]