diff --git a/glnx-fdio.c b/glnx-fdio.c index 09aa87f68e4b4e291248fbbdeeb704b46d4545de..ffe5400d179914e96218a26c5d6b224a94f233ab 100644 --- a/glnx-fdio.c +++ b/glnx-fdio.c @@ -53,6 +53,15 @@ sizeof(type) <= 4 ? 10 : \ sizeof(type) <= 8 ? 20 : sizeof(int[-2*(sizeof(type) > 8)]))) +gboolean +glnx_stdio_file_flush (FILE *f, GError **error) +{ + if (fflush (f) != 0) + return glnx_throw_errno_prefix (error, "fflush"); + if (ferror (f) != 0) + return glnx_throw_errno_prefix (error, "ferror"); + return TRUE; +} /* An implementation of renameat2(..., RENAME_NOREPLACE) * with fallback to a non-atomic version. diff --git a/glnx-fdio.h b/glnx-fdio.h index f459e93ab181ecd307dda93676dc70b38fd36f1b..150b22e3e22bb769ab85f7261621dfad8ad809bd 100644 --- a/glnx-fdio.h +++ b/glnx-fdio.h @@ -50,6 +50,23 @@ const char *glnx_basename (const char *path) return (basename) (path); } +/* Utilities for standard FILE* */ +static inline void +glnx_stdio_file_cleanup (void *filep) +{ + FILE *f = filep; + if (f) + fclose (f); +} +G_DEFINE_AUTOPTR_CLEANUP_FUNC(FILE, glnx_stdio_file_cleanup) + +/** + * glnx_stdio_file_flush: + * Call fflush() and check ferror(). + */ +gboolean +glnx_stdio_file_flush (FILE *f, GError **error); + typedef struct { gboolean initialized; gboolean anonymous; diff --git a/tests/test-libglnx-fdio.c b/tests/test-libglnx-fdio.c index cee7cb683cd6d0737f8005cffeee66fa333142d7..d4e627235c1e298fe5d562bf9ab0482987c656d0 100644 --- a/tests/test-libglnx-fdio.c +++ b/tests/test-libglnx-fdio.c @@ -160,6 +160,28 @@ test_tmpfile (void) g_assert_no_error (local_error); } +static void +test_stdio_file (void) +{ + g_autoptr(GError) local_error = NULL; + GError **error = &local_error; + g_auto(GLnxTmpfile) tmpf = { 0, }; + if (!glnx_open_anonymous_tmpfile (O_RDWR|O_CLOEXEC, &tmpf, error)) + goto out; + + g_autoptr(FILE) f = fdopen (tmpf.fd, "w"); + if (fwrite ("hello", 1, strlen ("hello"), f) != strlen ("hello")) + { + (void)glnx_throw_errno_prefix (error, "fwrite"); + goto out; + } + if (!glnx_stdio_file_flush (f, error)) + goto out; + + out: + g_assert_no_error (local_error); +} + int main (int argc, char **argv) { int ret; @@ -167,6 +189,7 @@ int main (int argc, char **argv) g_test_init (&argc, &argv, NULL); g_test_add_func ("/tmpfile", test_tmpfile); + g_test_add_func ("/stdio-file", test_stdio_file); g_test_add_func ("/renameat2-noreplace", test_renameat2_noreplace); g_test_add_func ("/renameat2-exchange", test_renameat2_exchange);