|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/usr/server/proc/proc_exit.c/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.1 /* 2 * Copyright (c) 2005-2008, Kohsuke Ohtani 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the author nor the names of any co-contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30 /* 31 * exit.c - process exit and wait 32 */ 33 34 #include <sys/prex.h> 35 #include <ipc/proc.h> 36 #include <sys/list.h> 37 38 #include <unistd.h> 39 #include <errno.h> 40 #include <signal.h> 41 42 #include "proc.h" 43 44 /* 45 * Exit process. 46 * 47 * process_exit() sets the process state to zombie state, and it 48 * saves the exit code for waiting process. 49 */ 50 int 51 sys_exit(int exitcode) 52 { 53 struct proc *child, *parent; 54 list_t head, n; 55 int error; 56 57 DPRINTF(("proc: exit pid=%d code=%x\n", curproc->p_pid, exitcode)); 58 59 if (curproc->p_stat == SZOMB) 60 return EBUSY; 61 62 /* 63 * Enter zombie state. 64 */ 65 curproc->p_stat = SZOMB; 66 curproc->p_exitcode = exitcode; 67 p_remove(curproc); 68 69 /* 70 * Set the parent pid of all child processes to 1 (init). 71 */ 72 head = &curproc->p_children; 73 n = list_first(head); 74 while (n != head) { 75 child = list_entry(n, struct proc, p_sibling); 76 n = list_next(n); 77 78 child->p_parent = &initproc; 79 list_remove(&child->p_sibling); 80 list_insert(&initproc.p_children, &child->p_sibling); 81 } 82 83 /* 84 * Resume parent process which is wating in vfork. 85 */ 86 parent = curproc->p_parent; 87 if (parent != NULL && parent->p_vforked) { 88 vfork_end(parent); 89 90 /* 91 * The child task loses its stack data. 92 * So, it can not run anymore. 93 */ 94 error = task_terminate(curproc->p_task); 95 if (error) 96 sys_panic("proc: can not terminate a task for exit"); 97 } 98 99 /* Send a signal to the parent process. */ 100 DPRINTF(("proc: exit send SIGCHLD to pid=%d\n", 101 curproc->p_parent->p_pid)); 102 exception_raise(curproc->p_parent->p_task, SIGCHLD); 103 104 return 0; 105 } 106 107 /* 108 * Stop process. 109 * 110 * This is similar with exit(), but it does not update the parent 111 * pid of any child processes. 112 */ 113 int 114 stop(int exitcode) 115 { 116 117 DPRINTF(("proc: stop code=%x\n", exitcode)); 118 119 if (curproc->p_stat == SZOMB) 120 return EBUSY; 121 122 curproc->p_stat = SSTOP; 123 curproc->p_exitcode = exitcode; 124 125 /* Send a signal to the parent process. */ 126 exception_raise(curproc->p_parent->p_task, SIGCHLD); 127 128 return 0; 129 } 130 131 /* 132 * Find the zombie process in the child processes. It just 133 * returns the pid and exit code if it find at least one zombie 134 * process. 135 * 136 * The library stub for waitpid() will wait the SIGCHLD signal in 137 * the stub code if there is no zombie process in child process. 138 * This signal is sent by proc_exit() or proc_stop() routines in 139 * the process server. 140 */ 141 int 142 sys_waitpid(pid_t pid, int *status, int options, pid_t *retval) 143 { 144 pid_t pid_child; 145 int code, match; 146 struct proc *p; 147 list_t head, n; 148 149 DPRINTF(("proc: wait pid=%d options=%x\n", pid, options)); 150 151 if (list_empty(&curproc->p_children)) 152 return ECHILD; /* No child process */ 153 154 /* Set the default pid and exit code */ 155 pid_child = 0; 156 code = 0; 157 158 /* 159 * Check all processes. 160 */ 161 p = NULL; 162 head = &curproc->p_children; 163 for (n = list_first(head); n != head; n = list_next(n)) { 164 p = list_entry(n, struct proc, p_sibling); 165 166 /* 167 * Check if pid matches. 168 */ 169 match = 0; 170 if (pid > 0) { 171 /* 172 * Wait a specific child process. 173 */ 174 if (p->p_pid == pid) 175 match = 1; 176 } else if (pid == 0) { 177 /* 178 * Wait a process who has same pgid. 179 */ 180 if (p->p_pgrp->pg_pgid == curproc->p_pgrp->pg_pgid) 181 match = 1; 182 } else if (pid != -1) { 183 /* 184 * Wait a specific pgid. 185 */ 186 if (p->p_pgrp->pg_pgid == -pid) 187 match = 1; 188 } else { 189 /* 190 * pid = -1 means wait any child process. 191 */ 192 match = 1; 193 } 194 if (match) { 195 /* 196 * Get the exit code. 197 */ 198 if (p->p_stat == SSTOP) { 199 pid_child = p->p_pid; 200 code = p->p_exitcode; 201 break; 202 } else if (p->p_stat == SZOMB) { 203 pid_child = p->p_pid; 204 code = p->p_exitcode; 205 cleanup(p); 206 break; 207 } 208 } 209 } 210 *status = code; 211 *retval = pid_child; 212 return 0; 213 } /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |