add callout lists for exit() and fork()
I've been meaning to do this for AGES as I keep having to patch those routines whenever I write a proprietary package or similar.. any module that assigns resources to processes needs to know when these events occur. there are existsing modules that should be modified to take advantage of these.. e.g. SYSV IPC primatives presently have #ifdef entries in exit() this also helps with making LKMs out of such things.. (see the man pages at_exit(9) and at_fork(9))
This commit is contained in:
parent
3fcaebbf79
commit
fed06968ba
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_exit.c 8.7 (Berkeley) 2/12/94
|
||||
* $Id: kern_exit.c,v 1.34 1996/07/27 03:23:42 dyson Exp $
|
||||
* $Id: kern_exit.c,v 1.35 1996/07/30 03:08:37 dyson Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
@ -80,6 +80,16 @@
|
||||
|
||||
static int wait1 __P((struct proc *, struct wait_args *, int [], int));
|
||||
|
||||
/*
|
||||
* callout list for things to do at exit time
|
||||
*/
|
||||
typedef struct exit_list_element {
|
||||
struct exit_list_element *next;
|
||||
exitlist_fn function;
|
||||
} *ele_p;
|
||||
|
||||
static ele_p exit_list;
|
||||
|
||||
/*
|
||||
* exit --
|
||||
* Death of process.
|
||||
@ -109,6 +119,7 @@ exit1(p, rv)
|
||||
{
|
||||
register struct proc *q, *nq;
|
||||
register struct vmspace *vm;
|
||||
ele_p ep = exit_list;
|
||||
|
||||
if (p->p_pid == 1) {
|
||||
printf("init died (signal %d, exit %d)\n",
|
||||
@ -118,6 +129,16 @@ exit1(p, rv)
|
||||
#ifdef PGINPROF
|
||||
vmsizmon();
|
||||
#endif
|
||||
/*
|
||||
* Check if any LKMs need anything done at process exit
|
||||
* e.g. SYSV IPC stuff
|
||||
* XXX what if one of these generates an error?
|
||||
*/
|
||||
while(ep) {
|
||||
(*ep->function)(p);
|
||||
ep = ep->next;
|
||||
}
|
||||
|
||||
if (p->p_flag & P_PROFIL)
|
||||
stopprofclock(p);
|
||||
MALLOC(p->p_ru, struct rusage *, sizeof(struct rusage),
|
||||
@ -473,3 +494,52 @@ proc_reparent(child, parent)
|
||||
LIST_INSERT_HEAD(&parent->p_children, child, p_sibling);
|
||||
child->p_pptr = parent;
|
||||
}
|
||||
|
||||
/*********************************************************
|
||||
* general routines to handle adding/deleting items on the
|
||||
* exit callout list
|
||||
*****
|
||||
* Take the arguments given and put them onto the exit callout list.
|
||||
* However first make sure that it's not already there.
|
||||
* returns 0 on success.
|
||||
*/
|
||||
int
|
||||
at_exit(exitlist_fn function)
|
||||
{
|
||||
ele_p ep;
|
||||
if(rm_at_exit(function)) {
|
||||
printf("exit callout entry already present\n");
|
||||
}
|
||||
ep = malloc(sizeof(*ep),M_TEMP,M_NOWAIT);
|
||||
if(!ep) return ENOMEM;
|
||||
ep->next = exit_list;
|
||||
ep->function = function;
|
||||
exit_list = ep;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Scan the exit callout list for the given items and remove them.
|
||||
* Returns the number of items removed.
|
||||
*/
|
||||
int
|
||||
rm_at_exit(exitlist_fn function)
|
||||
{
|
||||
ele_p *epp,ep;
|
||||
int count = 0;
|
||||
|
||||
epp = &exit_list;
|
||||
ep = *epp;
|
||||
while(ep) {
|
||||
if(ep->function == function) {
|
||||
*epp = ep->next;
|
||||
free(ep,M_TEMP);
|
||||
count++;
|
||||
} else {
|
||||
epp = &ep->next;
|
||||
}
|
||||
ep = *epp;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_fork.c 8.6 (Berkeley) 4/8/94
|
||||
* $Id: kern_fork.c,v 1.22 1996/06/12 05:07:30 gpalmer Exp $
|
||||
* $Id: kern_fork.c,v 1.23 1996/07/31 09:26:34 davidg Exp $
|
||||
*/
|
||||
|
||||
#include "opt_ktrace.h"
|
||||
@ -64,6 +64,16 @@
|
||||
|
||||
static int fork1 __P((struct proc *p, int flags, int *retval));
|
||||
|
||||
/*
|
||||
* callout list for things to do at fork time
|
||||
*/
|
||||
typedef struct fork_list_element {
|
||||
struct fork_list_element *next;
|
||||
forklist_fn function;
|
||||
} *fle_p;
|
||||
|
||||
static fle_p fork_list;
|
||||
|
||||
#ifndef _SYS_SYSPROTO_H_
|
||||
struct fork_args {
|
||||
int dummy;
|
||||
@ -114,6 +124,7 @@ fork1(p1, flags, retval)
|
||||
struct proc *newproc;
|
||||
int count;
|
||||
static int nextpid, pidchecked = 0;
|
||||
fle_p ep = fork_list;
|
||||
|
||||
if ((flags & RFPROC) == 0)
|
||||
return (EINVAL);
|
||||
@ -334,6 +345,16 @@ fork1(p1, flags, retval)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Both processes are set up,
|
||||
* check if any LKMs want to adjust anything
|
||||
* What if they have an error? XXX
|
||||
*/
|
||||
while(ep) {
|
||||
(*ep->function)(p1,p2,flags);
|
||||
ep = ep->next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make child runnable and add to run queue.
|
||||
*/
|
||||
@ -363,3 +384,53 @@ fork1(p1, flags, retval)
|
||||
retval[1] = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*********************************************************
|
||||
* general routines to handle adding/deleting items on the
|
||||
* fork callout list
|
||||
*****
|
||||
* Take the arguments given and put them onto the fork callout list.
|
||||
* However first make sure that it's not already there.
|
||||
* returns 0 on success.
|
||||
*/
|
||||
int
|
||||
at_fork(forklist_fn function)
|
||||
{
|
||||
fle_p ep;
|
||||
if(rm_at_fork(function)) {
|
||||
printf("fork callout entry already present\n");
|
||||
}
|
||||
ep = malloc(sizeof(*ep),M_TEMP,M_NOWAIT);
|
||||
if(!ep) return ENOMEM;
|
||||
ep->next = fork_list;
|
||||
ep->function = function;
|
||||
fork_list = ep;
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* Scan the exit callout list for the given items and remove them.
|
||||
* Returns the number of items removed.
|
||||
*/
|
||||
int
|
||||
rm_at_fork(forklist_fn function)
|
||||
{
|
||||
fle_p *epp,ep;
|
||||
int count = 0;
|
||||
|
||||
epp = &fork_list;
|
||||
ep = *epp;
|
||||
while(ep) {
|
||||
if(ep->function == function) {
|
||||
*epp = ep->next;
|
||||
free(ep,M_TEMP);
|
||||
count++;
|
||||
} else {
|
||||
epp = &ep->next;
|
||||
}
|
||||
ep = *epp;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user