Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Jun 1998 18:51:20 +0000 (GMT)
From:      Terry Lambert <tlambert@primenet.com>
To:        fenner@parc.xerox.com (Bill Fenner)
Cc:        tlambert@primenet.com, peter@netplex.com.au, current@FreeBSD.ORG
Subject:   Re: Bogus errno twiddling by lstat...
Message-ID:  <199806191851.LAA12551@usr06.primenet.com>
In-Reply-To: <98Jun19.095515pdt.177515@crevenia.parc.xerox.com> from "Bill Fenner" at Jun 19, 98 09:55:00 am

next in thread | previous in thread | raw e-mail | index | archive | help
> >> 1: This is a classic programming error.. You're not really supposed to be 
> >> looking at the value of errno except right after a -1 return from 
> >> something.
> >
> >I know I'm not supposed to be.  However, it's not supposed to be diddling
> >the errno.
> 
> The ANSI C standard says that unless stated otherwise in the standard
> (e.g. the math functions), library functions may change errno even if
> there is no error.

On the other hand, they may leave it alone.


Look, what I was surprised at was the multiple attempts to open
malloc.conf after the first failure in crt0's use of ld.so.


I became concerned, in that it is *perfectly* valid to implement a
POSIX OS using library routines that operate on non-POSIX system
services.

In such a situation, I would not expected these pseduo-system calls
to modify errno, just as I do not expect real system calls to
modify errno.

This alarm comes from somewhere that I can't at present identify: A
system call in SCO Xenix whose failure detection requires the setting
of errno to zero and on a return from the call (whose return value
does not have a namespace incursion like "-1" or "NULL" that can
be relied upon as an error indicator), comparing errno to zero to
see if it was successful (if I recall correctly, the failure case
returned EWOULDBLOCK).

I admit that this is terribly bogus, but it's the ABI, so live with it.


A more prosaic example might be atoi(3), which casts the result
of a strtol(3) to an int.  On a machine where an int is 32 bits
and a long is 64 bits, it would be impossible to compare the
return value for the value LONG_MAX, which can't be represented
in 32 bits.

The method you would (presumably) use is:

	errno = 0;
	i = atoi( buf);
	if( errno == ERANGE)
		...



So the question becomes: "At what point can I expect a library routine
to behave like a system call"?

I *thought* that there were some ISO/POSIX requirements that errno
not be touched in non-error cases, and that "internally handled"
errors would restore the value to whatever it was before the occurance
of the internal error, thus fully encapsulating the error.


Consider:

	errno  = 0;
	printf( "testing for FreeBSD without malloc.conf....\n");
	if( errno == ENOFILE) {
		printf( "Sorry, your system is misconfigured!\n");
		exit( 1);
	}


This is especially an issue for POSIX threads implemented as a user
space call conversion scheduler; they are, in fact, library routines
which wrap system calls.

POSIX threads go to great lengths to do what I would call "the right
thing".


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199806191851.LAA12551>