sscanf always generates error condition

Chris Lewis clewis at ferret.ocunix.on.ca
Sat May 18 12:40:23 AEST 1991


In article <785 at minya.UUCP> jc at minya.UUCP (John Chambers) writes:
>In article <1991May1.050122.21795 at athena.mit.edu>, jik at athena.mit.edu (Jonathan I. Kamens) writes:

>>   Second, technically speaking, the only time errno is relevant is when a
>> system call fails.  This means that, in the strictest sense, it is not valid
>> to use errno to find out what error occurred after a library function fails. 
>> However, in cases where you know that the library function failed because of a
>> failed system call, it's a good bet that errno will still contain the error
>> return value from the system call, so it's usually OK to use it to determine
>> what happened.

>Well, gee, I've written lots of routines that do things like:
>	if (f < 0 || f > maxfile) {
>		errno = EBADF;
>		return -1;
>	}
>I've recently seen a lot of suggestions, including the above, that I am
>violating some rules that I've never seen documented.  It seems that the
>naive programmer is highly likely to assume that such practices are not
>only legal, but encouraged.  Now I find that some people think that errno
>is not legal for me to use, even when it does the job quite elegantly.

>So if I'm not allowed to mimic the system calls in such a case, what should
>I do?  Should I set up a new global variable to hold the error code for each
>routine, and make up my own error codes for each one?  Sure, I can do this,
>but it doesn't seem like a very friendly thing to do to the poor suckers who
>use my routines.

>So what are the rules?  Is errno truly global, or is it supposed to be
>private to libc?  Where is it documented and specified that I am forbidden
>to use it in the obvious way, that I should have known about it?

I think you misunderstand.  The correct interpretation of the manuals is
that you can't rely on the value of errno after invoking a function (whether
system call or real function) *unless* the manual page for the function
*documents* that the value of errno is set on error, and that the function
has actually returned an error.  I've not seen documentation saying that
you cannot set errno yourself.

For example, go look at the manual page for open().  It will probably give
a list of what conditions lead to the errno being set, and what it'll be
set to.  Therefore, if (open(...) < 0) you can inspect errno and be
guaranteed that errno is relevant to the real error.  On the other hand, for
printf(), there is no documented settings for errno, thus errno cannot
be trusted to mean anything relevant if printf() returns an error.

I say "system call or function" *because* some functions are documented to
set errno.  Sometimes because they're emulating a system call (eg: various
flavors of exec), and sometimes because the original definition did.  Further,
many functions that aren't documented to set errno on error, *may* invoke
something that does (depending on implementation specifics), and the errno
setting may have *nothing* to do whatsoever with the function you actually
called.  Ie: the infamous "not a tty" or "invalid ioctl on device"
errno after a printf().

I've never seen anything prohibiting you from setting errno in a function
of your own and testing it.  However, you must be cautious that anything
you invoke between the time you set errno and the time you test it doesn't
clobber errno.  Ie this is dangerous:

	if (f < 0 || f > maxfile) {
	    errno = EBADF;
	    fprintf(stderr, "You goofed\n");
	    return -1;
	}

Swap the order of the fprintf and the errno assignment and it'll be safe
as far as I know.

[Some systems might just make the errno read-only but I don't know of
any.  I know that some systems have errno at an absolute address near the top
of the user's stack.  Others have it at a special absolute place in the image's
data space.  Still others inlined it in the text area - but those didn't
have readonly text.]
-- 
Chris Lewis, Phone: (613) 832-0541, Domain: clewis at ferret.ocunix.on.ca
UUCP: ...!cunews!latour!ecicrl!clewis; Ferret Mailing List:
ferret-request at eci386; Psroff (not Adobe Transcript) enquiries:
psroff-request at eci386 or Canada 416-832-0541.  Psroff 3.0 in c.s.u soon!



More information about the Comp.unix.programmer mailing list