The process std handles should be preserved in this case.
Fixes error on startup in "Re:ZERO -Starting Life in Another World- The Prophecy of the Throne" launcher.
Signed-off-by: Paul Gofman pgofman@codeweavers.com --- dlls/msvcrt/file.c | 2 +- dlls/msvcrt/tests/file.c | 41 ++++++++++++++++++++++++++++++---------- 2 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/dlls/msvcrt/file.c b/dlls/msvcrt/file.c index 73e1a82476f..89d6e7d721f 100644 --- a/dlls/msvcrt/file.c +++ b/dlls/msvcrt/file.c @@ -586,7 +586,7 @@ void msvcrt_init_io(void) count = min(count, MSVCRT_MAX_FILES); for (i = 0; i < count; i++) { - if ((*wxflag_ptr & WX_OPEN) && *handle_ptr != INVALID_HANDLE_VALUE) + if ((*wxflag_ptr & WX_OPEN) && GetFileType(*handle_ptr) != FILE_TYPE_UNKNOWN) { fdinfo = get_ioinfo_alloc_fd(i); if(fdinfo != &MSVCRT___badioinfo) diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c index 0cf8bad124f..5d5b3dbffc9 100644 --- a/dlls/msvcrt/tests/file.c +++ b/dlls/msvcrt/tests/file.c @@ -1454,13 +1454,27 @@ static void test_file_write_read( void ) free(tempf); }
-static void test_file_inherit_child(const char* fd_s) +static void test_file_inherit_child(const char* fd_s, const char *handle_str) { + HANDLE handle_value; int fd = atoi(fd_s); + HANDLE *handle_ptr; + unsigned int count; char buffer[32]; + STARTUPINFOA si; int ret;
- ret =write(fd, "Success", 8); + GetStartupInfoA(&si); + count = *(unsigned *)si.lpReserved2; + if (handle_str && count >= 2) + { + sscanf(handle_str, "%p", &handle_value); + handle_ptr = (HANDLE *)(si.lpReserved2 + sizeof(unsigned) + count); + ok(handle_value == handle_ptr[1], "Got unexpected handle %p.\n", handle_ptr[1]); + } + + count = min(count, (si.cbReserved2 - sizeof(unsigned)) / (sizeof(HANDLE) + 1)); + ret = write(fd, "Success", 8); ok( ret == 8, "Couldn't write in child process on %d (%s)\n", fd, strerror(errno)); lseek(fd, 0, SEEK_SET); ok(read(fd, buffer, sizeof (buffer)) == 8, "Couldn't read back the data\n"); @@ -1635,14 +1649,21 @@ static void test_file_inherit( const char* selfname ) CloseHandle( handles[1] ); DeleteFileA("fdopen.tst");
- /* test inherit block with larger size */ - handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE, - FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL ); + /* test inherit block with invalid handle */ + handles[1] = INVALID_HANDLE_VALUE; create_io_inherit_block( &startup, 3, handles ); - startup.cbReserved2 += 7; - test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" ); - CloseHandle( handles[1] ); - DeleteFileA("fdopen.tst"); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "INVALID_HANDLE_VALUE stdout handle" ); + + handles[1] = NULL; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "NULL stdout handle" ); + + handles[1] = (void *)0xdeadbeef; + create_io_inherit_block( &startup, 3, handles ); + sprintf(cmdline, "%s file inherit 1 %p", selfname, handles[1]); + test_stdout_handle( &startup, cmdline, NULL, FALSE, "invalid stdout handle" ); }
static void test_invalid_stdin_child( void ) @@ -2714,7 +2735,7 @@ START_TEST(file) if (arg_c >= 3) { if (strcmp(arg_v[2], "inherit") == 0) - test_file_inherit_child(arg_v[3]); + test_file_inherit_child(arg_v[3], arg_c > 4 ? arg_v[4] : NULL); else if (strcmp(arg_v[2], "inherit_no") == 0) test_file_inherit_child_no(arg_v[3]); else if (strcmp(arg_v[2], "pipes") == 0)
Hi Paul,
The change in implementation looks good for me.
On 2/15/21 12:43 PM, Paul Gofman wrote:
-static void test_file_inherit_child(const char* fd_s) +static void test_file_inherit_child(const char* fd_s, const char *handle_str) {
- HANDLE handle_value; int fd = atoi(fd_s);
- HANDLE *handle_ptr;
- unsigned int count; char buffer[32];
- STARTUPINFOA si; int ret;
- ret =write(fd, "Success", 8);
- GetStartupInfoA(&si);
- count = *(unsigned *)si.lpReserved2;
- if (handle_str && count >= 2)
- {
sscanf(handle_str, "%p", &handle_value);
handle_ptr = (HANDLE *)(si.lpReserved2 + sizeof(unsigned) + count);
ok(handle_value == handle_ptr[1], "Got unexpected handle %p.\n", handle_ptr[1]);
- }
- count = min(count, (si.cbReserved2 - sizeof(unsigned)) / (sizeof(HANDLE) + 1));
count is never used after the last assignment. It probably makes sense to change the code to something like: if (handle_str) { HANDLE handle_value, handle_ptr; unsigned int count; STARTUPINFOA si;
GetStartupInfoA(&si); count = *(unsigned int*)si.lpReserved2; ok(count == 3, "count = %u\n", count);
sscanf(handle_str, "%p", &handle_value); ...
- /* test inherit block with larger size */
- handles[1] = CreateFileA( "fdopen.tst", GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, CREATE_ALWAYS, 0, NULL );
- /* test inherit block with invalid handle */
- handles[1] = INVALID_HANDLE_VALUE; create_io_inherit_block( &startup, 3, handles );
- startup.cbReserved2 += 7;
- test_stdout_handle( &startup, cmdline, handles[1], TRUE, "large size block" );
- CloseHandle( handles[1] );
- DeleteFileA("fdopen.tst");
Is there any reason for removing the "test inherit block with larger size" test?
Thanks, Piotr
On 2/15/21 17:27, Piotr Caban wrote:
Hi Paul, + count = min(count, (si.cbReserved2 - sizeof(unsigned)) / (sizeof(HANDLE) + 1)); count is never used after the last assignment. It probably makes sense to change the code to something like:
Thanks, I will update the test.
Is there any reason for removing the "test inherit block with larger size" test?
Oh no, it happened by accident, sorry.