|
|||
Prex Home / Browse Source - Prex Version: 0.9.0 |
|||
root/usr/server/proc/proc_fork.c/* [<][>][^][v][top][bottom][index][help] */DEFINITIONSThis source file includes following definitions.1 /* 2 * Copyright (c) 2005-2006, 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 * fork.c - fork() support 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 <stdlib.h> 41 #include <string.h> 42 43 #include "proc.h" 44 45 static int vfork_start(struct proc *); 46 47 /* 48 * PID previously allocated. 49 * 50 * Note: The following pids are reserved by default. 51 * pid = 0: Process server 52 * pid = 1: Init process 53 */ 54 static pid_t last_pid = 1; 55 56 /* 57 * Assign new pid. 58 * Returns pid on sucess, or 0 on failure. 59 */ 60 static pid_t 61 pid_alloc(void) 62 { 63 pid_t pid; 64 65 pid = last_pid + 1; 66 if (pid >= PID_MAX) 67 pid = 1; 68 while (pid != last_pid) { 69 if (p_find(pid) == NULL) 70 break; 71 if (++pid >= PID_MAX) 72 pid = 1; 73 } 74 if (pid == last_pid) 75 return 0; 76 last_pid = pid; 77 return pid; 78 } 79 80 /* 81 * Create a new process. 82 */ 83 int 84 newproc(struct proc *p, pid_t pid, task_t task) 85 { 86 struct pgrp *pg; 87 88 pg = curproc->p_pgrp; 89 90 if (pid == 0) { 91 pid = pid_alloc(); 92 if (pid == 0) { 93 /* Too many processes */ 94 return EAGAIN; 95 } 96 } 97 /* 98 * make proc entry for new proc 99 */ 100 p->p_parent = curproc; 101 p->p_pgrp = pg; 102 p->p_stat = SRUN; 103 p->p_exitcode = 0; 104 p->p_pid = pid; 105 p->p_task = task; 106 p->p_vforked = 0; 107 p->p_invfork = 0; 108 109 list_init(&p->p_children); 110 p_add(p); 111 list_insert(&curproc->p_children, &p->p_sibling); 112 list_insert(&pg->pg_members, &p->p_pgrp_link); 113 list_insert(&allproc, &p->p_link); 114 115 return 0; 116 } 117 118 /* 119 * fork() support. 120 * 121 * It creates new process data and update all process relations. 122 * The task creation and the thread creation are done by the 123 * fork() library stub. 124 */ 125 int 126 sys_fork(task_t child, int vfork, pid_t *retval) 127 { 128 struct proc *p; 129 int error; 130 131 DPRINTF(("proc: fork child=%x vfork=%d\n", child, vfork)); 132 133 if (vfork && curproc->p_invfork) { 134 DPRINTF(("proc: vfork under vfork!\n")); 135 return EINVAL; 136 } 137 138 if (task_to_proc(child) != NULL) { 139 DPRINTF(("proc: process already exists\n")); 140 return EINVAL; 141 } 142 143 if ((p = malloc(sizeof(struct proc))) == NULL) 144 return ENOMEM; 145 memset(p, 0, sizeof(*p)); 146 147 error = newproc(p, 0, child); 148 if (error) 149 return error; 150 151 if (vfork) { 152 vfork_start(curproc); 153 p->p_invfork = 1; 154 } 155 156 DPRINTF(("proc: fork newpid=%d\n", p->p_pid)); 157 *retval = p->p_pid; 158 return 0; 159 } 160 161 /* 162 * Clean up all resource created by fork(). 163 */ 164 void 165 cleanup(struct proc *p) 166 { 167 struct proc *pp; 168 169 DPRINTF(("proc: cleanup pid=%d\n", p->p_pid)); 170 pp = p->p_parent; 171 list_remove(&p->p_sibling); 172 list_remove(&p->p_pgrp_link); 173 list_remove(&p->p_link); 174 free(p); 175 } 176 177 static int 178 vfork_start(struct proc *p) 179 { 180 void *stack; 181 182 /* 183 * Save parent's stack 184 */ 185 DPRINTF(("proc: vfork_start stack=%x\n", p->p_stackbase)); 186 187 if (vm_allocate(p->p_task, &stack, DFLSTKSZ, 1) != 0) { 188 DPRINTF(("proc: failed to allocate save stack\n")); 189 return ENOMEM; 190 } 191 192 memcpy(stack, p->p_stackbase, DFLSTKSZ); 193 p->p_stacksaved = stack; 194 195 p->p_vforked = 1; 196 return 0; 197 } 198 199 void 200 vfork_end(struct proc *p) 201 { 202 203 DPRINTF(("proc: vfork_end org=%x saved=%x\n", p->p_stackbase, 204 p->p_stacksaved)); 205 /* 206 * Restore parent's stack 207 */ 208 memcpy(p->p_stackbase, p->p_stacksaved, DFLSTKSZ); 209 vm_free(p->p_task, p->p_stacksaved); 210 211 /* 212 * Resume parent 213 */ 214 p->p_vforked = 0; 215 task_resume(p->p_task); 216 } /* [<][>][^][v][top][bottom][index][help] */ | |||
Copyright© 2005-2009 Kohsuke Ohtani |