blob: 25f42ffc8f35aa28ac99cfa5b302cd753ad2b634 [file] [log] [blame]
Eric Andersen44608e92002-10-22 12:21:15 +00001/* vi: set sw=4 ts=4: */
2/*
3 * Utility routines.
4 *
5 * Copyright 1998 by Albert Cahalan; all rights reserved.
6 * Copyright (C) 2002 by Vladimir Oleynik <dzo@simtreas.ru>
7 * GNU Library General Public License Version 2, or any later version
8 *
9 */
10
Eric Andersen44608e92002-10-22 12:21:15 +000011#include <dirent.h>
12#include <string.h>
13#include <stdlib.h>
14#include <unistd.h>
15#include <asm/page.h>
Rob Landleyb2804552006-02-13 22:04:27 +000016#include <fcntl.h>
Eric Andersen44608e92002-10-22 12:21:15 +000017
Glenn L McGrath7b1eca22002-11-24 01:32:56 +000018#include "libbb.h"
Eric Andersen44608e92002-10-22 12:21:15 +000019
Rob Landleyb2804552006-02-13 22:04:27 +000020
"Vladimir N. Oleynik"465300c2006-02-14 10:17:09 +000021#define PROCPS_BUFSIZE 1024
22
23static int read_to_buf(const char *filename, void *buf)
Rob Landleyb2804552006-02-13 22:04:27 +000024{
25 int fd;
"Vladimir N. Oleynik"465300c2006-02-14 10:17:09 +000026 ssize_t ret;
Rob Landleyb2804552006-02-13 22:04:27 +000027
28 fd = open(filename, O_RDONLY);
29 if(fd < 0)
30 return -1;
"Vladimir N. Oleynik"465300c2006-02-14 10:17:09 +000031 ret = read(fd, buf, PROCPS_BUFSIZE);
Rob Landleyb2804552006-02-13 22:04:27 +000032 close(fd);
"Vladimir N. Oleynik"465300c2006-02-14 10:17:09 +000033 return ret;
Rob Landleyb2804552006-02-13 22:04:27 +000034}
35
36
Rob Landleydfba7412006-03-06 20:47:33 +000037procps_status_t * procps_scan(int save_user_arg0)
Eric Andersen44608e92002-10-22 12:21:15 +000038{
39 static DIR *dir;
40 struct dirent *entry;
41 static procps_status_t ret_status;
42 char *name;
43 int n;
44 char status[32];
Rob Landleyb2804552006-02-13 22:04:27 +000045 char *status_tail;
"Vladimir N. Oleynik"465300c2006-02-14 10:17:09 +000046 char buf[PROCPS_BUFSIZE];
Eric Andersen44608e92002-10-22 12:21:15 +000047 procps_status_t curstatus;
48 int pid;
49 long tasknice;
50 struct stat sb;
51
52 if (!dir) {
Bernhard Reutner-Fischercb448162006-04-12 07:35:12 +000053 dir = bb_xopendir("/proc");
Eric Andersen44608e92002-10-22 12:21:15 +000054 }
55 for(;;) {
56 if((entry = readdir(dir)) == NULL) {
57 closedir(dir);
58 dir = 0;
59 return 0;
60 }
61 name = entry->d_name;
62 if (!(*name >= '0' && *name <= '9'))
63 continue;
64
65 memset(&curstatus, 0, sizeof(procps_status_t));
66 pid = atoi(name);
67 curstatus.pid = pid;
68
Rob Landleyb2804552006-02-13 22:04:27 +000069 status_tail = status + sprintf(status, "/proc/%d", pid);
Eric Andersen242ab832004-01-27 20:17:39 +000070 if(stat(status, &sb))
71 continue;
Bernhard Reutner-Fischerd5bd1372005-09-20 21:06:17 +000072 bb_getpwuid(curstatus.user, sb.st_uid, sizeof(curstatus.user));
Eric Andersen242ab832004-01-27 20:17:39 +000073
Rob Landleyb2804552006-02-13 22:04:27 +000074 strcpy(status_tail, "/stat");
"Vladimir N. Oleynik"465300c2006-02-14 10:17:09 +000075 n = read_to_buf(status, buf);
Rob Landleyb2804552006-02-13 22:04:27 +000076 if(n < 0)
Eric Andersen44608e92002-10-22 12:21:15 +000077 continue;
78 name = strrchr(buf, ')'); /* split into "PID (cmd" and "<rest>" */
79 if(name == 0 || name[1] != ' ')
80 continue;
81 *name = 0;
82 sscanf(buf, "%*s (%15c", curstatus.short_cmd);
83 n = sscanf(name+2,
84 "%c %d "
85 "%*s %*s %*s %*s " /* pgrp, session, tty, tpgid */
86 "%*s %*s %*s %*s %*s " /* flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
"Vladimir N. Oleynik"f246dc72005-09-16 12:55:29 +000087#ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
Eric Andersen44608e92002-10-22 12:21:15 +000088 "%lu %lu "
89#else
90 "%*s %*s "
91#endif
92 "%*s %*s %*s " /* cutime, cstime, priority */
93 "%ld "
94 "%*s %*s %*s " /* timeout, it_real_value, start_time */
95 "%*s " /* vsize */
96 "%ld",
97 curstatus.state, &curstatus.ppid,
"Vladimir N. Oleynik"f246dc72005-09-16 12:55:29 +000098#ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
Eric Andersen44608e92002-10-22 12:21:15 +000099 &curstatus.utime, &curstatus.stime,
100#endif
101 &tasknice,
102 &curstatus.rss);
"Vladimir N. Oleynik"f246dc72005-09-16 12:55:29 +0000103#ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
Eric Andersen44608e92002-10-22 12:21:15 +0000104 if(n != 6)
105#else
106 if(n != 4)
107#endif
108 continue;
109
110 if (curstatus.rss == 0 && curstatus.state[0] != 'Z')
111 curstatus.state[1] = 'W';
112 else
113 curstatus.state[1] = ' ';
114 if (tasknice < 0)
115 curstatus.state[2] = '<';
116 else if (tasknice > 0)
117 curstatus.state[2] = 'N';
118 else
119 curstatus.state[2] = ' ';
120
Glenn L McGratha1e4a0e2004-01-21 11:36:44 +0000121#ifdef PAGE_SHIFT
Eric Andersen44608e92002-10-22 12:21:15 +0000122 curstatus.rss <<= (PAGE_SHIFT - 10); /* 2**10 = 1kb */
Glenn L McGratha1e4a0e2004-01-21 11:36:44 +0000123#else
124 curstatus.rss *= (getpagesize() >> 10); /* 2**10 = 1kb */
125#endif
Eric Andersen44608e92002-10-22 12:21:15 +0000126
Eric Andersen44608e92002-10-22 12:21:15 +0000127 if(save_user_arg0) {
Rob Landleyb2804552006-02-13 22:04:27 +0000128 strcpy(status_tail, "/cmdline");
"Vladimir N. Oleynik"465300c2006-02-14 10:17:09 +0000129 n = read_to_buf(status, buf);
Rob Landleyb2804552006-02-13 22:04:27 +0000130 if(n > 0) {
Glenn L McGrath393ad1a2002-11-25 22:31:37 +0000131 if(buf[n-1]=='\n')
132 buf[--n] = 0;
133 name = buf;
134 while(n) {
Glenn L McGrath09adaca2002-12-02 21:18:10 +0000135 if(((unsigned char)*name) < ' ')
Glenn L McGrath393ad1a2002-11-25 22:31:37 +0000136 *name = ' ';
137 name++;
138 n--;
139 }
140 *name = 0;
Eric Andersen44608e92002-10-22 12:21:15 +0000141 if(buf[0])
142 curstatus.cmd = strdup(buf);
143 /* if NULL it work true also */
144 }
Eric Andersen44608e92002-10-22 12:21:15 +0000145 }
146 return memcpy(&ret_status, &curstatus, sizeof(procps_status_t));
147 }
148}
149
Eric Andersen44608e92002-10-22 12:21:15 +0000150/* END CODE */
151/*
152Local Variables:
153c-file-style: "linux"
154c-basic-offset: 4
155tab-width: 4
156End:
157*/