/* ******************************************************************************* * Copyright (c) 1996 Martin Poole ******************************************************************************* ** ** WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! ** ** Any changes to be made to this file should first be checked with ** mplib1 source control for library integrity. ** ** mplib1 source control can be reached at mplib1@quatermass.co.cuk ** * * $Source: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/bpo_proc.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:37 $ * $Revision: 1.2 $ * ******************************************************************************* * * Change History * * $Log: bpo_proc.c,v $ * Revision 1.2 2002/10/07 09:37:37 mpoole * Initial checkin of mplib1-3.1.0 * * Revision 1.1 2002/10/07 09:36:54 mpoole * Initial checkin of mplib1-3.1.0 * * ******************************************************************************* */ #ident "$Header: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/bpo_proc.c,v 1.2 2002/10/07 09:37:37 mpoole Exp $" /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "include/bpo_proc_internal.h" #include /* ------------------------------------------------------------------ defines ------------------------------------------------------------------ */ struct proc_man { struct shm_proc_list *splp; struct shm_process *spp; const char *pid_str; }; static dl_List_t cached_procs; static pid_t my_pid = (pid_t)0; static char proc_debug_str[]="BPO_PROC_DEBUG"; static int bpo_proc_debug=0; static char processes[]="Processes"; /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ static void init_pid_stuff( void ) { pid_t this_pid; this_pid = getpid(); if (my_pid==(pid_t)0) { dl_Init_List( &cached_procs, 0 ); } my_pid = this_pid; return; } struct shm_proc_list * Find_Proc_List( const void *hint ) { struct shm_proc_list *splp; off_t qro,*ofp; init_pid_stuff(); bpo_proc_debug = get_config_flag(proc_debug_str); splp = Find_SODB_Resource( hint, processes ); if (splp==NULL) { ofp = shalloc( hint, sizeof(struct shm_proc_list) + sizeof(off_t) ); if (ofp) { *ofp = (off_t)0; splp = (struct shm_proc_list *)(ofp+1); if (bpo_proc_debug) fprintfile( stderr, "Now to init process resource\n"); /* Init the structure before adding it to the resources */ splp->lno_me = Get_SODB_Offset( splp ); time( &splp->update_tm ); bpo_Init_List( &splp->proc_List, LN_IGNORECASE ); qro = Add_SODB_Resource( splp, processes ); if (qro == 0) { if (bpo_proc_debug) fprintfile( stderr, "Unable to add process resource\n"); shfree( ofp ); splp = Find_SODB_Resource( hint, processes ); } }else { if (bpo_proc_debug) fprintfile( stderr, "Unable to allocate process Head\n"); } } if (bpo_proc_debug) fprintfile(stderr,"Find_Proc_List: returns %p\n", splp ); return(splp); } /* cache routines */ static int add_this_to_cache( struct shm_process *spp, struct cache_proc_list *cpl ) { /* copy out relevant details into private structure */ struct shm_process_private *lpp; lpp = dl_Find_Item_By_Name( &cpl->old_proc_list, spp->pid_str ); if (lpp) { dl_Remove_Node( &lpp->spp_Node ); }else { lpp=alloc_private_process( spp->pid, (const char *)GRPTR(spp, spp->pid_grp_o), (const char *)GRPTR(spp, spp->pid_nm_o), (const char *)GRPTR(spp, spp->pid_fifo_o) ); lpp->pid_start_tm = spp->pid_start_tm; lpp->spp = spp; } if (lpp) dl_Add_Tail( &cpl->proc_list, &lpp->spp_Node ); if (bpo_proc_debug) fprintfile(stderr,"add_this_to_cache: pid %s (%p)\n", spp->pid_str, lpp ); return(0); } static int cache_some_list( bpo_List_t *blp, struct cache_proc_list *cpl ) { struct shm_process_private *sppp; while( (sppp = dl_Remove_Head_Item( &cpl->proc_list )) ) dl_Add_Tail( &cpl->old_proc_list, &sppp->spp_Node ); cpl->update_tm = cpl->splp->update_tm; /* List is locked, so walk it and transfer details */ bpo_Walk_List( blp, (bpo_Walk_List_t)add_this_to_cache, cpl ); dl_Walk_List( &cpl->old_proc_list, (dl_Walk_List_t)free_private_process, NULL ); return(0); } static struct cache_proc_list * cache_procs( struct shm_proc_list *splp ) { char tbuf[40]; struct cache_proc_list *cpl; sprintf( tbuf, "%p", splp ); cpl = dl_Find_Item_By_Name( &cached_procs, tbuf ); if (cpl==NULL && (cpl = malloc( sizeof(struct cache_proc_list) )) ) { if (bpo_proc_debug) fprintfile(stderr,"cache_procs: Start caching %s\n", tbuf ); /* We've never cached this before */ strcpy( cpl->ptr_str, tbuf ); cpl->serial_nbr = 1L; cpl->splp = splp; dl_Init_Node( &cpl->lnk_node, cpl->ptr_str, cpl ); dl_Init_List( &cpl->proc_list, LN_IGNORECASE ); dl_Init_List( &cpl->old_proc_list, LN_IGNORECASE ); dl_Add_Tail( &cached_procs, &cpl->lnk_node ); } if (cpl) { bpo_May_Work_List( &splp->proc_List, &cpl->serial_nbr, (bpo_Work_List_t)cache_some_list, cpl ); } return(cpl); } struct cache_proc_list * Get_Cache_Procs( const void *hint ) { struct shm_proc_list *splp; struct cache_proc_list *cpl; bpo_proc_debug = get_config_flag(proc_debug_str); init_pid_stuff(); splp = Find_Proc_List( hint ); if ( splp == NULL ) return(NULL); cpl = cache_procs(splp); return(cpl); } static int inform_this_pipe( const char *pipe_name ) { static int fifo_fd=-1; static char *old_name=NULL; static char tc='1'; int rv= -1,terr; if (fifo_fd!=-1) { /* still open from before */ if (strcmp(old_name,pipe_name)) { free(old_name); old_name=NULL; close(fifo_fd); fifo_fd= -1; } } if(fifo_fd== -1) { fifo_fd = open( pipe_name, O_WRONLY | O_NONBLOCK ); old_name=strdup(pipe_name); } if (fifo_fd!= -1) { rv = write( fifo_fd, &tc, 1 ); if (old_name==NULL || rv) { terr = errno; close(fifo_fd); fifo_fd= -1; if (old_name) { free(old_name); old_name=NULL; } errno=terr; } } return(rv); } static int inform_lpp( struct shm_process_private *lpp ) { int rv= -1; if (bpo_proc_debug) fprintfile(stderr,"inform_lpp: %ld = %s\n", lpp->pid, (lpp->pid_fifo)? lpp->pid_fifo : "NULL" ); if ( (is_pid_dead( lpp->pid ) == 0) && lpp->pid_fifo ) { rv = inform_this_pipe( lpp->pid_fifo ); } if (bpo_proc_debug) fprintfile(stderr,"inform_lpp: rv = %d\n", rv ); return(rv); } int Inform_Named_Pipe( const char *pipe_name ) { int rv; bpo_proc_debug = get_config_flag(proc_debug_str); if (bpo_proc_debug) fprintfile(stderr,"Inform_Named_Pipe: %s\n", pipe_name ); rv = inform_this_pipe( pipe_name ); return(rv); } int Inform_Process_Str( const void *hint, const char *pid_str ) { struct shm_proc_list *splp; struct shm_process_private *lpp; struct cache_proc_list *cpl; int rv= -1; bpo_proc_debug = get_config_flag(proc_debug_str); if (bpo_proc_debug) fprintfile(stderr,"Inform_Process_Str: %s\n", pid_str ); init_pid_stuff(); /* First we need to ensure that the process list resource exists */ splp = Find_Proc_List( hint ); if ( splp == NULL ) return(rv); if ( (cpl = cache_procs(splp)) && (lpp = dl_Find_Item_By_Name( &cpl->proc_list, pid_str )) ) rv = inform_lpp(lpp); return(rv); } int Inform_Process_Pid( const void *hint, pid_t pid ) { char tstr[12]; gen_pid_str( tstr, pid ); return( Inform_Process_Str( hint, tstr ) ); } /* Now the functions devoted to our own registration in a segment */ static int add_to_work_list( bpo_List_t *blp, struct shm_proc_list *splp, struct shm_process *spp ) { /* must be an add */ bpo_Add_Tail( &splp->proc_List, &spp->proc_Node ); /* Now update the timestamps */ time( &splp->update_tm ); return(0); } int Register_Process_Details( const void *hint ) { struct shm_proc_list *splp; struct shm_process *spp; struct shm_process_private *mdp; size_t sz; int rv=0; char p_str[14]; off_t *offtp; bpo_proc_debug = get_config_flag(proc_debug_str); init_pid_stuff(); /* First we need to ensure that the process list resource exists */ splp = Find_Proc_List( hint ); if ( splp == NULL ) return(rv); gen_pid_str( p_str, getpid() ); /* Are we already registered ? */ spp = bpo_Find_Item_By_Name( &splp->proc_List, p_str ); if ( spp == NULL ) { mdp = Get_My_Proc_Details( Get_SODB_Privs(hint) ); /* Now we allocate (or replace) a proc structure */ sz = sizeof(struct shm_process) + sizeof(off_t); offtp = shalloc( hint, sz ); if (offtp == NULL) { return(rv); } spp = (struct shm_process *)(offtp+1); /* Now setup the details */ spp->lno_me = Get_SODB_Offset( spp ); spp->pid = mdp->pid; strcpy( spp->pid_str, mdp->pid_str ); bpo_Init_Node( &spp->proc_Node, spp->pid_str, spp ); bpo_Init_List( &spp->pid_resources, LN_IGNORECASE ); time( &spp->pid_start_tm ); if (mdp->pid_grp) spp->pid_grp_o = bpo_strdup_offset( splp, mdp->pid_grp ); if (mdp->pid_nm) spp->pid_nm_o = bpo_strdup_offset( splp, mdp->pid_nm ); if (mdp->pid_fifo) spp->pid_fifo_o = bpo_strdup_offset( splp, mdp->pid_fifo ); if (bpo_proc_debug) fprintfile(stderr, "About to add process to proc_list\n" ); bpo_Work_List2( &splp->proc_List, (bpo_Work_List2_t)add_to_work_list, splp, spp ); rv=1; if (bpo_proc_debug) fprintfile(stderr, "shm_process added to process list\n" ); }else { /* is it still valid ? */ rv=1; } /* And add it to the process list for everyone's edification */ return(rv); } static int remove_proc( bpo_List_t *blp, struct proc_man *pmp ) { struct shm_process *spp; if ( (spp=bpo_Find_Item_By_Name( blp, pmp->pid_str )) ) { bpo_Remove_Node( &spp->proc_Node ); pmp->spp = spp; } return(0); } static void shfree_off( void *base, off_t *offtp ) { if (*offtp && base) { shfree( GPTR(base, (*offtp) )); *offtp=(off_t)0; } return; } int Remove_Shm_Process( const void *hint, const char *pid_str ) { struct proc_man pm; struct shm_proc_list *splp; off_t *offtp; splp = Find_Proc_List( hint ); if ( splp == NULL ) return(0); pm.splp = splp; pm.spp = NULL; pm.pid_str = pid_str; bpo_Work_List( &splp->proc_List, (bpo_Work_List_t)remove_proc, &pm ); if (pm.spp) { void *base; base = Get_SODB_Base( pm.spp ); bpo_free_list_contents( &pm.spp->pid_resources ); shfree_off( base, &pm.spp->pid_grp_o ); shfree_off( base, &pm.spp->pid_nm_o ); shfree_off( base, &pm.spp->pid_fifo_o ); offtp = ((off_t *)(pm.spp)) -1; /* shfree( pm.spp );*/ shfree( offtp ); } return((pm.spp)?1:0); } extern int Deregister_Process_Details( const void *hint ) { struct shm_proc_list *splp; struct shm_process_private *mdp; int rv=0; bpo_proc_debug = get_config_flag(proc_debug_str); init_pid_stuff(); /* First we need to ensure that the process list resource exists */ splp = Find_Proc_List( hint ); if ( splp == NULL ) return(rv); mdp = Get_My_Proc_Details( Get_SODB_Privs( hint ) ); /* Next we need to search for a pre-existing proc structure for this process. */ Remove_Shm_Process( splp, mdp->pid_str ); return(rv); } int Add_This_Pid_Resource( const void *hint, bpo_Node_t *nptr ) { struct shm_proc_list *splp; struct shm_process *spp; int rv=0; char p_str[PID_STR_LEN]; bpo_proc_debug = get_config_flag(proc_debug_str); init_pid_stuff(); /* First we need to ensure that the process list resource exists */ splp = Find_Proc_List( hint ); if ( splp == NULL ) return(rv); gen_pid_str( p_str, getpid() ); /* Are we already registered ? */ spp = bpo_Find_Item_By_Name( &splp->proc_List, p_str ); if ( spp ) { bpo_Add_Tail( &spp->pid_resources, nptr ); rv=1; } return(rv); } /* -- End of File -- */