2 * Server-side process management
4 * Copyright (C) 1998 Alexandre Julliard
26 /* process structure */
28 static struct process
*first_process
;
29 static int running_processes
;
31 /* process operations */
33 static void process_dump( struct object
*obj
, int verbose
);
34 static int process_signaled( struct object
*obj
, struct thread
*thread
);
35 static void process_destroy( struct object
*obj
);
37 static const struct object_ops process_ops
=
39 sizeof(struct process
), /* size */
40 process_dump
, /* dump */
41 add_queue
, /* add_queue */
42 remove_queue
, /* remove_queue */
43 process_signaled
, /* signaled */
44 no_satisfied
, /* satisfied */
45 NULL
, /* get_poll_events */
46 NULL
, /* poll_event */
47 no_read_fd
, /* get_read_fd */
48 no_write_fd
, /* get_write_fd */
50 no_get_file_info
, /* get_file_info */
51 process_destroy
/* destroy */
55 /* create a new process */
56 static struct process
*create_process( struct process
*parent
, struct new_process_request
*req
,
57 const char *cmd_line
, size_t len
)
59 struct process
*process
;
61 if (!(process
= alloc_object( &process_ops
, -1 ))) return NULL
;
64 process
->thread_list
= NULL
;
65 process
->debugger
= NULL
;
66 process
->handles
= NULL
;
67 process
->exit_code
= 0x103; /* STILL_ACTIVE */
68 process
->running_threads
= 0;
69 process
->priority
= NORMAL_PRIORITY_CLASS
;
70 process
->affinity
= 1;
72 process
->create_flags
= 0;
73 process
->console_in
= NULL
;
74 process
->console_out
= NULL
;
75 process
->init_event
= NULL
;
77 gettimeofday( &process
->start_time
, NULL
);
79 /* copy the request structure */
80 if (!(process
->info
= mem_alloc( sizeof(*process
->info
) + len
))) goto error
;
81 memcpy( process
->info
, req
, sizeof(*req
) );
82 memcpy( process
->info
->cmdline
, cmd_line
, len
);
83 process
->info
->cmdline
[len
] = 0;
84 req
= process
->info
; /* use the copy now */
85 process
->create_flags
= req
->create_flags
;
88 process
->handles
= copy_handle_table( process
, parent
);
90 process
->handles
= alloc_handle_table( process
, 0 );
91 if (!process
->handles
) goto error
;
93 /* alloc a handle for the process itself */
94 alloc_handle( process
, process
, PROCESS_ALL_ACCESS
, 0 );
96 /* get the init done event */
99 if (!(process
->init_event
= get_event_obj( parent
, req
->event
, EVENT_MODIFY_STATE
)))
103 /* set the process console */
104 if (process
->create_flags
& CREATE_NEW_CONSOLE
)
106 if (!alloc_console( process
)) goto error
;
108 else if (!(process
->create_flags
& DETACHED_PROCESS
))
110 if (parent
->console_in
) process
->console_in
= grab_object( parent
->console_in
);
111 if (parent
->console_out
) process
->console_out
= grab_object( parent
->console_out
);
114 if (!req
->inherit_all
&& !(req
->start_flags
& STARTF_USESTDHANDLES
))
116 process
->info
->hstdin
= duplicate_handle( parent
, req
->hstdin
, process
,
117 0, TRUE
, DUPLICATE_SAME_ACCESS
);
118 process
->info
->hstdout
= duplicate_handle( parent
, req
->hstdout
, process
,
119 0, TRUE
, DUPLICATE_SAME_ACCESS
);
120 process
->info
->hstderr
= duplicate_handle( parent
, req
->hstderr
, process
,
121 0, TRUE
, DUPLICATE_SAME_ACCESS
);
124 /* attach to the debugger if requested */
125 if (process
->create_flags
& (DEBUG_PROCESS
| DEBUG_ONLY_THIS_PROCESS
))
126 debugger_attach( process
, current
);
127 else if (parent
&& parent
->debugger
&& !(parent
->create_flags
& DEBUG_ONLY_THIS_PROCESS
))
128 debugger_attach( process
, parent
->debugger
);
130 if ((process
->next
= first_process
) != NULL
) process
->next
->prev
= process
;
131 first_process
= process
;
135 free_console( process
);
136 if (process
->handles
) release_object( process
->handles
);
137 release_object( process
);
141 /* create the initial process */
142 struct process
*create_initial_process(void)
144 struct process
*process
;
145 struct new_process_request req
;
149 req
.create_flags
= CREATE_NEW_CONSOLE
;
150 req
.start_flags
= STARTF_USESTDHANDLES
;
157 if ((process
= create_process( NULL
, &req
, "", 1 )))
159 process
->info
->hstdin
= alloc_handle( process
, process
->console_in
,
160 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, 1 );
161 process
->info
->hstdout
= alloc_handle( process
, process
->console_out
,
162 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, 1 );
163 process
->info
->hstderr
= alloc_handle( process
, process
->console_out
,
164 GENERIC_READ
| GENERIC_WRITE
| SYNCHRONIZE
, 1 );
169 /* destroy a process when its refcount is 0 */
170 static void process_destroy( struct object
*obj
)
172 struct process
*process
= (struct process
*)obj
;
173 assert( obj
->ops
== &process_ops
);
175 /* we can't have a thread remaining */
176 assert( !process
->thread_list
);
177 if (process
->next
) process
->next
->prev
= process
->prev
;
178 if (process
->prev
) process
->prev
->next
= process
->next
;
179 else first_process
= process
->next
;
180 if (process
->info
) free( process
->info
);
181 if (process
->init_event
) release_object( process
->init_event
);
184 /* dump a process on stdout for debugging purposes */
185 static void process_dump( struct object
*obj
, int verbose
)
187 struct process
*process
= (struct process
*)obj
;
188 assert( obj
->ops
== &process_ops
);
190 fprintf( stderr
, "Process next=%p prev=%p console=%p/%p handles=%p\n",
191 process
->next
, process
->prev
, process
->console_in
, process
->console_out
,
195 static int process_signaled( struct object
*obj
, struct thread
*thread
)
197 struct process
*process
= (struct process
*)obj
;
198 return !process
->running_threads
;
202 /* get a process from an id (and increment the refcount) */
203 struct process
*get_process_from_id( void *id
)
205 struct process
*p
= first_process
;
206 while (p
&& (p
!= id
)) p
= p
->next
;
207 if (p
) grab_object( p
);
208 else set_error( ERROR_INVALID_PARAMETER
);
212 /* get a process from a handle (and increment the refcount) */
213 struct process
*get_process_from_handle( int handle
, unsigned int access
)
215 return (struct process
*)get_handle_obj( current
->process
, handle
,
216 access
, &process_ops
);
219 /* a process has been killed (i.e. its last thread died) */
220 static void process_killed( struct process
*process
, int exit_code
)
222 assert( !process
->thread_list
);
223 process
->exit_code
= exit_code
;
224 gettimeofday( &process
->end_time
, NULL
);
225 release_object( process
->handles
);
226 process
->handles
= NULL
;
227 free_console( process
);
228 wake_up( &process
->obj
, 0 );
229 if (!--running_processes
)
231 /* last process died, close global handles */
232 close_global_handles();
236 /* add a thread to a process running threads list */
237 void add_process_thread( struct process
*process
, struct thread
*thread
)
239 thread
->proc_next
= process
->thread_list
;
240 thread
->proc_prev
= NULL
;
241 if (thread
->proc_next
) thread
->proc_next
->proc_prev
= thread
;
242 process
->thread_list
= thread
;
243 if (!process
->running_threads
++) running_processes
++;
244 grab_object( thread
);
247 /* remove a thread from a process running threads list */
248 void remove_process_thread( struct process
*process
, struct thread
*thread
)
250 assert( process
->running_threads
> 0 );
251 assert( process
->thread_list
);
253 if (thread
->proc_next
) thread
->proc_next
->proc_prev
= thread
->proc_prev
;
254 if (thread
->proc_prev
) thread
->proc_prev
->proc_next
= thread
->proc_next
;
255 else process
->thread_list
= thread
->proc_next
;
257 if (!--process
->running_threads
)
259 /* we have removed the last running thread, exit the process */
260 process_killed( process
, thread
->exit_code
);
262 release_object( thread
);
265 /* suspend all the threads of a process */
266 void suspend_process( struct process
*process
)
268 if (!process
->suspend
++)
270 struct thread
*thread
= process
->thread_list
;
271 for (; thread
; thread
= thread
->proc_next
)
273 if (!thread
->suspend
) stop_thread( thread
);
278 /* resume all the threads of a process */
279 void resume_process( struct process
*process
)
281 assert (process
->suspend
> 0);
282 if (!--process
->suspend
)
284 struct thread
*thread
= process
->thread_list
;
285 for (; thread
; thread
= thread
->proc_next
)
287 if (!thread
->suspend
) continue_thread( thread
);
292 /* kill a process on the spot */
293 void kill_process( struct process
*process
, int exit_code
)
295 while (process
->thread_list
)
296 kill_thread( process
->thread_list
, exit_code
);
299 /* kill all processes being debugged by a given thread */
300 void kill_debugged_processes( struct thread
*debugger
, int exit_code
)
302 for (;;) /* restart from the beginning of the list every time */
304 struct process
*process
= first_process
;
305 /* find the first process being debugged by 'debugger' and still running */
306 while (process
&& (process
->debugger
!= debugger
|| !process
->running_threads
))
307 process
= process
->next
;
308 if (!process
) return;
309 process
->debugger
= NULL
;
310 kill_process( process
, exit_code
);
314 /* get all information about a process */
315 static void get_process_info( struct process
*process
, struct get_process_info_request
*req
)
318 req
->exit_code
= process
->exit_code
;
319 req
->priority
= process
->priority
;
320 req
->process_affinity
= process
->affinity
;
321 req
->system_affinity
= 1;
324 /* set all information about a process */
325 static void set_process_info( struct process
*process
,
326 struct set_process_info_request
*req
)
328 if (req
->mask
& SET_PROCESS_INFO_PRIORITY
)
329 process
->priority
= req
->priority
;
330 if (req
->mask
& SET_PROCESS_INFO_AFFINITY
)
332 if (req
->affinity
!= 1) set_error( ERROR_INVALID_PARAMETER
);
333 else process
->affinity
= req
->affinity
;
337 /* read data from a process memory space */
338 /* len is the total size (in ints), max is the size we can actually store in the output buffer */
339 /* we read the total size in all cases to check for permissions */
340 static void read_process_memory( struct process
*process
, const int *addr
,
341 size_t len
, size_t max
, int *dest
)
343 struct thread
*thread
= process
->thread_list
;
345 if ((unsigned int)addr
% sizeof(int)) /* address must be aligned */
347 set_error( ERROR_INVALID_PARAMETER
);
350 suspend_thread( thread
, 0 );
351 if (thread
->attached
)
353 while (len
> 0 && max
)
355 if (read_thread_int( thread
, addr
++, dest
++ ) == -1) goto done
;
359 /* check the rest for read permission */
362 int dummy
, page
= get_page_size() / sizeof(int);
367 if (read_thread_int( thread
, addr
- 1, &dummy
) == -1) goto done
;
369 if (len
&& (read_thread_int( thread
, addr
+ len
- 1, &dummy
) == -1)) goto done
;
372 else set_error( ERROR_ACCESS_DENIED
);
374 resume_thread( thread
);
377 /* write data to a process memory space */
378 /* len is the total size (in ints), max is the size we can actually read from the input buffer */
379 /* we check the total size for write permissions */
380 static void write_process_memory( struct process
*process
, int *addr
, size_t len
,
381 size_t max
, unsigned int first_mask
,
382 unsigned int last_mask
, const int *src
)
384 struct thread
*thread
= process
->thread_list
;
386 if (!len
|| ((unsigned int)addr
% sizeof(int))) /* address must be aligned */
388 set_error( ERROR_INVALID_PARAMETER
);
391 suspend_thread( thread
, 0 );
392 if (thread
->attached
)
394 /* first word is special */
397 if (write_thread_int( thread
, addr
++, *src
++, first_mask
) == -1) goto done
;
401 else last_mask
&= first_mask
;
403 while (len
> 1 && max
)
405 if (write_thread_int( thread
, addr
++, *src
++, ~0 ) == -1) goto done
;
412 /* last word is special too */
413 if (write_thread_int( thread
, addr
, *src
, last_mask
) == -1) goto done
;
417 /* check the rest for write permission */
418 int page
= get_page_size() / sizeof(int);
423 if (write_thread_int( thread
, addr
- 1, 0, 0 ) == -1) goto done
;
425 if (len
&& (write_thread_int( thread
, addr
+ len
- 1, 0, 0 ) == -1)) goto done
;
428 else set_error( ERROR_ACCESS_DENIED
);
430 resume_thread( thread
);
433 /* take a snapshot of currently running processes */
434 struct process_snapshot
*process_snap( int *count
)
436 struct process_snapshot
*snapshot
, *ptr
;
437 struct process
*process
;
438 if (!running_processes
) return NULL
;
439 if (!(snapshot
= mem_alloc( sizeof(*snapshot
) * running_processes
)))
442 for (process
= first_process
; process
; process
= process
->next
)
444 if (!process
->running_threads
) continue;
445 ptr
->process
= process
;
446 ptr
->threads
= process
->running_threads
;
447 ptr
->priority
= process
->priority
;
448 grab_object( process
);
451 *count
= running_processes
;
455 /* create a new process */
456 DECL_HANDLER(new_process
)
458 size_t len
= get_req_strlen( req
->cmdline
);
459 struct process
*process
;
463 if ((process
= create_process( current
->process
, req
, req
->cmdline
, len
)))
465 req
->handle
= alloc_handle( current
->process
, process
, PROCESS_ALL_ACCESS
, req
->inherit
);
467 release_object( process
);
471 /* initialize a new process */
472 DECL_HANDLER(init_process
)
474 struct new_process_request
*info
;
476 if (!current
->unix_pid
)
478 fatal_protocol_error( current
, "init_process: init_thread not called yet\n" );
481 if (!(info
= current
->process
->info
))
483 fatal_protocol_error( current
, "init_process: called twice\n" );
486 current
->process
->info
= NULL
;
487 req
->start_flags
= info
->start_flags
;
488 req
->hstdin
= info
->hstdin
;
489 req
->hstdout
= info
->hstdout
;
490 req
->hstderr
= info
->hstderr
;
491 req
->cmd_show
= info
->cmd_show
;
492 req
->env_ptr
= info
->env_ptr
;
493 strcpy( req
->cmdline
, info
->cmdline
);
497 /* signal the end of the process initialization */
498 DECL_HANDLER(init_process_done
)
500 struct process
*process
= current
->process
;
501 if (!process
->init_event
)
503 fatal_protocol_error( current
, "init_process_done: no event\n" );
506 set_event( process
->init_event
);
507 release_object( process
->init_event
);
508 process
->init_event
= NULL
;
509 if (current
->suspend
+ current
->process
->suspend
> 0) stop_thread( current
);
512 /* open a handle to a process */
513 DECL_HANDLER(open_process
)
515 struct process
*process
= get_process_from_id( req
->pid
);
519 req
->handle
= alloc_handle( current
->process
, process
, req
->access
, req
->inherit
);
520 release_object( process
);
524 /* terminate a process */
525 DECL_HANDLER(terminate_process
)
527 struct process
*process
;
529 if ((process
= get_process_from_handle( req
->handle
, PROCESS_TERMINATE
)))
531 kill_process( process
, req
->exit_code
);
532 release_object( process
);
536 /* fetch information about a process */
537 DECL_HANDLER(get_process_info
)
539 struct process
*process
;
541 if ((process
= get_process_from_handle( req
->handle
, PROCESS_QUERY_INFORMATION
)))
543 get_process_info( process
, req
);
544 release_object( process
);
548 /* set information about a process */
549 DECL_HANDLER(set_process_info
)
551 struct process
*process
;
553 if ((process
= get_process_from_handle( req
->handle
, PROCESS_SET_INFORMATION
)))
555 set_process_info( process
, req
);
556 release_object( process
);
560 /* read data from a process address space */
561 DECL_HANDLER(read_process_memory
)
563 struct process
*process
;
565 if ((process
= get_process_from_handle( req
->handle
, PROCESS_VM_READ
)))
567 read_process_memory( process
, req
->addr
, req
->len
,
568 get_req_size( req
->data
, sizeof(int) ), req
->data
);
569 release_object( process
);
573 /* write data to a process address space */
574 DECL_HANDLER(write_process_memory
)
576 struct process
*process
;
578 if ((process
= get_process_from_handle( req
->handle
, PROCESS_VM_WRITE
)))
580 write_process_memory( process
, req
->addr
, req
->len
, get_req_size( req
->data
, sizeof(int) ),
581 req
->first_mask
, req
->last_mask
, req
->data
);
582 release_object( process
);