Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!uunet!paralogics!shaw From: shaw@paralogics.UUCP (Guy Shaw) Newsgroups: comp.unix.wizards Subject: Re: ENOTTY error when executing cp(1) Summary: This isn't safe either Message-ID: <250@paralogics.UUCP> Date: 25 Sep 89 09:33:19 GMT References: <507@fdmetd.uucp> <2556@taux01.UUCP> <301@6sigma.UUCP> <109@harald.UUCP> Organization: Paralogics; Santa Monica, CA Lines: 70 In article <109@harald.UUCP>, jba@harald.ruc.dk (Jan B. Andersen) writes: > if( some_system_call() ) { > printf( "errno %d has occured in some_system_call()\n", errno ); > exit( errno ); > } 1. "if (some_system_call()) { ... }" is not the way to test for failure of a system call. Most system calls return -1 to indicate failure, and may return 0 or some other non-zero result, if successful. 2. Even after substituting an appropriate test for failure, such as, "if (some_system_call() == -1)", there is still a problem. Printf() may invoke a system call, for instance write(). In that case, the value of errno will be the droppings from that system call, whether it was successful or not. So, the "exit(errno)" may cause the program to exit with the new value of errno as its return code. > If you don't like if'ing the call do something like this: > > errno = 0; > some_system_call(); > if( errno ) { > ... > } Again, this is not safe. Errno should be tested only after an error has occurred. It is not just that successful system calls don't bother to clear errno; there is more to it than that. Clearing errno before a system call won't help. A system call can succeed and leave trash in errno. A system call can have code sequences in it like: errno = EBARF; if (! precondition) return (-1); ok_do_it(); return (handy_value); They are not obliged to be coded like: if (! precondition) { errno = EBARF; return (-1); } ok_do_it(); return (handy_value); In article <2163@munnari.oz.au>, ok@cs.mu.oz.au (Richard O'Keefe) writes: > But if we were talking extensions, I would much rather have a portable way > of making *sure* that I got the errno appropriate to a failed system call > (such as HP-UX's method that was posted some time ago), ... I missed that posting, but it sounds interesting. Judging from the number of postings that contain misconceptions about when errno is valid, I think there ought to be some kind of change. I have mixed feelings about which direction the change ought to take. On the one hand, the mistakes I see are all based on very natural assumptions - maybe those assumptions should be made valid in future. But then, for the foreseeable future, we would all have to code without making those assumptions, anyway, for the sake of backward compatibility. So, maybe future versions of UNIX should *guarantee* that errno will be set to garbage after all successful system calls. That will flush out a lot of latent bugs, and those people who have been "lucky" so far will learn quickly. -- Guy Shaw Paralogics paralogics!shaw@uunet.uu.net or uunet!paralogics!shaw