Commit 0bfb1cbc authored by Eric Pouech's avatar Eric Pouech Committed by Alexandre Julliard

- msvcrt: the file descriptors are now inherited between parent/child

processes - kernel32.CreateProcess: make use of the *reserved2 fields for C-RunTime data inheritance
parent 77994cce
...@@ -439,8 +439,8 @@ void ENV_CopyStartupInformation(void) ...@@ -439,8 +439,8 @@ void ENV_CopyStartupInformation(void)
startup_infoW.dwFillAttribute = rupp->dwFillAttribute; startup_infoW.dwFillAttribute = rupp->dwFillAttribute;
startup_infoW.dwFlags = rupp->dwFlags; startup_infoW.dwFlags = rupp->dwFlags;
startup_infoW.wShowWindow = rupp->wShowWindow; startup_infoW.wShowWindow = rupp->wShowWindow;
startup_infoW.cbReserved2 = 0; startup_infoW.cbReserved2 = rupp->RuntimeInfo.Length;
startup_infoW.lpReserved2 = NULL; startup_infoW.lpReserved2 = (void*)rupp->RuntimeInfo.Buffer;
startup_infoW.hStdInput = rupp->hStdInput; startup_infoW.hStdInput = rupp->hStdInput;
startup_infoW.hStdOutput = rupp->hStdOutput; startup_infoW.hStdOutput = rupp->hStdOutput;
startup_infoW.hStdError = rupp->hStdError; startup_infoW.hStdError = rupp->hStdError;
...@@ -462,8 +462,8 @@ void ENV_CopyStartupInformation(void) ...@@ -462,8 +462,8 @@ void ENV_CopyStartupInformation(void)
startup_infoA.dwFillAttribute = rupp->dwFillAttribute; startup_infoA.dwFillAttribute = rupp->dwFillAttribute;
startup_infoA.dwFlags = rupp->dwFlags; startup_infoA.dwFlags = rupp->dwFlags;
startup_infoA.wShowWindow = rupp->wShowWindow; startup_infoA.wShowWindow = rupp->wShowWindow;
startup_infoA.cbReserved2 = 0; startup_infoA.cbReserved2 = rupp->RuntimeInfo.Length;
startup_infoA.lpReserved2 = NULL; startup_infoA.lpReserved2 = (void*)rupp->RuntimeInfo.Buffer;
startup_infoA.hStdInput = rupp->hStdInput; startup_infoA.hStdInput = rupp->hStdInput;
startup_infoA.hStdOutput = rupp->hStdOutput; startup_infoA.hStdOutput = rupp->hStdOutput;
startup_infoA.hStdError = rupp->hStdError; startup_infoA.hStdError = rupp->hStdError;
......
...@@ -1386,7 +1386,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST ...@@ -1386,7 +1386,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST
const STARTUPINFOW *startup ) const STARTUPINFOW *startup )
{ {
RTL_USER_PROCESS_PARAMETERS *params; RTL_USER_PROCESS_PARAMETERS *params;
UNICODE_STRING image_str, cmdline_str, curdir_str, desktop, title; UNICODE_STRING image_str, cmdline_str, curdir_str, desktop, title, runtime;
NTSTATUS status; NTSTATUS status;
WCHAR buffer[MAX_PATH]; WCHAR buffer[MAX_PATH];
...@@ -1400,13 +1400,19 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST ...@@ -1400,13 +1400,19 @@ static RTL_USER_PROCESS_PARAMETERS *create_user_params( LPCWSTR filename, LPCWST
if (cur_dir) RtlInitUnicodeString( &curdir_str, cur_dir ); if (cur_dir) RtlInitUnicodeString( &curdir_str, cur_dir );
if (startup->lpDesktop) RtlInitUnicodeString( &desktop, startup->lpDesktop ); if (startup->lpDesktop) RtlInitUnicodeString( &desktop, startup->lpDesktop );
if (startup->lpTitle) RtlInitUnicodeString( &title, startup->lpTitle ); if (startup->lpTitle) RtlInitUnicodeString( &title, startup->lpTitle );
if (startup->lpReserved2 && startup->cbReserved2)
{
runtime.Length = runtime.MaximumLength = startup->cbReserved2;
runtime.Buffer = (WCHAR*)startup->lpReserved2;
}
status = RtlCreateProcessParameters( &params, &image_str, NULL, status = RtlCreateProcessParameters( &params, &image_str, NULL,
cur_dir ? &curdir_str : NULL, cur_dir ? &curdir_str : NULL,
&cmdline_str, env, &cmdline_str, env,
startup->lpTitle ? &title : NULL, startup->lpTitle ? &title : NULL,
startup->lpDesktop ? &desktop : NULL, startup->lpDesktop ? &desktop : NULL,
NULL, NULL ); NULL,
(startup->lpReserved2 && startup->cbReserved2) ? &runtime : NULL );
if (status != STATUS_SUCCESS) if (status != STATUS_SUCCESS)
{ {
SetLastError( RtlNtStatusToDosError(status) ); SetLastError( RtlNtStatusToDosError(status) );
......
...@@ -126,6 +126,8 @@ extern void msvcrt_free_console(void); ...@@ -126,6 +126,8 @@ extern void msvcrt_free_console(void);
extern void msvcrt_init_args(void); extern void msvcrt_init_args(void);
extern void msvcrt_free_args(void); extern void msvcrt_free_args(void);
extern unsigned msvcrt_create_io_inherit_block(STARTUPINFOA*);
/* run-time error codes */ /* run-time error codes */
#define _RT_STACK 0 #define _RT_STACK 0
#define _RT_NULLPTR 1 #define _RT_NULLPTR 1
......
...@@ -49,19 +49,19 @@ static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env) ...@@ -49,19 +49,19 @@ static int msvcrt_spawn(int flags, const char* exe, char* cmdline, char* env)
return -1; return -1;
} }
FIXME(":must dup/kill streams for child process\n");
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
si.cb = sizeof(si); si.cb = sizeof(si);
msvcrt_create_io_inherit_block(&si);
if (!CreateProcessA(exe, cmdline, NULL, NULL, TRUE, if (!CreateProcessA(exe, cmdline, NULL, NULL, TRUE,
flags == MSVCRT__P_DETACH ? DETACHED_PROCESS : 0, flags == MSVCRT__P_DETACH ? DETACHED_PROCESS : 0,
env, NULL, &si, &pi)) env, NULL, &si, &pi))
{ {
msvcrt_set_errno(GetLastError()); msvcrt_set_errno(GetLastError());
MSVCRT_free(&si.lpReserved2);
return -1; return -1;
} }
MSVCRT_free(&si.lpReserved2);
switch(flags) switch(flags)
{ {
case MSVCRT__P_WAIT: case MSVCRT__P_WAIT:
......
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
#include <windef.h> #include <windef.h>
#include <winbase.h> #include <winbase.h>
#include <winnls.h> #include <winnls.h>
#include <process.h>
#include <errno.h>
static void test_fdopen( void ) static void test_fdopen( void )
{ {
...@@ -233,6 +235,58 @@ static void test_file_write_read( void ) ...@@ -233,6 +235,58 @@ static void test_file_write_read( void )
ok(unlink(tempf) !=-1 ,"Can't unlink '%s': %d\n", tempf, errno); ok(unlink(tempf) !=-1 ,"Can't unlink '%s': %d\n", tempf, errno);
} }
static void test_file_inherit_child(const char* fd_s)
{
int fd = atoi(fd_s);
char buffer[32];
ok(write(fd, "Success", 8) == 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");
ok(memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
}
static void test_file_inherit_child_no(const char* fd_s)
{
int fd = atoi(fd_s);
ok(write(fd, "Success", 8) == -1 && errno == EBADF,
"Wrong write result in child process on %d (%s)\n", fd, strerror(errno));
}
static void test_file_inherit( const char* selfname )
{
int fd;
const char* arg_v[5];
char buffer[16];
fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY, _S_IREAD |_S_IWRITE);
ok(fd != -1, "Couldn't create test file\n ");
arg_v[0] = selfname;
arg_v[1] = "tests/file.c";
arg_v[2] = buffer; sprintf(buffer, "%d", fd);
arg_v[3] = 0;
_spawnvp(_P_WAIT, selfname, arg_v);
ok(tell(fd) == 8, "bad position %lu expecting 8\n", tell(fd));
lseek(fd, 0, SEEK_SET);
ok(read(fd, buffer, sizeof (buffer)) == 8 && memcmp(buffer, "Success", 8) == 0, "Couldn't read back the data\n");
close (fd);
ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
fd = open ("fdopen.tst", O_CREAT | O_RDWR | O_BINARY | O_NOINHERIT, _S_IREAD |_S_IWRITE);
ok(fd != -1, "Couldn't create test file\n ");
arg_v[0] = selfname;
arg_v[1] = "tests/file.c";
arg_v[2] = buffer; sprintf(buffer, "%d", fd);
arg_v[3] = buffer;
arg_v[4] = 0;
_spawnvp(_P_WAIT, selfname, arg_v);
ok(tell(fd) == 0, "bad position %lu expecting 0\n", tell(fd));
ok(read(fd, buffer, sizeof (buffer)) == 0, "Found unexpected data (%s)\n", buffer);
close (fd);
ok(unlink("fdopen.tst") != 1, "Couldn't unlink\n");
}
static void test_tmpnam( void ) static void test_tmpnam( void )
{ {
char name[MAX_PATH] = "abc"; char name[MAX_PATH] = "abc";
...@@ -249,17 +303,29 @@ static void test_tmpnam( void ) ...@@ -249,17 +303,29 @@ static void test_tmpnam( void )
ok(res == name, "supplied buffer was not used\n"); ok(res == name, "supplied buffer was not used\n");
ok(res[0] == '\\', "first character is not a backslash\n"); ok(res[0] == '\\', "first character is not a backslash\n");
ok(strchr(res+1, '\\') == 0, "file not in the root directory\n"); ok(strchr(res+1, '\\') == 0, "file not in the root directory\n");
ok(res[strlen(res)-1] != '.', "second call - last character is not a dot\n"); ok(res[strlen(res)-1] != '.', "second call - last character is a dot\n");
} }
START_TEST(file) START_TEST(file)
{ {
int arg_c;
char** arg_v;
arg_c = winetest_get_mainargs( &arg_v );
if (arg_c >= 3)
{
if (arg_c == 3) test_file_inherit_child(arg_v[2]); else test_file_inherit_child_no(arg_v[2]);
return;
}
test_fdopen(); test_fdopen();
test_fileops(); test_fileops();
test_fgetwc(); test_fgetwc();
test_file_put_get(); test_file_put_get();
test_file_write_read(); test_file_write_read();
test_file_inherit(arg_v[0]);
test_tmpnam(); test_tmpnam();
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment