Re: close return value (was Re: [ANNOUNCE] Ext3 vs Reiserfs benchmarks)

Linus Torvalds (torvalds@transmeta.com)
Wed, 17 Jul 2002 17:43:57 +0000 (UTC)


In article <20020717164933.GA2136@eskimo.com>,
Elladan <elladan@eskimo.com> wrote:
>
>Consider what this says, if a particular OS doesn't pick a standard
>which the application can port to. It means that the *only way* to
>correctly close a file descriptor is like this:
>
>int ret;
>do {
> ret = close(fd);
>} while(ret == -1 && errno != EBADF);

NO.

The above is
(a) not portable
(b) not current practice

The "not portable" part comes from the fact that (as somebody pointed
out), a threaded environment in which the kernel _does_ close the FD on
errors, the FD may have been validly re-used (by the kernel) for some
other thread, and closing the FD a second time is a BUG.

The "not practice" comes from the fact that applications do not do what
you suggest.

The fact is, what Linux does and has always done is the only reasonable
thing to do: the close _will_ tear down the FD, and the error value is
nothing but a warning to the application that there may still be IO
pending (or there may have been failed IO) on the file that the (now
closed) descriptor pointed to.

The application may want to take evasive action (ie try to write the
file again, make a backup, or just warn the user), but the file
descriptor is _gone_.

>That means, if we get an error, we have to loop until the kernel throws
>a BADF error! We can't detect that the file is closed from any other
>error value, because only BADF has a defined behavior.

But your loop is _provably_ incorrect for a threaded application. Your
explicit system call locking approach doesn't work either, because I'm
pretty certain that POSIX already states that open/close are thread
safe, so you can't just invalidate that _other_ standard.

Linus
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/