Hello all,

Following a discussion [4][5] (and a bit of education for me, thanks
to Rich Felker) on the GNU C Library (libc-alpha) mailing list, I have
some questions about bug 529 [0].

1. If I understand correctly, the proposed changes for Issue 8 will in
effect declare to be broken those existing applications that treat
EINTR from close() as "the file is closed". (I.e., per the proposed
changes [7], implementations will not be allowed to have close() fail
with EINTR while also closing the file.) However, those existing
applications are behaving correctly in terms of what the
implementations do. Is my understanding of the intentions of the Issue
8 changes correct? If yes, I presume the path is that such
applications would be conformant to older POSIX, but won't be
conformant to Issue 8. (Right?)

2. From the bug thread, I've missed something. I understand the
argument that EINTR was being treated inconsistently for close() on
Linux and other systems, but the thing is that implementations with
the close() "EINTR means the file descriptor is closed" behavior
exist, and seem even to be common. Why (given the variation in
existing implementations) was the decision taken to change the
specification for close() , instead of just adding a new posix_close()
that addresses the problem?

3. [An observation, not a question] As far as I can tell, the Linux
behavior for close() EINTR semantics is not an isolated case. One can
see this in the FreeBSD close(2) manual page [1] and in the AIX [2]
manual page. It seems also to be the norm for other implementations
(see my next point). HP-UX claims [6] in the documentation to leave
the file open on EINTR, but unfortunately, the source code isn't
publicly available to verify this

4. The interpretation for bug 529 doesn't address a wider issue. On
several implementations, the FD is always closed *for any error* that
close() may return. That is what Linux does (the FD is released very
early in the "close" processing, and errors may be reported
afterward). It's also what FreeBSD does, as documented in its close(2)
man page:

    In case of any error except EBADF, the supplied file descriptor
    is deallocated and therefore is no longer valid.

(By the way, that text seems to have been added in FreeBSD 9.1, in
early 2012, I presume to document existing behavior after someone read
this Austin bug report.)

For info, FreeBSD documents the following errors for close(): EBADF,
EINTR, ENOSPC, and ECONNRESET.

Looking at some historical source code (mostly from [3]) suggests that
the "close() always closes regardless of error return" behavior has a
long history, predating even POSIX.1-1990.

For example, in SVR4 for x86 (from the file sysvr4.tar.bz2 at [3]), we
see the following:

===
int
close(uap, rvp)
        register struct closea *uap;
        rval_t *rvp;
{
        file_t *fp;
        register int error;

        if (error = getf(uap->fdes, &fp))
                return error;
        error = closef(fp);
        setf(uap->fdes, NULLFP);
        return error;
}
===

In the above, getf() can return EBADF. The other errors are returned
by closef(), but the file descriptor is deallocated regardless of
errors by setf().

A similar pattern seems to have been preserved into at least late
OpenSolaris days (verified from looking at the initial commit of the
illumos source code). There we find the following in closeandsetf()
(called by close())

        error = closef(fp);

        setf(fd, newfp);

        return (error);

Looking at the code of closef() in AIX 4.1.3 suggests that, as on on
Linux and FreeBSD, the open file is always released, regardless of
errors.

For Irix, 6.5.5, I'm not sure (the code is not so easy to quickly
read); it may be that it does return errors while leaving the FD open.

So, my summary here is that many (perhaps most?) implementations are
similar to Linux and FreeBSD, but this isn't currently addressed in
POSIX, so far as I can tell. Should it be?

Cheers,

Michael

[0] http://austingroupbugs.net/view.php?id=529
[1] 
https://www.freebsd.org/cgi/man.cgi?query=close&apropos=0&sektion=0&manpath=FreeBSD+10.3-RELEASE+and+Ports&arch=default&format=html#ERRORS
[2] 
http://publib16.boulder.ibm.com/doc_link/en_US/a_doc_lib/libs/basetrf1/close.htm
[3] https://archive.org/download/various_operating_system_source_code
[4] https://sourceware.org/ml/libc-alpha/2016-12/msg00110.html
[5] https://sourceware.org/ml/libc-alpha/2016-12/msg00136.html
[6] http://www.unix.com/man-page/hpux/2/close/
[7] http://austingroupbugs.net/view.php?id=529#c1200

Reply via email to