Files
flatpak/tests/libglnx-testlib.c
Simon McVittie 606dbdbc20 testlib: Add an assertion that a fd has really been closed
We can't easily assert this without triggering warnings from tools like
valgrind by doing an invalid operation on a closed fd, so we only check
this when under `-m undefined`.

Originally contributed to GLib 2.76 in GNOME/glib@b3934133
"gstdio: Add g_clear_fd() and g_autofd". The implementation in GLib used
g_fsync() as a portable thing that we can do with a fd, but that
function is newer than our minimum GLib version, and libglnx isn't
portable to non-Unix anyway, so use fnctl() instead.

Signed-off-by: Simon McVittie <smcv@collabora.com>
2026-04-07 15:59:31 +01:00

94 lines
2.4 KiB
C

/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
*
* Copyright 2019 Collabora Ltd.
* SPDX-License-Identifier: LGPL-2.0-or-later
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "libglnx-config.h"
#include "libglnx-testlib.h"
#include <errno.h>
#include <fcntl.h>
#include <glib/gstdio.h>
#include "libglnx.h"
struct _GLnxTestAutoTempDir
{
gchar *old_cwd;
int old_cwd_fd;
GLnxTmpDir temp_dir;
};
_GLnxTestAutoTempDir *
_glnx_test_auto_temp_dir_enter (void)
{
GError *error = NULL;
_GLnxTestAutoTempDir *ret = g_new0 (_GLnxTestAutoTempDir, 1);
glnx_mkdtemp ("glnx-test-XXXXXX", 0700, &ret->temp_dir, &error);
g_assert_no_error (error);
/* just for better diagnostics */
ret->old_cwd = g_get_current_dir ();
glnx_opendirat (-1, ".", TRUE, &ret->old_cwd_fd, &error);
g_assert_no_error (error);
if (fchdir (ret->temp_dir.fd) != 0)
g_error ("fchdir(<fd for \"%s\">): %s", ret->temp_dir.path, g_strerror (errno));
return ret;
}
void
_glnx_test_auto_temp_dir_leave (_GLnxTestAutoTempDir *dir)
{
GError *error = NULL;
if (fchdir (dir->old_cwd_fd) != 0)
g_error ("fchdir(<fd for \"%s\">): %s", dir->old_cwd, g_strerror (errno));
glnx_tmpdir_delete (&dir->temp_dir, NULL, &error);
g_assert_no_error (error);
glnx_close_fd (&dir->old_cwd_fd);
g_free (dir->old_cwd);
g_free (dir);
}
void
_glnx_test_assert_fd_was_closed (int fd)
{
/* We can't tell a fd was really closed without behaving as though it
* was still valid */
if (g_test_undefined ())
{
int result;
int errsv;
errno = 0;
result = fcntl (fd, F_GETFD, 0);
errsv = errno;
g_assert_cmpint (result, <, 0);
g_assert_cmpint (errsv, ==, EBADF);
}
}