Merge branch 'th/g-close-ebadf' into 'main'

gstdio: fail assertion in g_close() for invalid file descriptor (EBADF)

See merge request GNOME/glib!2964
This commit is contained in:
Philip Withnall 2022-10-18 13:19:26 +00:00
commit 1f00fc9212

View File

@ -1757,6 +1757,8 @@ g_utime (const gchar *filename,
* attempt to correctly handle %EINTR, which has platform-specific * attempt to correctly handle %EINTR, which has platform-specific
* semantics. * semantics.
* *
* It is a bug to call this function with an invalid file descriptor.
*
* Returns: %TRUE on success, %FALSE if there was an error. * Returns: %TRUE on success, %FALSE if there was an error.
* *
* Since: 2.36 * Since: 2.36
@ -1766,26 +1768,54 @@ g_close (gint fd,
GError **error) GError **error)
{ {
int res; int res;
res = close (fd); res = close (fd);
if (res == -1)
{
int errsv = errno;
if (errsv == EINTR)
{
/* Just ignore EINTR for now; a retry loop is the wrong thing to do /* Just ignore EINTR for now; a retry loop is the wrong thing to do
* on Linux at least. Anyone who wants to add a conditional check * on Linux at least. Anyone who wants to add a conditional check
* for e.g. HP-UX is welcome to do so later... * for e.g. HP-UX is welcome to do so later...
* *
* https://lwn.net/Articles/576478/
* http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html * http://lkml.indiana.edu/hypermail/linux/kernel/0509.1/0877.html
* https://bugzilla.gnome.org/show_bug.cgi?id=682819 * https://bugzilla.gnome.org/show_bug.cgi?id=682819
* http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR * http://utcc.utoronto.ca/~cks/space/blog/unix/CloseEINTR
* https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain * https://sites.google.com/site/michaelsafyan/software-engineering/checkforeintrwheninvokingclosethinkagain
*/ */
if (G_UNLIKELY (res == -1 && errno == EINTR))
return TRUE; return TRUE;
else if (res == -1) }
{
int errsv = errno;
g_set_error_literal (error, G_FILE_ERROR, g_set_error_literal (error, G_FILE_ERROR,
g_file_error_from_errno (errsv), g_file_error_from_errno (errsv),
g_strerror (errsv)); g_strerror (errsv));
if (errsv == EBADF)
{
if (fd >= 0)
{
/* Closing an non-negative, invalid file descriptor is a bug. The bug is
* not necessarily in the caller of g_close(), but somebody else
* might have wrongly closed fd. In any case, there is a serious bug
* somewhere. */
g_critical ("g_close(fd:%d) failed with EBADF. The tracking of file descriptors got messed up", fd);
}
else
{
/* Closing a negative "file descriptor" is less problematic. It's still a nonsensical action
* from the caller. Assert against that too. */
g_critical ("g_close(fd:%d) failed with EBADF. This is not a valid file descriptor", fd);
}
}
errno = errsv; errno = errsv;
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }