From: Wietse Venema (no email)
Date: Mon Sep 01 2003 - 18:36:47 EDT
Carsten Hoeger:
> > > I've been told, that
> > >
> > > ... getrlimit(RLIMIT_FSIZE, &rlim) returns ULONG_MAX, the
> > > limit the kernel is able to handle. and off_t is LONG_MAX + 1, the limit the
> > > kernel interface is able to handle.
> >
> > Again, how portable is this? I know of no standard that requires
> > getrlimit() to return values limited by ULONG_MAX.
>
> Do you know a standard, that requires getrlimit() to return something which
> can be assigned to a off_t type value without changing the algebraic sign?
Welcome to the world of non-standards. I hope it is clear that an
innocent change can completely break Postfix because of negative
file sizes and/or integer under/overflow, and I want to avoid this.
Postfix must be able to seek files, therefore files can't be larger
than the largest off_t value. What should Postfix do when the
system imposed file size limit is larger than what can be represented
as a file offset? The best is to truncate the limit to the largest
positive off_t value.
It seems relatively safe to assume that off_t is a signed integer
type in two's complement format. What is the portable way to find
out the largest value of such a signed integer?
Coming back to your proposed macro:
#define FSIZE_MAX (off_t)1<<((sizeof(off_t)*8)-1)
This macro assumes that bytes are 8 bits wide, but the C standard
does not require this. Postfix runs on machines other than peecees
and I would not like to lose those platforms. Fortunately, ANSI C
defines the CHAR_BIT constant in <limits.h> for this exact purpose.
So let's fix this portability problem. While we're at it, let's
also fix a potential operator precedence problem by adding add
outer parentheses. And let's generalize this macro a bit so that
it can be tested easily.
#define MAX_POSITIVE_OF(T) ((T) 1 << ((sizeof(T) * CHAR_BIT) - 1))
This reveals that the original macro has bigger problems than 8-bit
byte assumptions or operator precedence conflicts. The macro simply
computes the wrong result.
For example,
MAX_POSITIVE_OF(char) evaluates to 128, should be 127
MAX_POSITIVE_OF(short) evaluates to 32768, should be 32767
I would be interested in something that has actually been tested
and that works on more than one platform.
Wietse
|
|
|