Added support for CREATE_SUSPENDED flag in CreateProcess.

oldstable
Alexandre Julliard 1999-11-12 03:35:25 +00:00
parent 796c0f1223
commit ec7bb2391d
8 changed files with 57 additions and 18 deletions

View File

@ -33,6 +33,7 @@ struct new_process_request
IN int hstdin; /* handle for stdin */ IN int hstdin; /* handle for stdin */
IN int hstdout; /* handle for stdout */ IN int hstdout; /* handle for stdout */
IN int hstderr; /* handle for stderr */ IN int hstderr; /* handle for stderr */
IN int event; /* event to signal startup */
IN int cmd_show; /* main window show mode */ IN int cmd_show; /* main window show mode */
IN void* env_ptr; /* pointer to environment (FIXME: hack) */ IN void* env_ptr; /* pointer to environment (FIXME: hack) */
OUT void* pid; /* process id */ OUT void* pid; /* process id */
@ -72,6 +73,13 @@ struct init_process_request
}; };
/* Signal the end of the process initialization */
struct init_process_done_request
{
IN int dummy;
};
/* Initialize a thread; called from the child after fork()/clone() */ /* Initialize a thread; called from the child after fork()/clone() */
struct init_thread_request struct init_thread_request
{ {
@ -808,6 +816,7 @@ enum request
REQ_NEW_THREAD, REQ_NEW_THREAD,
REQ_SET_DEBUG, REQ_SET_DEBUG,
REQ_INIT_PROCESS, REQ_INIT_PROCESS,
REQ_INIT_PROCESS_DONE,
REQ_INIT_THREAD, REQ_INIT_THREAD,
REQ_GET_THREAD_BUFFER, REQ_GET_THREAD_BUFFER,
REQ_TERMINATE_PROCESS, REQ_TERMINATE_PROCESS,

View File

@ -1113,8 +1113,6 @@ BOOL WINAPI CreateProcessA( LPCSTR lpApplicationName, LPSTR lpCommandLine,
/* Warn if unsupported features are used */ /* Warn if unsupported features are used */
if (dwCreationFlags & CREATE_SUSPENDED)
FIXME_(module)("(%s,...): CREATE_SUSPENDED ignored\n", name);
if (dwCreationFlags & DETACHED_PROCESS) if (dwCreationFlags & DETACHED_PROCESS)
FIXME_(module)("(%s,...): DETACHED_PROCESS ignored\n", name); FIXME_(module)("(%s,...): DETACHED_PROCESS ignored\n", name);
if (dwCreationFlags & CREATE_NEW_CONSOLE) if (dwCreationFlags & CREATE_NEW_CONSOLE)

View File

@ -446,9 +446,7 @@ void PROCESS_Start(void)
PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 ); PROCESS_CallUserSignalProc( USIG_PROCESS_INIT, 0 );
/* Signal the parent process to continue */ /* Signal the parent process to continue */
SetEvent( pdb->load_done_evt ); server_call( REQ_INIT_PROCESS_DONE );
CloseHandle( pdb->load_done_evt );
pdb->load_done_evt = INVALID_HANDLE_VALUE;
/* Perform Win32 specific process initialization */ /* Perform Win32 specific process initialization */
if ( type == PROC_WIN32 ) if ( type == PROC_WIN32 )
@ -523,7 +521,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
BOOL inherit, DWORD flags, STARTUPINFOA *startup, BOOL inherit, DWORD flags, STARTUPINFOA *startup,
PROCESS_INFORMATION *info ) PROCESS_INFORMATION *info )
{ {
HANDLE handles[2], load_done_evt = INVALID_HANDLE_VALUE; HANDLE handles[2], load_done_evt = 0;
DWORD exitcode, size; DWORD exitcode, size;
BOOL alloc_stack16; BOOL alloc_stack16;
int server_thandle; int server_thandle;
@ -534,6 +532,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
if (!pdb) return NULL; if (!pdb) return NULL;
info->hThread = info->hProcess = INVALID_HANDLE_VALUE; info->hThread = info->hProcess = INVALID_HANDLE_VALUE;
if (!(load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL ))) goto error;
/* Create the process on the server side */ /* Create the process on the server side */
@ -541,6 +540,7 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
req->inherit_all = inherit; req->inherit_all = inherit;
req->create_flags = flags; req->create_flags = flags;
req->start_flags = startup->dwFlags; req->start_flags = startup->dwFlags;
req->event = load_done_evt;
if (startup->dwFlags & STARTF_USESTDHANDLES) if (startup->dwFlags & STARTF_USESTDHANDLES)
{ {
req->hstdin = startup->hStdInput; req->hstdin = startup->hStdInput;
@ -588,17 +588,12 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
/* Create the main thread */ /* Create the main thread */
if (!(teb = THREAD_Create( pdb, 0L, size, alloc_stack16, tsa, &server_thandle ))) if (!(teb = THREAD_Create( pdb, flags & CREATE_SUSPENDED, size,
goto error; alloc_stack16, tsa, &server_thandle ))) goto error;
info->hThread = server_thandle; info->hThread = server_thandle;
info->dwThreadId = (DWORD)teb->tid; info->dwThreadId = (DWORD)teb->tid;
teb->startup = PROCESS_Start; teb->startup = PROCESS_Start;
/* Create the load-done event */
load_done_evt = CreateEventA( NULL, TRUE, FALSE, NULL );
DuplicateHandle( GetCurrentProcess(), load_done_evt,
info->hProcess, &pdb->load_done_evt, 0, TRUE, DUPLICATE_SAME_ACCESS );
/* Pass module to new process (FIXME: hack) */ /* Pass module to new process (FIXME: hack) */
pdb->module = pModule->self; pdb->module = pModule->self;
SYSDEPS_SpawnThread( teb ); SYSDEPS_SpawnThread( teb );
@ -634,12 +629,12 @@ PDB *PROCESS_Create( NE_MODULE *pModule, LPCSTR cmd_line, LPCSTR env,
} }
CloseHandle( load_done_evt ); CloseHandle( load_done_evt );
load_done_evt = INVALID_HANDLE_VALUE; load_done_evt = 0;
return pdb; return pdb;
error: error:
if (load_done_evt != INVALID_HANDLE_VALUE) CloseHandle( load_done_evt ); if (load_done_evt) CloseHandle( load_done_evt );
if (info->hThread != INVALID_HANDLE_VALUE) CloseHandle( info->hThread ); if (info->hThread != INVALID_HANDLE_VALUE) CloseHandle( info->hThread );
if (info->hProcess != INVALID_HANDLE_VALUE) CloseHandle( info->hProcess ); if (info->hProcess != INVALID_HANDLE_VALUE) CloseHandle( info->hProcess );
PROCESS_FreePDB( pdb ); PROCESS_FreePDB( pdb );

View File

@ -70,6 +70,7 @@ static struct process *create_process( struct process *parent, struct new_proces
process->suspend = 0; process->suspend = 0;
process->console_in = NULL; process->console_in = NULL;
process->console_out = NULL; process->console_out = NULL;
process->init_event = NULL;
process->info = NULL; process->info = NULL;
gettimeofday( &process->start_time, NULL ); gettimeofday( &process->start_time, NULL );
@ -87,6 +88,13 @@ static struct process *create_process( struct process *parent, struct new_proces
memcpy( process->info->cmdline, cmd_line, len ); memcpy( process->info->cmdline, cmd_line, len );
process->info->cmdline[len] = 0; process->info->cmdline[len] = 0;
/* get the init done event */
if (req->event != -1)
{
if (!(process->init_event = get_event_obj( parent, req->event, EVENT_MODIFY_STATE )))
goto error;
}
/* set the process console */ /* set the process console */
if (req->create_flags & CREATE_NEW_CONSOLE) if (req->create_flags & CREATE_NEW_CONSOLE)
{ {
@ -120,7 +128,6 @@ static struct process *create_process( struct process *parent, struct new_proces
error: error:
free_console( process ); free_console( process );
if (process->info) free( process->info );
if (process->handles) release_object( process->handles ); if (process->handles) release_object( process->handles );
release_object( process ); release_object( process );
return NULL; return NULL;
@ -139,6 +146,7 @@ struct process *create_initial_process(void)
req.hstdin = -1; req.hstdin = -1;
req.hstdout = -1; req.hstdout = -1;
req.hstderr = -1; req.hstderr = -1;
req.event = -1;
req.cmd_show = 0; req.cmd_show = 0;
req.env_ptr = NULL; req.env_ptr = NULL;
if ((process = create_process( NULL, &req, "", 1 ))) if ((process = create_process( NULL, &req, "", 1 )))
@ -165,6 +173,7 @@ static void process_destroy( struct object *obj )
if (process->prev) process->prev->next = process->next; if (process->prev) process->prev->next = process->next;
else first_process = process->next; else first_process = process->next;
if (process->info) free( process->info ); if (process->info) free( process->info );
if (process->init_event) release_object( process->init_event );
} }
/* dump a process on stdout for debugging purposes */ /* dump a process on stdout for debugging purposes */
@ -369,6 +378,21 @@ DECL_HANDLER(init_process)
free( info ); free( info );
} }
/* signal the end of the process initialization */
DECL_HANDLER(init_process_done)
{
struct process *process = current->process;
if (!process->init_event)
{
fatal_protocol_error( current, "init_process_done: no event\n" );
return;
}
set_event( process->init_event );
release_object( process->init_event );
process->init_event = NULL;
if (current->suspend + current->process->suspend > 0) stop_thread( current );
}
/* open a handle to a process */ /* open a handle to a process */
DECL_HANDLER(open_process) DECL_HANDLER(open_process)
{ {

View File

@ -34,6 +34,7 @@ struct process
int suspend; /* global process suspend count */ int suspend; /* global process suspend count */
struct object *console_in; /* console input */ struct object *console_in; /* console input */
struct object *console_out; /* console output */ struct object *console_out; /* console output */
struct event *init_event; /* event for init done */
struct new_process_request *info; /* startup info (freed after startup) */ struct new_process_request *info; /* startup info (freed after startup) */
}; };

View File

@ -65,6 +65,7 @@ DECL_HANDLER(new_process);
DECL_HANDLER(new_thread); DECL_HANDLER(new_thread);
DECL_HANDLER(set_debug); DECL_HANDLER(set_debug);
DECL_HANDLER(init_process); DECL_HANDLER(init_process);
DECL_HANDLER(init_process_done);
DECL_HANDLER(init_thread); DECL_HANDLER(init_thread);
DECL_HANDLER(get_thread_buffer); DECL_HANDLER(get_thread_buffer);
DECL_HANDLER(terminate_process); DECL_HANDLER(terminate_process);
@ -142,6 +143,7 @@ static const struct handler {
{ (void(*)())req_new_thread, sizeof(struct new_thread_request) }, { (void(*)())req_new_thread, sizeof(struct new_thread_request) },
{ (void(*)())req_set_debug, sizeof(struct set_debug_request) }, { (void(*)())req_set_debug, sizeof(struct set_debug_request) },
{ (void(*)())req_init_process, sizeof(struct init_process_request) }, { (void(*)())req_init_process, sizeof(struct init_process_request) },
{ (void(*)())req_init_process_done, sizeof(struct init_process_done_request) },
{ (void(*)())req_init_thread, sizeof(struct init_thread_request) }, { (void(*)())req_init_thread, sizeof(struct init_thread_request) },
{ (void(*)())req_get_thread_buffer, sizeof(struct get_thread_buffer_request) }, { (void(*)())req_get_thread_buffer, sizeof(struct get_thread_buffer_request) },
{ (void(*)())req_terminate_process, sizeof(struct terminate_process_request) }, { (void(*)())req_terminate_process, sizeof(struct terminate_process_request) },

View File

@ -318,7 +318,8 @@ static void detach_thread( struct thread *thread )
/* stop a thread (at the Unix level) */ /* stop a thread (at the Unix level) */
void stop_thread( struct thread *thread ) void stop_thread( struct thread *thread )
{ {
if (!thread->unix_pid) return; /* can't stop a thread while initialisation is in progress */
if (!thread->unix_pid || thread->process->init_event) return;
/* first try to attach to it */ /* first try to attach to it */
if (!thread->attached) if (!thread->attached)
if (attach_thread( thread )) return; /* this will have stopped it */ if (attach_thread( thread )) return; /* this will have stopped it */

View File

@ -52,6 +52,7 @@ static void dump_new_process_request( struct new_process_request *req )
fprintf( stderr, " hstdin=%d,", req->hstdin ); fprintf( stderr, " hstdin=%d,", req->hstdin );
fprintf( stderr, " hstdout=%d,", req->hstdout ); fprintf( stderr, " hstdout=%d,", req->hstdout );
fprintf( stderr, " hstderr=%d,", req->hstderr ); fprintf( stderr, " hstderr=%d,", req->hstderr );
fprintf( stderr, " event=%d,", req->event );
fprintf( stderr, " cmd_show=%d,", req->cmd_show ); fprintf( stderr, " cmd_show=%d,", req->cmd_show );
fprintf( stderr, " env_ptr=%p,", req->env_ptr ); fprintf( stderr, " env_ptr=%p,", req->env_ptr );
fprintf( stderr, " cmdline=\"%s\"", req->cmdline ); fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
@ -96,6 +97,11 @@ static void dump_init_process_reply( struct init_process_request *req )
fprintf( stderr, " cmdline=\"%s\"", req->cmdline ); fprintf( stderr, " cmdline=\"%s\"", req->cmdline );
} }
static void dump_init_process_done_request( struct init_process_done_request *req )
{
fprintf( stderr, " dummy=%d", req->dummy );
}
static void dump_init_thread_request( struct init_thread_request *req ) static void dump_init_thread_request( struct init_thread_request *req )
{ {
fprintf( stderr, " unix_pid=%d,", req->unix_pid ); fprintf( stderr, " unix_pid=%d,", req->unix_pid );
@ -762,6 +768,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_thread_request, (dump_func)dump_new_thread_request,
(dump_func)dump_set_debug_request, (dump_func)dump_set_debug_request,
(dump_func)dump_init_process_request, (dump_func)dump_init_process_request,
(dump_func)dump_init_process_done_request,
(dump_func)dump_init_thread_request, (dump_func)dump_init_thread_request,
(dump_func)dump_get_thread_buffer_request, (dump_func)dump_get_thread_buffer_request,
(dump_func)dump_terminate_process_request, (dump_func)dump_terminate_process_request,
@ -835,6 +842,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_new_thread_reply, (dump_func)dump_new_thread_reply,
(dump_func)0, (dump_func)0,
(dump_func)dump_init_process_reply, (dump_func)dump_init_process_reply,
(dump_func)0,
(dump_func)dump_init_thread_reply, (dump_func)dump_init_thread_reply,
(dump_func)0, (dump_func)0,
(dump_func)0, (dump_func)0,
@ -908,6 +916,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"new_thread", "new_thread",
"set_debug", "set_debug",
"init_process", "init_process",
"init_process_done",
"init_thread", "init_thread",
"get_thread_buffer", "get_thread_buffer",
"terminate_process", "terminate_process",