1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
|
/* vi: set sw=4 ts=4: */
/*
* Utility routines.
*
* Copyright 1998 by Albert Cahalan; all rights reserved.
* Copyright (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru>
* GNU Library General Public License Version 2, or any later version
*
*/
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/page.h>
#include "libbb.h"
extern procps_status_t * procps_scan(int save_user_arg0
#ifdef CONFIG_SELINUX
, int use_selinux , security_id_t *sid
#endif
)
{
static DIR *dir;
struct dirent *entry;
static procps_status_t ret_status;
char *name;
int n;
char status[32];
char buf[1024];
FILE *fp;
procps_status_t curstatus;
int pid;
long tasknice;
struct stat sb;
if (!dir) {
dir = opendir("/proc");
if(!dir)
bb_error_msg_and_die("Can't open /proc");
}
for(;;) {
if((entry = readdir(dir)) == NULL) {
closedir(dir);
dir = 0;
return 0;
}
name = entry->d_name;
if (!(*name >= '0' && *name <= '9'))
continue;
memset(&curstatus, 0, sizeof(procps_status_t));
pid = atoi(name);
curstatus.pid = pid;
sprintf(status, "/proc/%d", pid);
if(stat(status, &sb))
continue;
my_getpwuid(curstatus.user, sb.st_uid);
sprintf(status, "/proc/%d/stat", pid);
if((fp = fopen(status, "r")) == NULL)
continue;
#ifdef CONFIG_SELINUX
if(use_selinux)
{
if(fstat_secure(fileno(fp), &sb, sid))
continue;
}
else
#endif
name = fgets(buf, sizeof(buf), fp);
fclose(fp);
if(name == NULL)
continue;
name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
if(name == 0 || name[1] != ' ')
continue;
*name = 0;
sscanf(buf, "%*s (%15c", curstatus.short_cmd);
n = sscanf(name+2,
"%c %d "
"%*s %*s %*s %*s " /* pgrp, session, tty, tpgid */
"%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
#ifdef FEATURE_CPU_USAGE_PERCENTAGE
"%lu %lu "
#else
"%*s %*s "
#endif
"%*s %*s %*s " /* cutime, cstime, priority */
"%ld "
"%*s %*s %*s " /* timeout, it_real_value, start_time */
"%*s " /* vsize */
"%ld",
curstatus.state, &curstatus.ppid,
#ifdef FEATURE_CPU_USAGE_PERCENTAGE
&curstatus.utime, &curstatus.stime,
#endif
&tasknice,
&curstatus.rss);
#ifdef FEATURE_CPU_USAGE_PERCENTAGE
if(n != 6)
#else
if(n != 4)
#endif
continue;
if (curstatus.rss == 0 && curstatus.state[0] != 'Z')
curstatus.state[1] = 'W';
else
curstatus.state[1] = ' ';
if (tasknice < 0)
curstatus.state[2] = '<';
else if (tasknice > 0)
curstatus.state[2] = 'N';
else
curstatus.state[2] = ' ';
#ifdef PAGE_SHIFT
curstatus.rss <<= (PAGE_SHIFT - 10); /* 2**10 = 1kb */
#else
curstatus.rss *= (getpagesize() >> 10); /* 2**10 = 1kb */
#endif
if(save_user_arg0) {
sprintf(status, "/proc/%d/cmdline", pid);
if((fp = fopen(status, "r")) == NULL)
continue;
if((n=fread(buf, 1, sizeof(buf)-1, fp)) > 0) {
if(buf[n-1]=='\n')
buf[--n] = 0;
name = buf;
while(n) {
if(((unsigned char)*name) < ' ')
*name = ' ';
name++;
n--;
}
*name = 0;
if(buf[0])
curstatus.cmd = strdup(buf);
/* if NULL it work true also */
}
fclose(fp);
}
return memcpy(&ret_status, &curstatus, sizeof(procps_status_t));
}
}
/* END CODE */
/*
Local Variables:
c-file-style: "linux"
c-basic-offset: 4
tab-width: 4
End:
*/
|