close(), exceptions and problems

Jeff Epler jepler at inetnebr.com
Mon Mar 26 08:58:39 EST 2001


On Sun, 25 Mar 2001 17:04:36 +0000 (UTC), Erwin S. Andreasen
 <erwin at andreasen.com> wrote:
>But this only happens when SA_RESTART is not set (OK, I thought it was
>SA_NORESTART to *disable* restarting but it's SA_RESTART to enable
>restarting).
>
>Read the "Interrupted Primitives" node for more information.
>
>Maybe the threading library on the platform the original poster uses does not
>set the SA_RESTART flag (if its threads are userspace, switched by receiving
>SIUGUSR1) ? But that's hard to believe.

Well, *either*
	1) The system returns -EINTR on close() and the file is not closed.
	   This should cause fclose() to return EOF, and Python to raise
	   an IOError.
	2) The system restarts the close() syscall internally in fclose().
	   When the fclose() call returns, it must have succeeded.
I don't see how anything else could happen.

However, I did just notice one potential problem when the system raises
IOError on close.  Regardless of the returned value from f->f_close(f->f_fp),
f->f_fp is set to NULL.  Thus, if close() returns -EINTR, the underlying fd
is not closed, but the file is marked as closed, and in effect the file is
"leaked".

Could this be the behavior the original poster was referring to?

Untested pseudo-patch below.

Jeff

static PyObject *
file_close(PyFileObject *f, PyObject *args)
{
        int sts = 0;
        if (!PyArg_NoArgs(args))
                return NULL;
        if (f->f_fp != NULL) {
                if (f->f_close != NULL) {
                        Py_BEGIN_ALLOW_THREADS
                        errno = 0;
                        sts = (*f->f_close)(f->f_fp);
                        Py_END_ALLOW_THREADS
                }
-               f->f_fp = NULL; 
+		if (sts != EOF) {
+                       f->f_fp = NULL;
+               }
        }
        if (sts == EOF)
                return PyErr_SetFromErrno(PyExc_IOError);
        if (sts != 0)
                return PyInt_FromLong((long)sts);
        Py_INCREF(Py_None);
        return Py_None;
}




More information about the Python-list mailing list