1
0
Files
2022-09-29 17:59:04 +03:00

166 lines
4.0 KiB
C++

/* proctbl.c++ - keep track of event server client pids
*
* NetVisualyzer Event Server
*
* $Revision: 1.2 $
*
*/
/*
* Copyright 1992 Silicon Graphics, Inc. All rights reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include "proctbl.h"
#define D_PRINTF(stuff) \
if (EV_debugging) fprintf stuff;
extern int EV_debugging;
/*
* procTable - constructor. create the table and initialize it
*/
procTable::procTable(int sz) {
size = sz; //total size of table
pcount = 0; // count of client pids
pa = new pid_t[size]; // create the table itself
for (int i = 0; i < size; i++) {
pa[i] = (PID_MAX+1); //initialize entries to invalid pid
}
}
/*
* grow -- double the size of the table if it become full.
*/
int
procTable::grow(void) {
int newsize = 2*size;
int i;
D_PRINTF ((stderr, "procTable::grow expanding table from %d to %d\n",
size, newsize));
if (EV_debugging) dump();
tpa = new pid_t[newsize]; //allocate a new larger table
if (! tpa) {
return 0;
}
for (i = 0; i < size; i++) { //copy current table
tpa[i] = pa[i];
}
for (i = size; i < newsize; i++) { //initialize the new blank entries
tpa[i] = (PID_MAX+1);
}
delete [size] pa; //delete the old space
pa = tpa; //point to the new space
size = newsize; //record new size
return (size);
}
/*
* add - add a client to the table
*/
Bool
procTable::add(pid_t pid) {
if (pcount == size) { // I'm full
if (! grow()) {
syslog(LOG_ERR,
"procTable::add: cannot grow table to add client %d, pid %d",
(pcount +1), pid);
return FALSE;
}
}
/*
* Find first empty slot and stuff the pid in it.
*/
for (int i = 0; i < size; i++) {
if (pa[i] == (PID_MAX+1)) {
pa[i] = pid;
pcount++;
break;
}
}
if (EV_debugging) dump();
return TRUE;
}
/*
* remove - remove an entry from the table
*/
int
procTable::remove (pid_t pid) {
int oldpcount = pcount;
for (int i = 0; i < size; i++) {
if (pa[i] == pid) {
pa[i] = (PID_MAX+1);
pcount--;
break;
}
}
// if the pid wasn't found return 0 else the new count
return ((pcount == oldpcount) ? 0 : pcount);
}
/*
* scan the pid table looking to see if any of the processes have disappeared.
* If they have, remove the entry from the table.
* Return FALSE (0) if there are no processes left at all otherwise TRUE(1)
*
* Note I always scan the entire table.
*/
int
procTable::scan() {
int found = FALSE;
for (int i = 0; i < size; i++) { // scan entire table
if (pa[i] != (PID_MAX+1)) { // look at only the possible existing
if (extant(pa[i])) { // client still there?
found = TRUE; // yup. Found at least one
}
else {
pa[i] = (PID_MAX+1); //client gone, mark it so
}
}
}
return (found);
}
Bool
procTable::extant (pid_t pid) {
int rslt;
if( (rslt = kill(pid, 0) == -1) && errno == ESRCH){
D_PRINTF ( (stderr, "procTable::extant pid %d does not exist\n", pid));
return FALSE;
}
else if (rslt == 0) {
D_PRINTF ((stderr, "procTable::extant pid %d exists\n", pid));
return TRUE;
}
else {
syslog (LOG_ERR, "procTable::extant: pid %d: kill errno %d",
pid, errno);
return TRUE;
}
}
void
procTable::dump(void) {
D_PRINTF ((stderr, "procTabel::dump: # clients: %d ", pcount));
for (int i = 0; i < size; i++) {
D_PRINTF((stderr, "%d: %d, ", i, pa[i]));
}
D_PRINTF ((stderr, "\n"));
}