Path: utzoo!utdoe!contact!robohack!eci386!ecicrl!clewis From: clewis@ferret.ocunix.on.ca (Chris Lewis) Newsgroups: comp.unix.programmer Subject: Re: sscanf always generates error condition Message-ID: <1511@ecicrl.ocunix.on.ca> Date: 18 May 91 02:40:23 GMT References: <1991Apr30.233554.1321@agate.berkeley.edu> <1991May1.050122.21795@athena.mit.edu> <785@minya.UUCP> Distribution: usa Organization: Elegant Communications Inc., Ottawa, Canada Lines: 79 In article <785@minya.UUCP> jc@minya.UUCP (John Chambers) writes: >In article <1991May1.050122.21795@athena.mit.edu>, jik@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@ferret.ocunix.on.ca UUCP: ...!cunews!latour!ecicrl!clewis; Ferret Mailing List: ferret-request@eci386; Psroff (not Adobe Transcript) enquiries: psroff-request@eci386 or Canada 416-832-0541. Psroff 3.0 in c.s.u soon!