mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-15 20:25:12 +01:00
tests: Test EBADF and errno handling when closing fds
Signed-off-by: Simon McVittie <smcv@collabora.com>
This commit is contained in:
parent
81130a6e3f
commit
f1f711dc77
@ -2470,6 +2470,64 @@ assert_fd_was_closed (int fd)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_clear_fd_ebadf (void)
|
||||
{
|
||||
char *name = NULL;
|
||||
GError *error = NULL;
|
||||
int fd;
|
||||
int copy_of_fd;
|
||||
int errsv;
|
||||
gboolean ret;
|
||||
|
||||
/* We're going to trigger a programming error: attmpting to close a
|
||||
* fd that was already closed. Make criticals non-fatal. */
|
||||
g_assert_true (g_test_undefined ());
|
||||
g_log_set_always_fatal (G_LOG_FATAL_MASK);
|
||||
g_log_set_fatal_mask ("GLib", G_LOG_FATAL_MASK);
|
||||
|
||||
fd = g_file_open_tmp (NULL, &name, &error);
|
||||
g_assert_cmpint (fd, !=, -1);
|
||||
g_assert_no_error (error);
|
||||
g_assert_nonnull (name);
|
||||
ret = g_close (fd, &error);
|
||||
g_assert_no_error (error);
|
||||
assert_fd_was_closed (fd);
|
||||
g_assert_true (ret);
|
||||
g_unlink (name);
|
||||
g_free (name);
|
||||
|
||||
/* Try to close it again with g_close() */
|
||||
ret = g_close (fd, NULL);
|
||||
errsv = errno;
|
||||
g_assert_cmpint (errsv, ==, EBADF);
|
||||
assert_fd_was_closed (fd);
|
||||
g_assert_false (ret);
|
||||
|
||||
/* Try to close it again with g_clear_fd() */
|
||||
copy_of_fd = fd;
|
||||
errno = EILSEQ;
|
||||
ret = g_clear_fd (©_of_fd, NULL);
|
||||
errsv = errno;
|
||||
g_assert_cmpint (errsv, ==, EBADF);
|
||||
assert_fd_was_closed (fd);
|
||||
g_assert_false (ret);
|
||||
|
||||
#ifdef g_autofree
|
||||
{
|
||||
g_autofd int close_me = fd;
|
||||
|
||||
/* This avoids clang warnings about the variables being unused */
|
||||
g_test_message ("Invalid fd will be closed by autocleanup: %d",
|
||||
close_me);
|
||||
errno = EILSEQ;
|
||||
}
|
||||
|
||||
errsv = errno;
|
||||
g_assert_cmpint (errsv, ==, EILSEQ);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
test_clear_fd (void)
|
||||
{
|
||||
@ -2477,6 +2535,7 @@ test_clear_fd (void)
|
||||
GError *error = NULL;
|
||||
int fd;
|
||||
int copy_of_fd;
|
||||
int errsv;
|
||||
|
||||
#ifdef g_autofree
|
||||
g_test_summary ("Test g_clear_fd() and g_autofd");
|
||||
@ -2522,12 +2581,31 @@ test_clear_fd (void)
|
||||
/* This avoids clang warnings about the variables being unused */
|
||||
g_test_message ("Will be closed by autocleanup: %d, %d",
|
||||
close_me, was_never_set);
|
||||
/* This is one of the few errno values guaranteed by Standard C.
|
||||
* We set it here to check that a successful g_autofd close doesn't
|
||||
* alter errno. */
|
||||
errno = EILSEQ;
|
||||
}
|
||||
|
||||
errsv = errno;
|
||||
g_assert_cmpint (errsv, ==, EILSEQ);
|
||||
assert_fd_was_closed (fd);
|
||||
g_unlink (name);
|
||||
g_free (name);
|
||||
#endif
|
||||
|
||||
if (g_test_undefined ())
|
||||
{
|
||||
g_test_message ("Testing error handling");
|
||||
g_test_trap_subprocess ("/fileutils/clear-fd/subprocess/ebadf",
|
||||
0, G_TEST_SUBPROCESS_DEFAULT);
|
||||
#ifdef g_autofree
|
||||
g_test_trap_assert_stderr ("*failed with EBADF*failed with EBADF*failed with EBADF*");
|
||||
#else
|
||||
g_test_trap_assert_stderr ("*failed with EBADF*failed with EBADF*");
|
||||
#endif
|
||||
g_test_trap_assert_passed ();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
@ -2567,6 +2645,7 @@ main (int argc,
|
||||
g_test_add_func ("/fileutils/stdio-wrappers", test_stdio_wrappers);
|
||||
g_test_add_func ("/fileutils/fopen-modes", test_fopen_modes);
|
||||
g_test_add_func ("/fileutils/clear-fd", test_clear_fd);
|
||||
g_test_add_func ("/fileutils/clear-fd/subprocess/ebadf", test_clear_fd_ebadf);
|
||||
|
||||
return g_test_run ();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user