kern_fork.c (17660) | kern_fork.c (17768) |
---|---|
1/* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 | 1/* 2 * Copyright (c) 1982, 1986, 1989, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 |
39 * $Id: kern_fork.c,v 1.23 1996/07/31 09:26:34 davidg Exp $ | 39 * $Id: kern_fork.c,v 1.24 1996/08/19 02:28:24 julian Exp $ |
40 */ 41 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/sysproto.h> 47#include <sys/filedesc.h> --- 12 unchanged lines hidden (view full) --- 60#include <vm/pmap.h> 61#include <vm/vm_map.h> 62#include <vm/vm_extern.h> 63#include <vm/vm_inherit.h> 64 65static int fork1 __P((struct proc *p, int flags, int *retval)); 66 67/* | 40 */ 41 42#include "opt_ktrace.h" 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/sysproto.h> 47#include <sys/filedesc.h> --- 12 unchanged lines hidden (view full) --- 60#include <vm/pmap.h> 61#include <vm/vm_map.h> 62#include <vm/vm_extern.h> 63#include <vm/vm_inherit.h> 64 65static int fork1 __P((struct proc *p, int flags, int *retval)); 66 67/* |
68 * callout list for things to do at fork time | 68 * These are the stuctures used to create a callout list for things to do 69 * when forking a process |
69 */ 70typedef struct fork_list_element { 71 struct fork_list_element *next; 72 forklist_fn function; 73} *fle_p; 74 | 70 */ 71typedef struct fork_list_element { 72 struct fork_list_element *next; 73 forklist_fn function; 74} *fle_p; 75 |
75static fle_p fork_list; | 76static fle_p fork_list; |
76 77#ifndef _SYS_SYSPROTO_H_ 78struct fork_args { | 77 78#ifndef _SYS_SYSPROTO_H_ 79struct fork_args { |
79 int dummy; | 80 int dummy; |
80}; 81#endif 82 83/* ARGSUSED */ 84int 85fork(p, uap, retval) 86 struct proc *p; 87 struct fork_args *uap; --- 31 unchanged lines hidden (view full) --- 119 int flags; 120 int retval[]; 121{ 122 register struct proc *p2, *pptr; 123 register uid_t uid; 124 struct proc *newproc; 125 int count; 126 static int nextpid, pidchecked = 0; | 81}; 82#endif 83 84/* ARGSUSED */ 85int 86fork(p, uap, retval) 87 struct proc *p; 88 struct fork_args *uap; --- 31 unchanged lines hidden (view full) --- 120 int flags; 121 int retval[]; 122{ 123 register struct proc *p2, *pptr; 124 register uid_t uid; 125 struct proc *newproc; 126 int count; 127 static int nextpid, pidchecked = 0; |
127 fle_p ep = fork_list; | 128 fle_p ep ; |
128 | 129 |
130 ep = fork_list; |
|
129 if ((flags & RFPROC) == 0) 130 return (EINVAL); 131 if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) 132 return (EINVAL); 133 134 /* 135 * Although process entries are dynamically created, we still keep 136 * a global limit on the maximum number we will create. Don't allow --- 204 unchanged lines hidden (view full) --- 341 */ 342 microtime(&runtime); 343 p2->p_stats->p_start = runtime; 344 p2->p_acflag = AFORK; 345 return (0); 346 } 347 348 /* | 131 if ((flags & RFPROC) == 0) 132 return (EINVAL); 133 if ((flags & (RFFDG|RFCFDG)) == (RFFDG|RFCFDG)) 134 return (EINVAL); 135 136 /* 137 * Although process entries are dynamically created, we still keep 138 * a global limit on the maximum number we will create. Don't allow --- 204 unchanged lines hidden (view full) --- 343 */ 344 microtime(&runtime); 345 p2->p_stats->p_start = runtime; 346 p2->p_acflag = AFORK; 347 return (0); 348 } 349 350 /* |
349 * Both processes are set up, 350 * check if any LKMs want to adjust anything 351 * What if they have an error? XXX | 351 * Both processes are set up, now check if any LKMs want 352 * to adjust anything. 353 * What if they have an error? XXX |
352 */ | 354 */ |
353 while(ep) { 354 (*ep->function)(p1,p2,flags); 355 ep = ep->next; 356 } | 355 while (ep) { 356 (*ep->function)(p1, p2, flags); 357 ep = ep->next; 358 } |
357 358 /* 359 * Make child runnable and add to run queue. 360 */ 361 (void) splhigh(); 362 p2->p_stat = SRUN; 363 setrunqueue(p2); 364 (void) spl0(); --- 15 unchanged lines hidden (view full) --- 380 * Return child pid to parent process, 381 * marking us as parent via retval[1]. 382 */ 383 retval[0] = p2->p_pid; 384 retval[1] = 0; 385 return (0); 386} 387 | 359 360 /* 361 * Make child runnable and add to run queue. 362 */ 363 (void) splhigh(); 364 p2->p_stat = SRUN; 365 setrunqueue(p2); 366 (void) spl0(); --- 15 unchanged lines hidden (view full) --- 382 * Return child pid to parent process, 383 * marking us as parent via retval[1]. 384 */ 385 retval[0] = p2->p_pid; 386 retval[1] = 0; 387 return (0); 388} 389 |
388 389/********************************************************* 390 * general routines to handle adding/deleting items on the 391 * fork callout list 392 ***** 393 * Take the arguments given and put them onto the fork callout list. | 390/* 391 * The next two functionms are general routines to handle adding/deleting 392 * items on the fork callout list. 393 * 394 * at_fork(): 395 * Take the arguments given and put them onto the fork callout list, |
394 * However first make sure that it's not already there. | 396 * However first make sure that it's not already there. |
395 * returns 0 on success. | 397 * Returns 0 on success or a standard error number. |
396 */ 397int 398at_fork(forklist_fn function) 399{ 400 fle_p ep; | 398 */ 399int 400at_fork(forklist_fn function) 401{ 402 fle_p ep; |
401 if(rm_at_fork(function)) { | 403 404 /* let the programmer know if he's been stupid */ 405 if (rm_at_fork(function)) |
402 printf("fork callout entry already present\n"); | 406 printf("fork callout entry already present\n"); |
403 } 404 ep = malloc(sizeof(*ep),M_TEMP,M_NOWAIT); 405 if(!ep) return ENOMEM; | 407 ep = malloc(sizeof(*ep), M_TEMP, M_NOWAIT); 408 if (ep == NULL) 409 return (ENOMEM); |
406 ep->next = fork_list; 407 ep->function = function; 408 fork_list = ep; | 410 ep->next = fork_list; 411 ep->function = function; 412 fork_list = ep; |
409 return 0; | 413 return (0); |
410} | 414} |
415 |
|
411/* 412 * Scan the exit callout list for the given items and remove them. 413 * Returns the number of items removed. | 416/* 417 * Scan the exit callout list for the given items and remove them. 418 * Returns the number of items removed. |
419 * Theoretically this value can only be 0 or 1. |
|
414 */ 415int 416rm_at_fork(forklist_fn function) 417{ | 420 */ 421int 422rm_at_fork(forklist_fn function) 423{ |
418 fle_p *epp,ep; 419 int count = 0; | 424 fle_p *epp, ep; 425 int count; |
420 | 426 |
427 count= 0; |
|
421 epp = &fork_list; 422 ep = *epp; | 428 epp = &fork_list; 429 ep = *epp; |
423 while(ep) { 424 if(ep->function == function) { | 430 while (ep) { 431 if (ep->function == function) { |
425 *epp = ep->next; | 432 *epp = ep->next; |
426 free(ep,M_TEMP); | 433 free(ep, M_TEMP); |
427 count++; 428 } else { 429 epp = &ep->next; 430 } 431 ep = *epp; 432 } | 434 count++; 435 } else { 436 epp = &ep->next; 437 } 438 ep = *epp; 439 } |
433 return count; | 440 return (count); |
434} 435 436 | 441} 442 443 |