| #include <parlib/event.h> | 
 | #include <parlib/parlib.h> | 
 | #include <parlib/uthread.h> | 
 |  | 
 | #include <assert.h> | 
 | #include <stdio.h> | 
 | #include <stdlib.h> | 
 | #include <sys/types.h> | 
 | #include <sys/wait.h> | 
 |  | 
 | static void ev_handler(struct event_msg *msg, unsigned int ev_type, void *data) | 
 | { | 
 | 	int rv; | 
 |  | 
 | 	assert(msg != NULL); | 
 | 	assert(ev_type == EV_USER_IPI); | 
 | 	(void)data; | 
 | 	rv = msg->ev_arg1; | 
 | 	exit(rv); | 
 | } | 
 |  | 
 | int main(int argc, char *argv[], char *envp[]) | 
 | { | 
 | 	struct event_queue *evq, *triggered; | 
 | 	pid_t pid; | 
 | 	struct event_msg msg; | 
 | 	int wstatus; | 
 |  | 
 | 	register_ev_handler(EV_USER_IPI, ev_handler, 0); | 
 | 	evq = get_eventq(EV_MBOX_UCQ); | 
 | 	evq->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR | | 
 | 		        EVENT_WAKEUP; | 
 | 	register_kevent_q(evq, EV_USER_IPI); | 
 |  | 
 | 	pid = create_child_with_stdfds(argv[1], argc - 1, argv + 1, envp); | 
 | 	if (pid < 0) { | 
 | 		perror("child creation failed"); | 
 | 		exit(-1); | 
 | 	} | 
 | 	sys_proc_run(pid); | 
 |  | 
 | 	waitpid(pid, &wstatus, 0); | 
 | 	if (!WIFEXITED(wstatus)) { | 
 | 		fprintf(stderr, "child %s did not exit normally!\n", argv[1]); | 
 | 		return -1; | 
 | 	} | 
 | 	return WEXITSTATUS(wstatus); | 
 | } |