Code:
for ( ; glance->process < glance->idNodes.count; glance->process++ )
{
notice->ownerId = *(
((int*)(glance->idNodes.space.block)) + glance->process);
while ( proc_notice_info( err, notice->ownerId, notice ) )
{
if ( notice->ownerId == glance->underId )
return proc_notice_info( err, entryId, notice );
if ( notice->ownerId <= 0 )
break;
}
}
if ( err ) *err = EXIT_SUCCESS;
proc_glance_shut( glance );
return NULL;
}
proc_notice_t*
proc_glance_open( int *err, proc_glance_t *glance, int underId ) {
int ret = errno = EXIT_SUCCESS;
DIR *dir;
struct dirent *ent;
node_t i = 0;
if ( !glance ) {
if ( err ) *err = EDESTADDRREQ;
ERRMSG( EDESTADDRREQ, "glance was NULL" );
return NULL;
}
(void)memset( glance, 0, sizeof(proc_glance_t) );
glance->underId = underId;
if ( more_nodes( int, &ret, &(glance->idNodes), 2000 ) ) {
if ( (dir = opendir("/proc")) ) {
while ( (ent = readdir( dir )) ) {
if ( ent->d_name[0] < '0' && ent->d_name[0] > '9' )
continue;
if ( (ret = add_node(
&(glance->idNodes), &i, sizeof(int) ))
!= EXIT_SUCCESS )
break;
sscanf( ent->d_name, "%d",
((int*)(glance->idNodes.space.block)) + i );
}
closedir(dir);
if ( glance->idNodes.count )
return proc_notice_next( err, glance );
}
}
ret = ( errno != EXIT_SUCCESS ) ? errno : EXIT_FAILURE;
if ( err ) *err = ret;
ERRMSG( ret, "glance->dir was NULL" );
return NULL;
}
...
proc_notice_t* proc_notice_info(
int *err, int pid, proc_notice_t *notice )
{
int fd;
char path[256] = {0};
space_t *full, *key, *val, *name;
kvpair_t *kvpair;
int ret;
char *txt, *k, *v;
intptr_t size;
if ( !notice ) {
if ( err ) *err = EDESTADDRREQ;
ERRMSG( EDESTADDRREQ, "notice was NULL" );
return NULL;
}
kvpair = &(notice->kvpair);
name = &(notice->name);
full = &(kvpair->full);
key = &(kvpair->key);
val = &(kvpair->val);
memset( name->block, 0, name->given );
memset( full->block, 0, full->given );
memset( key->block, 0, key->given );
memset( val->block, 0, val->given );
notice->ownerId = -1;
notice->entryId = pid;
sprintf( path, "/proc/%d/status", pid );
/* Implements a fallback looped read call in the event lseek gleans
* nothing */
if ( !(size = file_get_size( &ret, path )) ) {
if ( err ) *err = ret;
ERRMSG( ret, "Couldn't get status size" );
return NULL;
}
if ( (fd = open(path,O_RDONLY)) < 0 ) {
if ( err ) *err = errno;
ERRMSG( errno, "Couldn't open status file" );
printf( "File '%s'\n", path );
return NULL;
}
if ( !more_space( &ret, full, size )) {
if ( err ) *err = ret;
ERRMSG( ret, "Couldn't allocate memory to read into" );
fprintf( stderr, "Wanted %zu bytes\n", size );
close(fd);
return NULL;
}
if ( !gasp_read(fd, full->block, full->given) ) {
close(fd);
ret = ENODATA;
if ( err ) *err = ret;
ERRMSG( ret, "Couldn't read the status file" );
return NULL;
}
/* No longer need the file opened since we have everything */
close(fd);
if ( (ret = change_kvpair(
kvpair, full->given,
full->given, full->given, 1 )) != EXIT_SUCCESS ) {
if ( err ) *err = ret;
ERRMSG( ret, "Couldn't allocate memory for key/val pair" );
return NULL;
}
/* Ensure we have enough space for the name */
if ( !more_space( &ret, name, full->given ) ) {
if ( err ) *err = ret;
ERRMSG( ret, "Couldn't allocate memory for name");
return NULL;
}
txt = strstr( full->block, "\n" );
if ( !txt ) {
ret = ENOSYS;
if ( err ) *err = ret;
ERRMSG( ret, "Don't know how to handle the status file" );
return NULL;
}
/* Don't want strlen to count through everything */
*txt = 0;
/* Find the start of the name given */
v = strstr( (k = full->block), "\t" );
if ( !v ) {
ret = ENODATA;
if ( *err ) *err = ret;
ERRMSG( ret, "Couldn't find character '\t' in read text");
(void)fprintf(stderr,"read '%s'\n", full->block );
return NULL;
}
/* We don't want to copy the tab character */
++v;
/* Fill name with the name given */
memcpy( name->block, v, strlen(v) );
/* Restore ability for strstr to see next character */
*txt = '\n';
while ( (k = txt = strstr( txt, "\n" )) ) {
*k = 0; ++k;
v = strstr( k, "\t" );
*v = 0;
/* This is currently the only value we care about besides the
* name */
if ( strcmp( k, "PPid:" ) == 0 ) break;
*v = '\t';
*(--k) = '\n';
++txt;
}
if ( !txt ) {
ret = ENOENT;
if ( err ) *err = ret;
ERRMSG( ret, "Couldn't locate ownerId" );
return NULL;
}
/* Just in case we decide to take more parameters */
*v = '\t';
sscanf( txt, "%d", &(notice->ownerId) );
if ( err ) *err = EXIT_SUCCESS;
return notice;
}