ENOTTY error when executing cp(1)

Guy Shaw shaw at paralogics.UUCP
Mon Sep 25 19:33:19 AEST 1989


In article <109 at harald.UUCP>, jba at 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 at munnari.oz.au>, ok at 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 at uunet.uu.net  or  uunet!paralogics!shaw



More information about the Comp.unix.wizards mailing list