[PATCH v5 3/4] msvcrt/tests: Add test for fopen/_open access hints
Luke Deller
luke at deller.id.au
Wed Aug 4 06:29:36 CDT 2021
Test passing sequential and random access hints to fopen and _open.
Test that the underlying windows handle actually has the corresponding
FILE_SEQUENTIAL_ONLY mode set correctly.
Signed-off-by: Luke Deller <luke at deller.id.au>
---
v5: reordered patches so that tests are added after dll changes
---
dlls/msvcrt/tests/file.c | 124 +++++++++++++++++++++++++++++++++++++++
1 file changed, 124 insertions(+)
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index fb242d81282..7a55e040d1c 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -35,6 +35,7 @@
#include <process.h>
#include <errno.h>
#include <locale.h>
+#include <winternl.h>
#define MSVCRT_FD_BLOCK_SIZE 32
typedef struct {
@@ -2731,6 +2732,127 @@ static void test_lseek(void)
DeleteFileA("_creat.tst");
}
+static BOOL has_sequential_hint(int fd)
+{
+ HANDLE handle;
+ FILE_MODE_INFORMATION mode_info;
+ IO_STATUS_BLOCK io;
+ NTSTATUS status;
+
+ /* Check whether the file handle has the sequential access hint */
+ handle = (HANDLE)_get_osfhandle(fd);
+ status = NtQueryInformationFile(handle, &io, &mode_info, sizeof(mode_info),
+ FileModeInformation);
+ ok(!status, "NtQueryInformationFile failed\n");
+ return (mode_info.Mode & FILE_SEQUENTIAL_ONLY) != 0;
+}
+
+static void test_fopen_hints(void)
+{
+ char *tempf;
+ FILE *fp;
+ int i;
+
+ /* fopen modes to test */
+ const char *fopen_modes[] = {
+ "rb", "rbS", "rbR", "rbSR", "rbRS"
+ };
+ /* corresponding expected hints */
+ BOOL expected_hints[][2] = {
+ /* expect_sequential, expect_random */
+ {FALSE, FALSE},
+ {TRUE, FALSE},
+ {FALSE, TRUE},
+ {TRUE, FALSE},
+ {FALSE, TRUE},
+ };
+
+ /* create a test file */
+ tempf = _tempnam(".","wne");
+ fp = fopen(tempf, "wb");
+ ok(fp != NULL, "unable to create test file\n");
+ fwrite("abc\n", 1, 4, fp);
+ fclose(fp);
+
+ /* test fopen with each mode */
+ for (i = 0; i < sizeof(fopen_modes)/sizeof(char*); ++i)
+ {
+ BOOL expect_sequential, has_sequential;
+ const char *mode = fopen_modes[i];
+ expect_sequential = expected_hints[i][0];
+
+ fp = fopen(tempf, mode);
+ ok(fp != NULL, "unable to fopen test file with mode \"%s\"\n", mode);
+
+ has_sequential = has_sequential_hint(_fileno(fp));
+ ok(has_sequential == expect_sequential,
+ "unexpected sequential hint %d for fopen mode \"%s\"\n",
+ has_sequential, mode);
+
+ /* TODO: Somehow check whether the random access hint has been applied.
+ * Sadly NtQueryInformationFile does not expose this information. */
+
+ fclose(fp);
+ }
+
+ unlink(tempf);
+ free(tempf);
+}
+
+static void test_open_hints(void)
+{
+ char *tempf;
+ int fd;
+ int i;
+
+ /* fopen modes to test */
+ int open_flags[] = {
+ _O_RDONLY | _O_BINARY,
+ _O_RDONLY | _O_BINARY | _O_SEQUENTIAL,
+ _O_RDONLY | _O_BINARY | _O_RANDOM,
+ _O_RDONLY | _O_BINARY | _O_RANDOM | _O_SEQUENTIAL,
+ };
+ /* corresponding expected hints */
+ BOOL expected_hints[][2] = {
+ /* expect_sequential, expect_random */
+ {FALSE, FALSE},
+ {TRUE, FALSE},
+ {FALSE, TRUE},
+ {TRUE, TRUE},
+ };
+
+ /* create a test file */
+ tempf = _tempnam(".","wne");
+ fd = _open(tempf, _O_CREAT | _O_WRONLY | _O_BINARY);
+ ok(fd != -1, "unable to create test file\n");
+ _write(fd, "abc\n", 4);
+ _close(fd);
+
+ /* test _open with each mode */
+ for (i = 0; i < sizeof(open_flags)/sizeof(int); ++i)
+ {
+ BOOL expect_sequential, has_sequential;
+ int flags = open_flags[i];
+ expect_sequential = expected_hints[i][0];
+
+ fd = open(tempf, flags);
+ ok(fd != -1, "unable to _open test file with flags %x\n", flags);
+
+ has_sequential = has_sequential_hint(fd);
+ ok(has_sequential == expect_sequential,
+ "unexpected sequential hint %d for _open flags %x\n",
+ has_sequential, flags);
+
+ /* TODO: Somehow check whether the random access hint has been applied.
+ * Sadly NtQueryInformationFile does not expose this information. */
+
+ close(fd);
+ }
+
+ unlink(tempf);
+ free(tempf);
+}
+
START_TEST(file)
{
int arg_c;
@@ -2803,6 +2925,8 @@ START_TEST(file)
test_close();
test__creat();
test_lseek();
+ test_fopen_hints();
+ test_open_hints();
/* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
* file contains lines in the correct order
--
2.25.1
More information about the wine-devel
mailing list