Changeset 3232 in MondoRescue for branches/3.2/mindi-busybox/procps
- Timestamp:
- Jan 1, 2014, 12:47:38 AM (10 years ago)
- Location:
- branches/3.2/mindi-busybox/procps
- Files:
-
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/3.2/mindi-busybox/procps/Config.src
r2725 r3232 11 11 bool "free" 12 12 default y 13 depends onPLATFORM_LINUX #sysinfo()13 select PLATFORM_LINUX #sysinfo() 14 14 help 15 15 free displays the total amount of free and used physical and swap … … 46 46 default y 47 47 depends on KILL 48 49 config NMETER50 bool "nmeter"51 default y52 help53 Prints selected system stats continuously, one line per update.54 48 55 49 config PGREP … … 97 91 bool "Enable wide output option (-w)" 98 92 default y 99 depends on PS 93 depends on PS && !DESKTOP 100 94 help 101 95 Support argument 'w' for wide output. … … 103 97 than once, the length is unlimited. 104 98 99 config FEATURE_PS_LONG 100 bool "Enable long output option (-l)" 101 default y 102 depends on PS && !DESKTOP 103 help 104 Support argument 'l' for long output. 105 Adds fields PPID, RSS, START, TIME & TTY 106 105 107 config FEATURE_PS_TIME 106 108 bool "Enable time and elapsed time output" 107 109 default y 108 depends on PS && DESKTOP && PLATFORM_LINUX #sysinfo() 110 depends on PS && DESKTOP 111 select PLATFORM_LINUX 109 112 help 110 113 Support -o time and -o etime output specifiers. … … 138 141 Configure kernel parameters at runtime. 139 142 140 config TOP141 bool " top"143 config FEATURE_SHOW_THREADS 144 bool "Support for showing threads in ps/pstree/top" 142 145 default y 146 depends on PS || TOP || PSTREE 143 147 help 144 The top program provides a dynamic real-time view of a running 145 system. 146 147 config FEATURE_TOP_CPU_USAGE_PERCENTAGE 148 bool "Show CPU per-process usage percentage" 149 default y 150 depends on TOP 151 help 152 Make top display CPU usage for each process. 153 This adds about 2k. 154 155 config FEATURE_TOP_CPU_GLOBAL_PERCENTS 156 bool "Show CPU global usage percentage" 157 default y 158 depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE 159 help 160 Makes top display "CPU: NN% usr NN% sys..." line. 161 This adds about 0.5k. 162 163 config FEATURE_TOP_SMP_CPU 164 bool "SMP CPU usage display ('c' key)" 165 default y 166 depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS 167 help 168 Allow 'c' key to switch between individual/cumulative CPU stats 169 This adds about 0.5k. 170 171 config FEATURE_TOP_DECIMALS 172 bool "Show 1/10th of a percent in CPU/mem statistics" 173 default y 174 depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE 175 help 176 Show 1/10th of a percent in CPU/mem statistics. 177 This adds about 0.3k. 178 179 config FEATURE_TOP_SMP_PROCESS 180 bool "Show CPU process runs on ('j' field)" 181 default y 182 depends on TOP 183 help 184 Show CPU where process was last found running on. 185 This is the 'j' field. 186 187 config FEATURE_TOPMEM 188 bool "Topmem command ('s' key)" 189 default y 190 depends on TOP 191 help 192 Enable 's' in top (gives lots of memory info). 193 194 config FEATURE_SHOW_THREADS 195 bool "Support for showing threads in ps/top" 196 default y 197 depends on PS || TOP 198 help 199 Enables ps -T option and 'h' command in top 200 201 config UPTIME 202 bool "uptime" 203 default y 204 depends on PLATFORM_LINUX #sysinfo() 205 help 206 uptime gives a one line display of the current time, how long 207 the system has been running, how many users are currently logged 208 on, and the system load averages for the past 1, 5, and 15 minutes. 148 Enables the ps -T option, showing of threads in pstree, 149 and 'h' command in top. 209 150 210 151 config WATCH -
branches/3.2/mindi-busybox/procps/Kbuild.src
r2725 r3232 12 12 lib-$(CONFIG_KILL) += kill.o 13 13 lib-$(CONFIG_ASH) += kill.o # used for built-in kill by ash 14 lib-$(CONFIG_NMETER) += nmeter.o15 14 lib-$(CONFIG_PGREP) += pgrep.o 16 15 lib-$(CONFIG_PKILL) += pgrep.o -
branches/3.2/mindi-busybox/procps/free.c
r2725 r3232 10 10 /* getopt not needed */ 11 11 12 //usage:#define free_trivial_usage 13 //usage: "" IF_DESKTOP("[-b/k/m/g]") 14 //usage:#define free_full_usage "\n\n" 15 //usage: "Display the amount of free and used system memory" 16 //usage: 17 //usage:#define free_example_usage 18 //usage: "$ free\n" 19 //usage: " total used free shared buffers\n" 20 //usage: " Mem: 257628 248724 8904 59644 93124\n" 21 //usage: " Swap: 128516 8404 120112\n" 22 //usage: "Total: 386144 257128 129016\n" 23 12 24 #include "libbb.h" 25 #ifdef __linux__ 26 # include <sys/sysinfo.h> 27 #endif 13 28 14 29 struct globals { … … 20 35 # define G_unit_steps 10 21 36 #endif 22 } ;37 } FIX_ALIASING; 23 38 #define G (*(struct globals*)&bb_common_bufsiz1) 24 39 #define INIT_G() do { } while (0) -
branches/3.2/mindi-busybox/procps/fuser.c
r2859 r3232 8 8 */ 9 9 10 //usage:#define fuser_trivial_usage 11 //usage: "[OPTIONS] FILE or PORT/PROTO" 12 //usage:#define fuser_full_usage "\n\n" 13 //usage: "Find processes which use FILEs or PORTs\n" 14 //usage: "\n -m Find processes which use same fs as FILEs" 15 //usage: "\n -4,-6 Search only IPv4/IPv6 space" 16 //usage: "\n -s Don't display PIDs" 17 //usage: "\n -k Kill found processes" 18 //usage: "\n -SIGNAL Signal to send (default: KILL)" 19 10 20 #include "libbb.h" 11 21 … … 27 37 } inode_list; 28 38 29 typedef struct pid_list {30 struct pid_list *next;31 pid_t pid;32 } pid_list;33 34 35 39 struct globals { 36 pid_list *pid_list_head; 40 int recursion_depth; 41 pid_t mypid; 37 42 inode_list *inode_list_head; 38 }; 43 smallint kill_failed; 44 int killsig; 45 } FIX_ALIASING; 39 46 #define G (*(struct globals*)&bb_common_bufsiz1) 40 #define INIT_G() do { } while (0) 41 42 43 static void add_pid(const pid_t pid) 44 { 45 pid_list **curr = &G.pid_list_head; 46 47 while (*curr) { 48 if ((*curr)->pid == pid) 49 return; 50 curr = &(*curr)->next; 51 } 52 53 *curr = xzalloc(sizeof(pid_list)); 54 (*curr)->pid = pid; 55 } 47 #define INIT_G() do { \ 48 G.mypid = getpid(); \ 49 G.killsig = SIGKILL; \ 50 } while (0) 56 51 57 52 static void add_inode(const struct stat *st) … … 73 68 } 74 69 75 static void scan_proc_net(const char *path, unsigned port) 76 { 77 char line[MAX_LINE + 1]; 78 long long uint64_inode; 79 unsigned tmp_port; 80 FILE *f; 81 struct stat st; 82 int fd; 83 84 /* find socket dev */ 85 st.st_dev = 0; 86 fd = socket(AF_INET, SOCK_DGRAM, 0); 87 if (fd >= 0) { 88 fstat(fd, &st); 89 close(fd); 90 } 91 92 f = fopen_for_read(path); 93 if (!f) 94 return; 95 96 while (fgets(line, MAX_LINE, f)) { 97 char addr[68]; 98 if (sscanf(line, "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x %*x:%*x " 99 "%*x:%*x %*x %*d %*d %llu", 100 addr, &tmp_port, &uint64_inode) == 3 101 ) { 102 int len = strlen(addr); 103 if (len == 8 && (option_mask32 & OPT_IP6)) 104 continue; 105 if (len > 8 && (option_mask32 & OPT_IP4)) 106 continue; 107 if (tmp_port == port) { 108 st.st_ino = uint64_inode; 109 add_inode(&st); 110 } 111 } 112 } 113 fclose(f); 114 } 115 116 static int search_dev_inode(const struct stat *st) 70 static smallint search_dev_inode(const struct stat *st) 117 71 { 118 72 inode_list *ilist = G.inode_list_head; … … 130 84 } 131 85 132 static void scan_pid_maps(const char *fname, pid_t pid) 133 { 134 FILE *file; 135 char line[MAX_LINE + 1]; 136 int major, minor; 86 enum { 87 PROC_NET = 0, 88 PROC_DIR, 89 PROC_DIR_LINKS, 90 PROC_SUBDIR_LINKS, 91 }; 92 93 static smallint scan_proc_net_or_maps(const char *path, unsigned port) 94 { 95 FILE *f; 96 char line[MAX_LINE + 1], addr[68]; 97 int major, minor, r; 137 98 long long uint64_inode; 138 struct stat st; 139 140 file = fopen_for_read(fname); 141 if (!file) 142 return; 143 144 while (fgets(line, MAX_LINE, file)) { 145 if (sscanf(line, "%*s %*s %*s %x:%x %llu", &major, &minor, &uint64_inode) != 3) 99 unsigned tmp_port; 100 smallint retval; 101 struct stat statbuf; 102 const char *fmt; 103 void *fag, *sag; 104 105 f = fopen_for_read(path); 106 if (!f) 107 return 0; 108 109 if (G.recursion_depth == PROC_NET) { 110 int fd; 111 112 /* find socket dev */ 113 statbuf.st_dev = 0; 114 fd = socket(AF_INET, SOCK_DGRAM, 0); 115 if (fd >= 0) { 116 fstat(fd, &statbuf); 117 close(fd); 118 } 119 120 fmt = "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x " 121 "%*x:%*x %*x:%*x %*x %*d %*d %llu"; 122 fag = addr; 123 sag = &tmp_port; 124 } else { 125 fmt = "%*s %*s %*s %x:%x %llu"; 126 fag = &major; 127 sag = &minor; 128 } 129 130 retval = 0; 131 while (fgets(line, MAX_LINE, f)) { 132 r = sscanf(line, fmt, fag, sag, &uint64_inode); 133 if (r != 3) 146 134 continue; 147 st.st_ino = uint64_inode; 148 if (major == 0 && minor == 0 && st.st_ino == 0) 149 continue; 150 st.st_dev = makedev(major, minor); 151 if (search_dev_inode(&st)) 152 add_pid(pid); 153 } 154 fclose(file); 155 } 156 157 static void scan_link(const char *lname, pid_t pid) 158 { 159 struct stat st; 160 161 if (stat(lname, &st) >= 0) { 162 if (search_dev_inode(&st)) 163 add_pid(pid); 164 } 165 } 166 167 static void scan_dir_links(const char *dname, pid_t pid) 135 136 statbuf.st_ino = uint64_inode; 137 if (G.recursion_depth == PROC_NET) { 138 r = strlen(addr); 139 if (r == 8 && (option_mask32 & OPT_IP6)) 140 continue; 141 if (r > 8 && (option_mask32 & OPT_IP4)) 142 continue; 143 if (tmp_port == port) 144 add_inode(&statbuf); 145 } else { 146 if (major != 0 && minor != 0 && statbuf.st_ino != 0) { 147 statbuf.st_dev = makedev(major, minor); 148 retval = search_dev_inode(&statbuf); 149 if (retval) 150 break; 151 } 152 } 153 } 154 fclose(f); 155 156 return retval; 157 } 158 159 static smallint scan_recursive(const char *path) 168 160 { 169 161 DIR *d; 170 struct dirent *de; 171 char *lname; 172 173 d = opendir(dname); 174 if (!d) 175 return; 176 177 while ((de = readdir(d)) != NULL) { 178 lname = concat_subpath_file(dname, de->d_name); 179 if (lname == NULL) 180 continue; 181 scan_link(lname, pid); 182 free(lname); 162 struct dirent *d_ent; 163 smallint stop_scan; 164 smallint retval; 165 166 d = opendir(path); 167 if (d == NULL) 168 return 0; 169 170 G.recursion_depth++; 171 retval = 0; 172 stop_scan = 0; 173 while (!stop_scan && (d_ent = readdir(d)) != NULL) { 174 struct stat statbuf; 175 pid_t pid; 176 char *subpath; 177 178 subpath = concat_subpath_file(path, d_ent->d_name); 179 if (subpath == NULL) 180 continue; /* . or .. */ 181 182 switch (G.recursion_depth) { 183 case PROC_DIR: 184 pid = (pid_t)bb_strtou(d_ent->d_name, NULL, 10); 185 if (errno != 0 186 || pid == G.mypid 187 /* "this PID doesn't use specified FILEs or PORT/PROTO": */ 188 || scan_recursive(subpath) == 0 189 ) { 190 break; 191 } 192 if (option_mask32 & OPT_KILL) { 193 if (kill(pid, G.killsig) != 0) { 194 bb_perror_msg("kill pid %s", d_ent->d_name); 195 G.kill_failed = 1; 196 } 197 } 198 if (!(option_mask32 & OPT_SILENT)) 199 printf("%s ", d_ent->d_name); 200 retval = 1; 201 break; 202 203 case PROC_DIR_LINKS: 204 switch ( 205 index_in_substrings( 206 "cwd" "\0" "exe" "\0" 207 "root" "\0" "fd" "\0" 208 "lib" "\0" "mmap" "\0" 209 "maps" "\0", 210 d_ent->d_name 211 ) 212 ) { 213 enum { 214 CWD_LINK, 215 EXE_LINK, 216 ROOT_LINK, 217 FD_DIR_LINKS, 218 LIB_DIR_LINKS, 219 MMAP_DIR_LINKS, 220 MAPS, 221 }; 222 case CWD_LINK: 223 case EXE_LINK: 224 case ROOT_LINK: 225 goto scan_link; 226 case FD_DIR_LINKS: 227 case LIB_DIR_LINKS: 228 case MMAP_DIR_LINKS: 229 stop_scan = scan_recursive(subpath); 230 if (stop_scan) 231 retval = stop_scan; 232 break; 233 case MAPS: 234 stop_scan = scan_proc_net_or_maps(subpath, 0); 235 if (stop_scan) 236 retval = stop_scan; 237 default: 238 break; 239 } 240 break; 241 case PROC_SUBDIR_LINKS: 242 scan_link: 243 if (stat(subpath, &statbuf) < 0) 244 break; 245 stop_scan = search_dev_inode(&statbuf); 246 if (stop_scan) 247 retval = stop_scan; 248 default: 249 break; 250 } 251 free(subpath); 183 252 } 184 253 closedir(d); 185 } 186 187 /* NB: does chdir internally */ 188 static void scan_proc_pids(void) 189 { 190 DIR *d; 191 struct dirent *de; 192 pid_t pid; 193 194 xchdir("/proc"); 195 d = opendir("/proc"); 196 if (!d) 197 return; 198 199 while ((de = readdir(d)) != NULL) { 200 pid = (pid_t)bb_strtou(de->d_name, NULL, 10); 201 if (errno) 202 continue; 203 if (chdir(de->d_name) < 0) 204 continue; 205 scan_link("cwd", pid); 206 scan_link("exe", pid); 207 scan_link("root", pid); 208 209 scan_dir_links("fd", pid); 210 scan_dir_links("lib", pid); 211 scan_dir_links("mmap", pid); 212 213 scan_pid_maps("maps", pid); 214 xchdir("/proc"); 215 } 216 closedir(d); 254 G.recursion_depth--; 255 return retval; 217 256 } 218 257 … … 220 259 int fuser_main(int argc UNUSED_PARAM, char **argv) 221 260 { 222 pid_list *plist;223 pid_t mypid;224 261 char **pp; 225 struct stat st; 226 unsigned port; 227 int opt; 228 int exitcode; 229 int killsig; 230 /* 231 fuser [OPTIONS] FILE or PORT/PROTO 232 Find processes which use FILEs or PORTs 233 -m Find processes which use same fs as FILEs 234 -4 Search only IPv4 space 235 -6 Search only IPv6 space 236 -s Don't display PIDs 237 -k Kill found processes 238 -SIGNAL Signal to send (default: KILL) 239 */ 262 263 INIT_G(); 264 240 265 /* Handle -SIGNAL. Oh my... */ 241 killsig = SIGKILL; /* yes, the default is not SIGTERM */242 266 pp = argv; 243 267 while (*++pp) { 268 int sig; 244 269 char *arg = *pp; 270 245 271 if (arg[0] != '-') 246 272 continue; … … 249 275 if ((arg[1] == '4' || arg[1] == '6') && arg[2] == '\0') 250 276 continue; /* it's "-4" or "-6" */ 251 opt= get_signum(&arg[1]);252 if ( opt< 0)277 sig = get_signum(&arg[1]); 278 if (sig < 0) 253 279 continue; 254 280 /* "-SIGNAL" option found. Remove it and bail out */ 255 killsig = opt;281 G.killsig = sig; 256 282 do { 257 283 pp[0] = arg = pp[1]; … … 262 288 263 289 opt_complementary = "-1"; /* at least one param */ 264 opt =getopt32(argv, OPTION_STRING);290 getopt32(argv, OPTION_STRING); 265 291 argv += optind; 266 292 … … 268 294 while (*pp) { 269 295 /* parse net arg */ 270 char path[20], tproto[5]; 271 if (sscanf(*pp, "%u/%4s", &port, tproto) != 2) 272 goto file; 273 sprintf(path, "/proc/net/%s", tproto); 274 if (access(path, R_OK) == 0) { /* PORT/PROTO */ 275 scan_proc_net(path, port); 276 } else { /* FILE */ 277 file: 278 xstat(*pp, &st); 279 add_inode(&st); 296 unsigned port; 297 char path[sizeof("/proc/net/TCP6")]; 298 299 strcpy(path, "/proc/net/"); 300 if (sscanf(*pp, "%u/%4s", &port, path + sizeof("/proc/net/")-1) == 2 301 && access(path, R_OK) == 0 302 ) { 303 /* PORT/PROTO */ 304 scan_proc_net_or_maps(path, port); 305 } else { 306 /* FILE */ 307 struct stat statbuf; 308 xstat(*pp, &statbuf); 309 add_inode(&statbuf); 280 310 } 281 311 pp++; 282 312 } 283 313 284 scan_proc_pids(); /* changes dir to "/proc" */ 285 286 mypid = getpid(); 287 plist = G.pid_list_head; 288 while (1) { 289 if (!plist) 290 return EXIT_FAILURE; 291 if (plist->pid != mypid) 292 break; 293 plist = plist->next; 294 } 295 296 exitcode = EXIT_SUCCESS; 297 do { 298 if (plist->pid != mypid) { 299 if (opt & OPT_KILL) { 300 if (kill(plist->pid, killsig) != 0) { 301 bb_perror_msg("kill pid %u", (unsigned)plist->pid); 302 exitcode = EXIT_FAILURE; 303 } 304 } 305 if (!(opt & OPT_SILENT)) { 306 printf("%u ", (unsigned)plist->pid); 307 } 308 } 309 plist = plist->next; 310 } while (plist); 311 312 if (!(opt & (OPT_SILENT))) { 313 bb_putchar('\n'); 314 } 315 316 return exitcode; 317 } 314 if (scan_recursive("/proc")) { 315 if (!(option_mask32 & OPT_SILENT)) 316 bb_putchar('\n'); 317 return G.kill_failed; 318 } 319 320 return EXIT_FAILURE; 321 } -
branches/3.2/mindi-busybox/procps/iostat.c
r2725 r3232 8 8 */ 9 9 10 //applet:IF_IOSTAT(APPLET(iostat, _BB_DIR_BIN, _BB_SUID_DROP))11 12 //kbuild:lib-$(CONFIG_IOSTAT) += iostat.o13 14 10 //config:config IOSTAT 15 11 //config: bool "iostat" … … 18 14 //config: Report CPU and I/O statistics 19 15 16 //applet:IF_IOSTAT(APPLET(iostat, BB_DIR_BIN, BB_SUID_DROP)) 17 18 //kbuild:lib-$(CONFIG_IOSTAT) += iostat.o 19 20 20 #include "libbb.h" 21 #include <sys/utsname.h> /* Needstruct utsname */21 #include <sys/utsname.h> /* struct utsname */ 22 22 23 23 //#define debug(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__) … … 25 25 26 26 #define MAX_DEVICE_NAME 12 27 #define CURRENT 0 28 #define LAST 1 27 #define MAX_DEVICE_NAME_STR "12" 29 28 30 29 #if 1 … … 40 39 #endif 41 40 42 struct stats_cpu { 43 cputime_t cpu_user; 44 cputime_t cpu_nice; 45 cputime_t cpu_system; 46 cputime_t cpu_idle; 47 cputime_t cpu_iowait; 48 cputime_t cpu_steal; 49 cputime_t cpu_irq; 50 cputime_t cpu_softirq; 51 cputime_t cpu_guest; 41 enum { 42 STATS_CPU_USER, 43 STATS_CPU_NICE, 44 STATS_CPU_SYSTEM, 45 STATS_CPU_IDLE, 46 STATS_CPU_IOWAIT, 47 STATS_CPU_IRQ, 48 STATS_CPU_SOFTIRQ, 49 STATS_CPU_STEAL, 50 STATS_CPU_GUEST, 51 52 GLOBAL_UPTIME, 53 SMP_UPTIME, 54 55 N_STATS_CPU, 52 56 }; 53 57 54 struct stats_dev { 55 char dname[MAX_DEVICE_NAME]; 58 typedef struct { 59 cputime_t vector[N_STATS_CPU]; 60 } stats_cpu_t; 61 62 typedef struct { 63 stats_cpu_t *prev; 64 stats_cpu_t *curr; 65 cputime_t itv; 66 } stats_cpu_pair_t; 67 68 typedef struct { 56 69 unsigned long long rd_sectors; 57 70 unsigned long long wr_sectors; 58 71 unsigned long rd_ops; 59 72 unsigned long wr_ops; 60 }; 61 62 /* List of devices entered on the command line */ 63 struct device_list { 64 char dname[MAX_DEVICE_NAME]; 65 }; 73 } stats_dev_data_t; 74 75 typedef struct stats_dev { 76 struct stats_dev *next; 77 char dname[MAX_DEVICE_NAME + 1]; 78 stats_dev_data_t prev_data; 79 stats_dev_data_t curr_data; 80 } stats_dev_t; 66 81 67 82 /* Globals. Sort by size and access frequency. */ 68 83 struct globals { 69 84 smallint show_all; 70 unsigned devlist_i; /* Index to the list of devices */71 85 unsigned total_cpus; /* Number of CPUs */ 72 86 unsigned clk_tck; /* Number of clock ticks per second */ 73 struct device_list *dlist;74 st ruct stats_dev *saved_stats_dev;87 llist_t *dev_name_list; /* List of devices entered on the command line */ 88 stats_dev_t *stats_dev_list; 75 89 struct tm tmtime; 90 struct { 91 const char *str; 92 unsigned div; 93 } unit; 76 94 }; 77 95 #define G (*ptr_to_globals) 78 96 #define INIT_G() do { \ 79 97 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 98 G.unit.str = "Blk"; \ 99 G.unit.div = 1; \ 80 100 } while (0) 81 101 … … 102 122 static void print_header(void) 103 123 { 104 char buf[ 16];124 char buf[32]; 105 125 struct utsname uts; 106 126 107 if (uname(&uts) < 0)108 bb_perror_msg_and_die("uname"); 109 127 uname(&uts); /* never fails */ 128 129 /* Date representation for the current locale */ 110 130 strftime(buf, sizeof(buf), "%x", &G.tmtime); 111 131 112 printf("%s %s (%s) \t%s \t_%s_\t(% dCPU)\n\n",132 printf("%s %s (%s) \t%s \t_%s_\t(%u CPU)\n\n", 113 133 uts.sysname, uts.release, uts.nodename, 114 134 buf, uts.machine, G.total_cpus); … … 124 144 static void print_timestamp(void) 125 145 { 126 char buf[20]; 146 char buf[64]; 147 /* %x: date representation for the current locale */ 148 /* %X: time representation for the current locale */ 127 149 strftime(buf, sizeof(buf), "%x %X", &G.tmtime); 128 150 printf("%s\n", buf); 129 151 } 130 152 153 static cputime_t get_smp_uptime(void) 154 { 155 FILE *fp; 156 unsigned long sec, dec; 157 158 fp = xfopen_for_read("/proc/uptime"); 159 160 if (fscanf(fp, "%lu.%lu", &sec, &dec) != 2) 161 bb_error_msg_and_die("can't read '%s'", "/proc/uptime"); 162 163 fclose(fp); 164 165 return (cputime_t)sec * G.clk_tck + dec * G.clk_tck / 100; 166 } 167 131 168 /* Fetch CPU statistics from /proc/stat */ 132 static void get_cpu_statistics(st ruct stats_cpu*sc)169 static void get_cpu_statistics(stats_cpu_t *sc) 133 170 { 134 171 FILE *fp; … … 140 177 141 178 while (fgets(buf, sizeof(buf), fp)) { 142 /* Does the line starts with "cpu "? */ 143 if (starts_with_cpu(buf) && buf[3] == ' ') { 144 sscanf(buf + 4 + 1, 145 "%"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %" 146 FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u", 147 &sc->cpu_user, &sc->cpu_nice, &sc->cpu_system, 148 &sc->cpu_idle, &sc->cpu_iowait, &sc->cpu_irq, 149 &sc->cpu_softirq, &sc->cpu_steal, &sc->cpu_guest); 150 } 179 int i; 180 char *ibuf; 181 182 /* Does the line start with "cpu "? */ 183 if (!starts_with_cpu(buf) || buf[3] != ' ') { 184 continue; 185 } 186 ibuf = buf + 4; 187 for (i = STATS_CPU_USER; i <= STATS_CPU_GUEST; i++) { 188 ibuf = skip_whitespace(ibuf); 189 sscanf(ibuf, "%"FMT_DATA"u", &sc->vector[i]); 190 if (i != STATS_CPU_GUEST) { 191 sc->vector[GLOBAL_UPTIME] += sc->vector[i]; 192 } 193 ibuf = skip_non_whitespace(ibuf); 194 } 195 break; 196 } 197 198 if (this_is_smp()) { 199 sc->vector[SMP_UPTIME] = get_smp_uptime(); 151 200 } 152 201 153 202 fclose(fp); 154 }155 156 static cputime_t get_smp_uptime(void)157 {158 FILE *fp;159 char buf[sizeof(long)*3 * 2 + 4];160 unsigned long sec, dec;161 162 fp = xfopen_for_read("/proc/uptime");163 164 if (fgets(buf, sizeof(buf), fp))165 if (sscanf(buf, "%lu.%lu", &sec, &dec) != 2)166 bb_error_msg_and_die("can't read /proc/uptime");167 168 fclose(fp);169 170 return (cputime_t)sec * G.clk_tck + dec * G.clk_tck / 100;171 }172 173 /*174 * Obtain current uptime in jiffies.175 * Uptime is sum of individual CPUs' uptimes.176 */177 static cputime_t get_uptime(const struct stats_cpu *sc)178 {179 /* NB: Don't include cpu_guest, it is already in cpu_user */180 return sc->cpu_user + sc->cpu_nice + sc->cpu_system + sc->cpu_idle +181 + sc->cpu_iowait + sc->cpu_irq + sc->cpu_steal + sc->cpu_softirq;182 203 } 183 204 … … 220 241 } 221 242 222 static void print_stats_cpu_struct(const struct stats_cpu *p, 223 const struct stats_cpu *c, cputime_t itv) 224 { 225 printf(" %6.2f %6.2f %6.2f %6.2f %6.2f %6.2f\n", 226 percent_value(p->cpu_user , c->cpu_user , itv), 227 percent_value(p->cpu_nice , c->cpu_nice , itv), 228 percent_value(p->cpu_system + p->cpu_softirq + p->cpu_irq, 229 c->cpu_system + c->cpu_softirq + c->cpu_irq, itv), 230 percent_value(p->cpu_iowait , c->cpu_iowait , itv), 231 percent_value(p->cpu_steal , c->cpu_steal , itv), 232 percent_value(p->cpu_idle , c->cpu_idle , itv) 243 static void print_stats_cpu_struct(stats_cpu_pair_t *stats) 244 { 245 cputime_t *p = stats->prev->vector; 246 cputime_t *c = stats->curr->vector; 247 printf(" %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n", 248 percent_value(p[STATS_CPU_USER] , c[STATS_CPU_USER] , stats->itv), 249 percent_value(p[STATS_CPU_NICE] , c[STATS_CPU_NICE] , stats->itv), 250 percent_value(p[STATS_CPU_SYSTEM] + p[STATS_CPU_SOFTIRQ] + p[STATS_CPU_IRQ], 251 c[STATS_CPU_SYSTEM] + c[STATS_CPU_SOFTIRQ] + c[STATS_CPU_IRQ], stats->itv), 252 percent_value(p[STATS_CPU_IOWAIT], c[STATS_CPU_IOWAIT], stats->itv), 253 percent_value(p[STATS_CPU_STEAL] , c[STATS_CPU_STEAL] , stats->itv), 254 percent_value(p[STATS_CPU_IDLE] , c[STATS_CPU_IDLE] , stats->itv) 233 255 ); 234 256 } 235 257 236 static void print_stats_dev_struct(const struct stats_dev *p, 237 const struct stats_dev *c, cputime_t itv) 238 { 239 int unit = 1; 240 241 if (option_mask32 & OPT_k) 242 unit = 2; 243 else if (option_mask32 & OPT_m) 244 unit = 2048; 245 258 static void cpu_report(stats_cpu_pair_t *stats) 259 { 260 /* Always print a header */ 261 puts("avg-cpu: %user %nice %system %iowait %steal %idle"); 262 263 /* Print current statistics */ 264 print_stats_cpu_struct(stats); 265 } 266 267 static void print_stats_dev_struct(stats_dev_t *stats_dev, cputime_t itv) 268 { 269 stats_dev_data_t *p = &stats_dev->prev_data; 270 stats_dev_data_t *c = &stats_dev->curr_data; 246 271 if (option_mask32 & OPT_z) 247 272 if (p->rd_ops == c->rd_ops && p->wr_ops == c->wr_ops) 248 273 return; 249 274 250 printf("%-13s", c->dname); 251 printf(" %8.2f %12.2f %12.2f %10llu %10llu \n", 252 percent_value(p->rd_ops + p->wr_ops , 253 /**/ c->rd_ops + c->wr_ops , itv), 254 percent_value(p->rd_sectors, c->rd_sectors, itv) / unit, 255 percent_value(p->wr_sectors, c->wr_sectors, itv) / unit, 256 (c->rd_sectors - p->rd_sectors) / unit, 257 (c->wr_sectors - p->wr_sectors) / unit); 258 } 259 260 static void cpu_report(const struct stats_cpu *last, 261 const struct stats_cpu *cur, 262 cputime_t itv) 263 { 264 /* Always print a header */ 265 puts("avg-cpu: %user %nice %system %iowait %steal %idle"); 266 267 /* Print current statistics */ 268 print_stats_cpu_struct(last, cur, itv); 275 printf("%-13s %8.2f %12.2f %12.2f %10llu %10llu\n", 276 stats_dev->dname, 277 percent_value(p->rd_ops + p->wr_ops, c->rd_ops + c->wr_ops, itv), 278 percent_value(p->rd_sectors, c->rd_sectors, itv) / G.unit.div, 279 percent_value(p->wr_sectors, c->wr_sectors, itv) / G.unit.div, 280 (c->rd_sectors - p->rd_sectors) / G.unit.div, 281 (c->wr_sectors - p->wr_sectors) / G.unit.div 282 ); 269 283 } 270 284 271 285 static void print_devstat_header(void) 272 286 { 273 printf("Device: tps"); 274 275 if (option_mask32 & OPT_m) 276 puts(" MB_read/s MB_wrtn/s MB_read MB_wrtn"); 277 else if (option_mask32 & OPT_k) 278 puts(" kB_read/s kB_wrtn/s kB_read kB_wrtn"); 279 else 280 puts(" Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn"); 287 printf("Device:%15s%6s%s/s%6s%s/s%6s%s%6s%s\n", 288 "tps", 289 G.unit.str, "_read", G.unit.str, "_wrtn", 290 G.unit.str, "_read", G.unit.str, "_wrtn" 291 ); 281 292 } 282 293 … … 290 301 } 291 302 292 /* 293 * Return number of numbers on cmdline. 294 * Reasonable values are only 0 (no interval/count specified), 295 * 1 (interval specified) and 2 (both interval and count specified) 296 */ 297 static int numbers_on_cmdline(int argc, char *argv[]) 298 { 299 int sum = 0; 300 301 if (isdigit(argv[argc-1][0])) 302 sum++; 303 if (argc > 2 && isdigit(argv[argc-2][0])) 304 sum++; 305 306 return sum; 307 } 308 309 static int is_dev_in_dlist(const char *dev) 310 { 311 int i; 312 313 /* Go through the device list */ 314 for (i = 0; i < G.devlist_i; i++) 315 if (strcmp(G.dlist[i].dname, dev) == 0) 316 /* Found a match */ 317 return 1; 318 319 /* No match found */ 320 return 0; 303 static stats_dev_t *stats_dev_find_or_new(const char *dev_name) 304 { 305 stats_dev_t **curr = &G.stats_dev_list; 306 307 while (*curr != NULL) { 308 if (strcmp((*curr)->dname, dev_name) == 0) 309 return *curr; 310 curr = &(*curr)->next; 311 } 312 313 *curr = xzalloc(sizeof(stats_dev_t)); 314 strncpy((*curr)->dname, dev_name, MAX_DEVICE_NAME); 315 return *curr; 316 } 317 318 static void stats_dev_free(stats_dev_t *stats_dev) 319 { 320 if (stats_dev) { 321 stats_dev_free(stats_dev->next); 322 free(stats_dev); 323 } 321 324 } 322 325 323 326 static void do_disk_statistics(cputime_t itv) 324 327 { 328 char buf[128]; 329 char dev_name[MAX_DEVICE_NAME + 1]; 330 unsigned long long rd_sec_or_dummy; 331 unsigned long long wr_sec_or_dummy; 332 stats_dev_data_t *curr_data; 333 stats_dev_t *stats_dev; 325 334 FILE *fp; 326 335 int rc; 327 int i = 0;328 char buf[128];329 unsigned major, minor;330 unsigned long wr_ops, dummy; /* %*lu for suppress the conversion wouldn't work */331 unsigned long long rd_sec_or_wr_ops;332 unsigned long long rd_sec_or_dummy, wr_sec_or_dummy, wr_sec;333 struct stats_dev sd;334 336 335 337 fp = xfopen_for_read("/proc/diskstats"); 336 337 338 /* Read and possibly print stats from /proc/diskstats */ 338 339 while (fgets(buf, sizeof(buf), fp)) { 339 rc = sscanf(buf, "%u %u %s %lu %llu %llu %llu %lu %lu %llu %lu %lu %lu %lu", 340 &major, &minor, sd.dname, &sd.rd_ops, 341 &rd_sec_or_dummy, &rd_sec_or_wr_ops, &wr_sec_or_dummy, 342 &wr_ops, &dummy, &wr_sec, &dummy, &dummy, &dummy, &dummy); 343 344 switch (rc) { 345 case 14: 346 sd.wr_ops = wr_ops; 347 sd.rd_sectors = rd_sec_or_wr_ops; 348 sd.wr_sectors = wr_sec; 349 break; 350 case 7: 351 sd.rd_sectors = rd_sec_or_dummy; 352 sd.wr_ops = (unsigned long)rd_sec_or_wr_ops; 353 sd.wr_sectors = wr_sec_or_dummy; 354 break; 355 default: 356 break; 357 } 358 359 if (!G.devlist_i && !is_partition(sd.dname)) { 360 /* User didn't specify device */ 361 if (!G.show_all && !sd.rd_ops && !sd.wr_ops) { 362 /* Don't print unused device */ 340 sscanf(buf, "%*s %*s %"MAX_DEVICE_NAME_STR"s", dev_name); 341 if (G.dev_name_list) { 342 /* Is device name in list? */ 343 if (!llist_find_str(G.dev_name_list, dev_name)) 363 344 continue; 364 } 365 print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv); 366 G.saved_stats_dev[i] = sd; 367 i++; 368 } else { 369 /* Is device in device list? */ 370 if (is_dev_in_dlist(sd.dname)) { 371 /* Print current statistics */ 372 print_stats_dev_struct(&G.saved_stats_dev[i], &sd, itv); 373 G.saved_stats_dev[i] = sd; 374 i++; 375 } else 376 continue; 377 } 345 } else if (is_partition(dev_name)) { 346 continue; 347 } 348 349 stats_dev = stats_dev_find_or_new(dev_name); 350 curr_data = &stats_dev->curr_data; 351 352 rc = sscanf(buf, "%*s %*s %*s %lu %llu %llu %llu %lu %*s %llu", 353 &curr_data->rd_ops, 354 &rd_sec_or_dummy, 355 &curr_data->rd_sectors, 356 &wr_sec_or_dummy, 357 &curr_data->wr_ops, 358 &curr_data->wr_sectors); 359 if (rc != 6) { 360 curr_data->rd_sectors = rd_sec_or_dummy; 361 curr_data->wr_sectors = wr_sec_or_dummy; 362 //curr_data->rd_ops = ; 363 curr_data->wr_ops = (unsigned long)curr_data->rd_sectors; 364 } 365 366 if (!G.dev_name_list /* User didn't specify device */ 367 && !G.show_all 368 && curr_data->rd_ops == 0 369 && curr_data->wr_ops == 0 370 ) { 371 /* Don't print unused device */ 372 continue; 373 } 374 375 /* Print current statistics */ 376 print_stats_dev_struct(stats_dev, itv); 377 stats_dev->prev_data = *curr_data; 378 378 } 379 379 … … 388 388 /* Fetch current disk statistics */ 389 389 do_disk_statistics(itv); 390 }391 392 static void save_to_devlist(const char *dname)393 {394 int i;395 struct device_list *tmp = G.dlist;396 397 if (strncmp(dname, "/dev/", 5) == 0)398 /* We'll ignore prefix '/dev/' */399 dname += 5;400 401 /* Go through the list */402 for (i = 0; i < G.devlist_i; i++, tmp++)403 if (strcmp(tmp->dname, dname) == 0)404 /* Already in the list */405 return;406 407 /* Add device name to the list */408 strncpy(tmp->dname, dname, MAX_DEVICE_NAME - 1);409 410 /* Update device list index */411 G.devlist_i++;412 }413 414 static unsigned get_number_of_devices(void)415 {416 FILE *fp;417 char buf[128];418 int rv;419 unsigned n = 0;420 unsigned long rd_ops, wr_ops;421 char dname[MAX_DEVICE_NAME];422 423 fp = xfopen_for_read("/proc/diskstats");424 425 while (fgets(buf, sizeof(buf), fp)) {426 rv = sscanf(buf, "%*d %*d %s %lu %*u %*u %*u %lu",427 dname, &rd_ops, &wr_ops);428 if (rv == 2 || is_partition(dname))429 /* A partition */430 continue;431 if (!rd_ops && !wr_ops) {432 /* Unused device */433 if (!G.show_all)434 continue;435 }436 n++;437 }438 439 fclose(fp);440 return n;441 }442 443 static int number_of_ALL_on_cmdline(char **argv)444 {445 int alls = 0;446 447 /* Iterate over cmd line arguments, count "ALL" */448 while (*argv)449 if (strcmp(*argv++, "ALL") == 0)450 alls++;451 452 return alls;453 390 } 454 391 … … 457 394 //usage:#define iostat_full_usage "\n\n" 458 395 //usage: "Report CPU and I/O statistics\n" 459 //usage: "\nOptions:"460 396 //usage: "\n -c Show CPU utilization" 461 397 //usage: "\n -d Show device utilization" … … 466 402 467 403 int iostat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 468 int iostat_main(int argc , char **argv)469 { 470 int opt , dev_num;471 unsigned interval = 0;404 int iostat_main(int argc UNUSED_PARAM, char **argv) 405 { 406 int opt; 407 unsigned interval; 472 408 int count; 473 cputime_t global_uptime[2] = { 0 }; 474 cputime_t smp_uptime[2] = { 0 }; 475 cputime_t itv; 476 struct stats_cpu stats_cur, stats_last; 409 stats_cpu_t stats_data[2]; 410 smallint current_stats; 477 411 478 412 INIT_G(); 479 413 480 memset(&stats_ last, 0, sizeof(stats_last));414 memset(&stats_data, 0, sizeof(stats_data)); 481 415 482 416 /* Get number of clock ticks per sec */ … … 497 431 498 432 argv += optind; 499 argc -= optind;500 501 dev_num = argc - numbers_on_cmdline(argc, argv);502 /* We don't want to allocate space for 'ALL' */503 dev_num -= number_of_ALL_on_cmdline(argv);504 if (dev_num > 0)505 /* Make space for device list */506 G.dlist = xzalloc(sizeof(G.dlist[0]) * dev_num);507 433 508 434 /* Store device names into device list */ 509 435 while (*argv && !isdigit(*argv[0])) { 510 if (strcmp(*argv, "ALL") != 0) 436 if (strcmp(*argv, "ALL") != 0) { 511 437 /* If not ALL, save device name */ 512 save_to_devlist(*argv); 513 else 438 char *dev_name = skip_dev_pfx(*argv); 439 if (!llist_find_str(G.dev_name_list, dev_name)) { 440 llist_add_to(&G.dev_name_list, dev_name); 441 } 442 } else { 514 443 G.show_all = 1; 444 } 515 445 argv++; 516 446 } 517 447 448 interval = 0; 518 449 count = 1; 519 450 if (*argv) { … … 527 458 } 528 459 529 /* Allocate space for device stats */ 530 if (opt & OPT_d) { 531 G.saved_stats_dev = xzalloc(sizeof(G.saved_stats_dev[0]) * 532 (dev_num ? dev_num : get_number_of_devices()) 533 ); 534 } 460 if (opt & OPT_m) { 461 G.unit.str = " MB"; 462 G.unit.div = 2048; 463 } 464 465 if (opt & OPT_k) { 466 G.unit.str = " kB"; 467 G.unit.div = 2; 468 } 469 470 get_localtime(&G.tmtime); 535 471 536 472 /* Display header */ 537 473 print_header(); 538 474 475 current_stats = 0; 539 476 /* Main loop */ 540 477 for (;;) { 478 stats_cpu_pair_t stats; 479 480 stats.prev = &stats_data[current_stats ^ 1]; 481 stats.curr = &stats_data[current_stats]; 482 541 483 /* Fill the time structure */ 542 484 get_localtime(&G.tmtime); 543 485 544 486 /* Fetch current CPU statistics */ 545 get_cpu_statistics(&stats_cur); 546 547 /* Fetch current uptime */ 548 global_uptime[CURRENT] = get_uptime(&stats_cur); 487 get_cpu_statistics(stats.curr); 549 488 550 489 /* Get interval */ 551 itv = get_interval(global_uptime[LAST], global_uptime[CURRENT]); 490 stats.itv = get_interval( 491 stats.prev->vector[GLOBAL_UPTIME], 492 stats.curr->vector[GLOBAL_UPTIME] 493 ); 552 494 553 495 if (opt & OPT_t) … … 555 497 556 498 if (opt & OPT_c) { 557 cpu_report(&stats _last, &stats_cur, itv);499 cpu_report(&stats); 558 500 if (opt & OPT_d) 559 501 /* Separate outputs by a newline */ … … 563 505 if (opt & OPT_d) { 564 506 if (this_is_smp()) { 565 smp_uptime[CURRENT] = get_smp_uptime(); 566 itv = get_interval(smp_uptime[LAST], smp_uptime[CURRENT]); 567 smp_uptime[LAST] = smp_uptime[CURRENT]; 507 stats.itv = get_interval( 508 stats.prev->vector[SMP_UPTIME], 509 stats.curr->vector[SMP_UPTIME] 510 ); 568 511 } 569 dev_report(itv); 570 } 512 dev_report(stats.itv); 513 } 514 515 bb_putchar('\n'); 571 516 572 517 if (count > 0) { … … 575 520 } 576 521 577 /* Backup current stats */ 578 global_uptime[LAST] = global_uptime[CURRENT]; 579 stats_last = stats_cur; 580 581 bb_putchar('\n'); 522 /* Swap stats */ 523 current_stats ^= 1; 524 582 525 sleep(interval); 583 526 } 584 527 585 bb_putchar('\n');586 587 528 if (ENABLE_FEATURE_CLEAN_UP) { 529 llist_free(G.dev_name_list, NULL); 530 stats_dev_free(G.stats_dev_list); 588 531 free(&G); 589 free(G.dlist);590 free(G.saved_stats_dev);591 532 } 592 533 -
branches/3.2/mindi-busybox/procps/kill.c
r2725 r3232 8 8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 9 */ 10 11 //usage:#define kill_trivial_usage 12 //usage: "[-l] [-SIG] PID..." 13 //usage:#define kill_full_usage "\n\n" 14 //usage: "Send a signal (default: TERM) to given PIDs\n" 15 //usage: "\n -l List all signal names and numbers" 16 /* //usage: "\n -s SIG Yet another way of specifying SIG" */ 17 //usage: 18 //usage:#define kill_example_usage 19 //usage: "$ ps | grep apache\n" 20 //usage: "252 root root S [apache]\n" 21 //usage: "263 www-data www-data S [apache]\n" 22 //usage: "264 www-data www-data S [apache]\n" 23 //usage: "265 www-data www-data S [apache]\n" 24 //usage: "266 www-data www-data S [apache]\n" 25 //usage: "267 www-data www-data S [apache]\n" 26 //usage: "$ kill 252\n" 27 //usage: 28 //usage:#define killall_trivial_usage 29 //usage: "[-l] [-q] [-SIG] PROCESS_NAME..." 30 //usage:#define killall_full_usage "\n\n" 31 //usage: "Send a signal (default: TERM) to given processes\n" 32 //usage: "\n -l List all signal names and numbers" 33 /* //usage: "\n -s SIG Yet another way of specifying SIG" */ 34 //usage: "\n -q Don't complain if no processes were killed" 35 //usage: 36 //usage:#define killall_example_usage 37 //usage: "$ killall apache\n" 38 //usage: 39 //usage:#define killall5_trivial_usage 40 //usage: "[-l] [-SIG] [-o PID]..." 41 //usage:#define killall5_full_usage "\n\n" 42 //usage: "Send a signal (default: TERM) to all processes outside current session\n" 43 //usage: "\n -l List all signal names and numbers" 44 //usage: "\n -o PID Don't signal this PID" 45 /* //usage: "\n -s SIG Yet another way of specifying SIG" */ 10 46 11 47 #include "libbb.h" … … 128 164 sid = getsid(pid); 129 165 /* Stop all processes */ 130 kill(-1, SIGSTOP); 166 if (signo != SIGSTOP && signo != SIGCONT) 167 kill(-1, SIGSTOP); 131 168 /* Signal all processes except those in our session */ 132 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID)) ) {169 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID)) != NULL) { 133 170 int i; 134 171 135 172 if (p->sid == (unsigned)sid 136 173 || p->pid == (unsigned)pid 137 || p->pid == 1) 174 || p->pid == 1 175 ) { 138 176 continue; 177 } 139 178 140 179 /* All remaining args must be -o PID options. … … 166 205 resume: 167 206 /* And let them continue */ 168 kill(-1, SIGCONT); 207 if (signo != SIGSTOP && signo != SIGCONT) 208 kill(-1, SIGCONT); 169 209 return ret; 170 210 } … … 207 247 /* Looks like they want to do a kill. Do that */ 208 248 while (arg) { 209 /* Support shell 'space' trick */ 210 if (arg[0] == ' ') 211 arg++; 249 #if ENABLE_ASH || ENABLE_HUSH 250 /* 251 * We need to support shell's "hack formats" of 252 * " -PRGP_ID" (yes, with a leading space) 253 * and " PID1 PID2 PID3" (with degenerate case "") 254 */ 255 while (*arg != '\0') { 256 char *end; 257 if (*arg == ' ') 258 arg++; 259 pid = bb_strtoi(arg, &end, 10); 260 if (errno && (errno != EINVAL || *end != ' ')) { 261 bb_error_msg("invalid number '%s'", arg); 262 errors++; 263 break; 264 } 265 if (kill(pid, signo) != 0) { 266 bb_perror_msg("can't kill pid %d", (int)pid); 267 errors++; 268 } 269 arg = end; /* can only point to ' ' or '\0' now */ 270 } 271 #else 212 272 pid = bb_strtoi(arg, NULL, 10); 213 273 if (errno) { … … 218 278 errors++; 219 279 } 280 #endif 220 281 arg = *++argv; 221 282 } -
branches/3.2/mindi-busybox/procps/mpstat.c
r2725 r3232 8 8 */ 9 9 10 //applet:IF_MPSTAT(APPLET(mpstat, _BB_DIR_BIN, _BB_SUID_DROP))10 //applet:IF_MPSTAT(APPLET(mpstat, BB_DIR_BIN, BB_SUID_DROP)) 11 11 12 12 //kbuild:lib-$(CONFIG_MPSTAT) += mpstat.o … … 37 37 * anything smaller than 10 chars looks ugly for /proc/softirqs stats. 38 38 */ 39 #define INTRATE_SCRWIDTH 1039 #define INTRATE_SCRWIDTH 10 40 40 #define INTRATE_SCRWIDTH_STR "10" 41 41 42 42 /* System files */ 43 #define SYSFS_DEVCPU "/sys/devices/system/cpu"44 43 #define PROCFS_STAT "/proc/stat" 45 44 #define PROCFS_INTERRUPTS "/proc/interrupts" … … 846 845 //usage:#define mpstat_full_usage "\n\n" 847 846 //usage: "Per-processor statistics\n" 848 //usage: "\nOptions:"849 847 //usage: "\n -A Same as -I ALL -u -P ALL" 850 848 //usage: "\n -I SUM|CPU|ALL|SCPU Report interrupt statistics" -
branches/3.2/mindi-busybox/procps/nmeter.c
r2725 r3232 6 6 * Contact me: vda.linux@googlemail.com 7 7 */ 8 9 //config:config NMETER 10 //config: bool "nmeter" 11 //config: default y 12 //config: help 13 //config: Prints selected system stats continuously, one line per update. 14 15 //applet:IF_NMETER(APPLET(nmeter, BB_DIR_USR_BIN, BB_SUID_DROP)) 16 17 //kbuild:lib-$(CONFIG_NMETER) += nmeter.o 18 19 //usage:#define nmeter_trivial_usage 20 //usage: "[-d MSEC] FORMAT_STRING" 21 //usage:#define nmeter_full_usage "\n\n" 22 //usage: "Monitor system in real time" 23 //usage: "\n" 24 //usage: "\n -d MSEC Milliseconds between updates (default:1000)" 25 //usage: "\n" 26 //usage: "\nFormat specifiers:" 27 //usage: "\n %Nc or %[cN] CPU. N - bar size (default:10)" 28 //usage: "\n (displays: S:system U:user N:niced D:iowait I:irq i:softirq)" 29 //usage: "\n %[nINTERFACE] Network INTERFACE" 30 //usage: "\n %m Allocated memory" 31 //usage: "\n %[mf] Free memory" 32 //usage: "\n %[mt] Total memory" 33 //usage: "\n %s Allocated swap" 34 //usage: "\n %f Number of used file descriptors" 35 //usage: "\n %Ni Total/specific IRQ rate" 36 //usage: "\n %x Context switch rate" 37 //usage: "\n %p Forks" 38 //usage: "\n %[pn] # of processes" 39 //usage: "\n %b Block io" 40 //usage: "\n %Nt Time (with N decimal points)" 41 //usage: "\n %r Print <cr> instead of <lf> at EOL" 8 42 9 43 //TODO: … … 238 272 239 273 // Parses /proc/diskstats 240 // 1 2 3 4 56(rd) 7 8 9 10(wr) 11 12 13 14274 // 1 2 3 4 5 6(rd) 7 8 9 10(wr) 11 12 13 14 241 275 // 3 0 hda 51292 14441 841783 926052 25717 79650 843256 3029804 0 148459 3956933 242 276 // 3 1 hda1 0 0 0 0 <- ignore if only 4 fields 277 // Linux 3.0 (maybe earlier) started printing full stats for hda1 too. 278 // Had to add code which skips such devices. 243 279 static int rdval_diskstats(const char* p, ullong *vec) 244 280 { 245 ullong rd = rd; // for compiler 246 int indexline = 0; 281 char devname[32]; 282 unsigned devname_len = 0; 283 int value_idx = 0; 284 247 285 vec[0] = 0; 248 286 vec[1] = 0; 249 287 while (1) { 250 indexline++; 251 while (*p == ' ' || *p == '\t') p++; 252 if (*p == '\0') break; 288 value_idx++; 289 while (*p == ' ' || *p == '\t') 290 p++; 291 if (*p == '\0') 292 break; 253 293 if (*p == '\n') { 254 indexline= 0;294 value_idx = 0; 255 295 p++; 256 296 continue; 257 297 } 258 if (indexline == 6) { 259 rd = strtoull(p, NULL, 10); 260 } else if (indexline == 10) { 261 vec[0] += rd; // TODO: *sectorsize (don't know how to find out sectorsize) 298 if (value_idx == 3) { 299 char *end = strchrnul(p, ' '); 300 /* If this a hda1-like device (same prefix as last one + digit)? */ 301 if (devname_len && strncmp(devname, p, devname_len) == 0 && isdigit(p[devname_len])) { 302 p = end; 303 goto skip_line; /* skip entire line */ 304 } 305 /* It is not. Remember the name for future checks */ 306 devname_len = end - p; 307 if (devname_len > sizeof(devname)-1) 308 devname_len = sizeof(devname)-1; 309 strncpy(devname, p, devname_len); 310 /* devname[devname_len] = '\0'; - not really needed */ 311 p = end; 312 } else 313 if (value_idx == 6) { 314 // TODO: *sectorsize (don't know how to find out sectorsize) 315 vec[0] += strtoull(p, NULL, 10); 316 } else 317 if (value_idx == 10) { 318 // TODO: *sectorsize (don't know how to find out sectorsize) 262 319 vec[1] += strtoull(p, NULL, 10); 263 while (*p != '\n' && *p != '\0') p++; 320 skip_line: 321 while (*p != '\n' && *p != '\0') 322 p++; 264 323 continue; 265 324 } 266 while (*p > ' ') p++; // skip over value 325 while ((unsigned char)(*p) > ' ') // skip over value 326 p++; 267 327 } 268 328 return 0; … … 770 830 typedef s_stat* init_func(const char *param); 771 831 832 // Deprecated %NNNd is to be removed, -d MSEC supersedes it 772 833 static const char options[] ALIGN1 = "ncmsfixptbdr"; 773 834 static init_func *const init_functions[] = { … … 793 854 s_stat *last = NULL; 794 855 s_stat *s; 856 char *opt_d; 795 857 char *cur, *prev; 796 858 … … 798 860 799 861 xchdir("/proc"); 800 801 if (!argv[1])802 bb_show_usage();803 862 804 863 if (open_read_close("version", buf, sizeof(buf)-1) > 0) { … … 807 866 } 808 867 809 // Can use argv[1] directly, but this will mess up 868 if (getopt32(argv, "d:", &opt_d)) 869 init_delay(opt_d); 870 argv += optind; 871 872 if (!argv[0]) 873 bb_show_usage(); 874 875 // Can use argv[0] directly, but this will mess up 810 876 // parameters as seen by e.g. ps. Making a copy... 811 cur = xstrdup(argv[ 1]);877 cur = xstrdup(argv[0]); 812 878 while (1) { 813 879 char *param, *p; -
branches/3.2/mindi-busybox/procps/pgrep.c
r2725 r3232 7 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 8 */ 9 10 //usage:#define pgrep_trivial_usage 11 //usage: "[-flnovx] [-s SID|-P PPID|PATTERN]" 12 //usage:#define pgrep_full_usage "\n\n" 13 //usage: "Display process(es) selected by regex PATTERN\n" 14 //usage: "\n -l Show command name too" 15 //usage: "\n -f Match against entire command line" 16 //usage: "\n -n Show the newest process only" 17 //usage: "\n -o Show the oldest process only" 18 //usage: "\n -v Negate the match" 19 //usage: "\n -x Match whole name (not substring)" 20 //usage: "\n -s Match session ID (0 for current)" 21 //usage: "\n -P Match parent process ID" 22 //usage: 23 //usage:#define pkill_trivial_usage 24 //usage: "[-l|-SIGNAL] [-fnovx] [-s SID|-P PPID|PATTERN]" 25 //usage:#define pkill_full_usage "\n\n" 26 //usage: "Send a signal to process(es) selected by regex PATTERN\n" 27 //usage: "\n -l List all signals" 28 //usage: "\n -f Match against entire command line" 29 //usage: "\n -n Signal the newest process only" 30 //usage: "\n -o Signal the oldest process only" 31 //usage: "\n -v Negate the match" 32 //usage: "\n -x Match whole name (not substring)" 33 //usage: "\n -s Match session ID (0 for current)" 34 //usage: "\n -P Match parent process ID" 35 9 36 #include "libbb.h" 10 37 #include "xregex.h" … … 102 129 103 130 if (argv[0]) 104 xregcomp(&re_buffer, argv[0], 0);131 xregcomp(&re_buffer, argv[0], REG_EXTENDED | REG_NOSUB); 105 132 106 133 matched_pid = 0; -
branches/3.2/mindi-busybox/procps/pidof.c
r2725 r3232 7 7 * Licensed under GPLv2, see file LICENSE in this source tree. 8 8 */ 9 10 //usage:#if (ENABLE_FEATURE_PIDOF_SINGLE || ENABLE_FEATURE_PIDOF_OMIT) 11 //usage:#define pidof_trivial_usage 12 //usage: "[OPTIONS] [NAME]..." 13 //usage:#define USAGE_PIDOF "\n" 14 //usage:#else 15 //usage:#define pidof_trivial_usage 16 //usage: "[NAME]..." 17 //usage:#define USAGE_PIDOF /* none */ 18 //usage:#endif 19 //usage:#define pidof_full_usage "\n\n" 20 //usage: "List PIDs of all processes with names that match NAMEs" 21 //usage: USAGE_PIDOF 22 //usage: IF_FEATURE_PIDOF_SINGLE( 23 //usage: "\n -s Show only one PID" 24 //usage: ) 25 //usage: IF_FEATURE_PIDOF_OMIT( 26 //usage: "\n -o PID Omit given pid" 27 //usage: "\n Use %PPID to omit pid of pidof's parent" 28 //usage: ) 29 //usage: 30 //usage:#define pidof_example_usage 31 //usage: "$ pidof init\n" 32 //usage: "1\n" 33 //usage: IF_FEATURE_PIDOF_OMIT( 34 //usage: "$ pidof /bin/sh\n20351 5973 5950\n") 35 //usage: IF_FEATURE_PIDOF_OMIT( 36 //usage: "$ pidof /bin/sh -o %PPID\n20351 5950") 9 37 10 38 #include "libbb.h" -
branches/3.2/mindi-busybox/procps/pmap.c
r2725 r3232 9 9 */ 10 10 11 //applet:IF_PMAP(APPLET(pmap, _BB_DIR_USR_BIN, _BB_SUID_DROP))12 //kbuild:lib-$(CONFIG_PMAP) += pmap.o13 14 11 //config:config PMAP 15 12 //config: bool "pmap" … … 18 15 //config: Display processes' memory mappings. 19 16 17 //applet:IF_PMAP(APPLET(pmap, BB_DIR_USR_BIN, BB_SUID_DROP)) 18 //kbuild:lib-$(CONFIG_PMAP) += pmap.o 19 20 20 //usage:#define pmap_trivial_usage 21 //usage: "[-x ][-q] PID"21 //usage: "[-xq] PID" 22 22 //usage:#define pmap_full_usage "\n\n" 23 //usage: "Display detailed pr ecesses' memory usage\n"24 //usage: "\nOptions:"25 //usage: "\n -x show details"26 //usage: "\n -q quiet"23 //usage: "Display detailed process memory usage" 24 //usage: "\n" 25 //usage: "\n -x Show details" 26 //usage: "\n -q Quiet" 27 27 28 28 #include "libbb.h" -
branches/3.2/mindi-busybox/procps/powertop.c
r2725 r3232 10 10 */ 11 11 12 //applet:IF_POWERTOP(APPLET(powertop, _BB_DIR_BIN, _BB_SUID_DROP))12 //applet:IF_POWERTOP(APPLET(powertop, BB_DIR_USR_SBIN, BB_SUID_DROP)) 13 13 14 14 //kbuild:lib-$(CONFIG_POWERTOP) += powertop.o … … 394 394 char line[15 + 3 + 128]; 395 395 int n; 396 ullong totalticks;397 396 FILE *fp; 398 397 399 398 buf[0] = '\0'; 400 totalticks = 0;401 399 402 400 n = 0; … … 496 494 */ 497 495 static void cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, 498 496 unsigned int *edx) 499 497 { 500 498 /* EAX value specifies what information to return */ … … 653 651 bb_putchar('\n'); 654 652 bb_error_msg("no stats available; run as root or" 655 " enable the cpufreq_stats module");653 " enable the timer_stats module"); 656 654 } 657 655 } -
branches/3.2/mindi-busybox/procps/ps.c
r2725 r3232 10 10 */ 11 11 12 //usage:#if ENABLE_DESKTOP 13 //usage: 14 //usage:#define ps_trivial_usage 15 //usage: "[-o COL1,COL2=HEADER]" IF_FEATURE_SHOW_THREADS(" [-T]") 16 //usage:#define ps_full_usage "\n\n" 17 //usage: "Show list of processes\n" 18 //usage: "\n -o COL1,COL2=HEADER Select columns for display" 19 //usage: IF_FEATURE_SHOW_THREADS( 20 //usage: "\n -T Show threads" 21 //usage: ) 22 //usage: 23 //usage:#else /* !ENABLE_DESKTOP */ 24 //usage: 25 //usage:#if !ENABLE_SELINUX && !ENABLE_FEATURE_PS_WIDE 26 //usage:#define USAGE_PS "\nThis version of ps accepts no options" 27 //usage:#else 28 //usage:#define USAGE_PS "" 29 //usage:#endif 30 //usage: 31 //usage:#define ps_trivial_usage 32 //usage: "" 33 //usage:#define ps_full_usage "\n\n" 34 //usage: "Show list of processes\n" 35 //usage: USAGE_PS 36 //usage: IF_SELINUX( 37 //usage: "\n -Z Show selinux context" 38 //usage: ) 39 //usage: IF_FEATURE_PS_WIDE( 40 //usage: "\n w Wide output" 41 //usage: ) 42 //usage: IF_FEATURE_PS_LONG( 43 //usage: "\n l Long output" 44 //usage: ) 45 //usage: IF_FEATURE_SHOW_THREADS( 46 //usage: "\n T Show threads" 47 //usage: ) 48 //usage: 49 //usage:#endif /* ENABLE_DESKTOP */ 50 //usage: 51 //usage:#define ps_example_usage 52 //usage: "$ ps\n" 53 //usage: " PID Uid Gid State Command\n" 54 //usage: " 1 root root S init\n" 55 //usage: " 2 root root S [kflushd]\n" 56 //usage: " 3 root root S [kupdate]\n" 57 //usage: " 4 root root S [kpiod]\n" 58 //usage: " 5 root root S [kswapd]\n" 59 //usage: " 742 andersen andersen S [bash]\n" 60 //usage: " 743 andersen andersen S -bash\n" 61 //usage: " 745 root root S [getty]\n" 62 //usage: " 2990 andersen andersen R ps\n" 63 12 64 #include "libbb.h" 65 #ifdef __linux__ 66 # include <sys/sysinfo.h> 67 #endif 13 68 14 69 /* Absolute maximum on output line length */ 15 70 enum { MAX_WIDTH = 2*1024 }; 16 71 72 #if ENABLE_FEATURE_PS_TIME || ENABLE_FEATURE_PS_LONG 73 static long get_uptime(void) 74 { 75 #ifdef __linux__ 76 struct sysinfo info; 77 if (sysinfo(&info) < 0) 78 return 0; 79 return info.uptime; 80 #elif 1 81 char buf[64]; 82 long uptime; 83 if (open_read_close("/proc/uptime", buf, sizeof(buf)) <= 0) 84 bb_perror_msg_and_die("can't read %s", "/proc/uptime"); 85 buf[sizeof(buf)-1] = '\0'; 86 sscanf(buf, "%l", &uptime); 87 return uptime; 88 #else 89 struct timespec ts; 90 if (clock_gettime(CLOCK_MONOTONIC, &ts) < 0) 91 return 0; 92 return ts.tv_sec; 93 #endif 94 } 95 #endif 96 17 97 #if ENABLE_DESKTOP 18 98 19 99 #include <sys/times.h> /* for times() */ 20 100 #ifndef AT_CLKTCK 21 #define AT_CLKTCK 17 22 #endif 23 24 25 #if ENABLE_SELINUX 26 #define SELINUX_O_PREFIX "label," 27 #define DEFAULT_O_STR (SELINUX_O_PREFIX "pid,user" IF_FEATURE_PS_TIME(",time") ",args") 28 #else 29 #define DEFAULT_O_STR ("pid,user" IF_FEATURE_PS_TIME(",time") ",args") 30 #endif 31 101 # define AT_CLKTCK 17 102 #endif 103 104 /* TODO: 105 * http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html 106 * specifies (for XSI-conformant systems) following default columns 107 * (l and f mark columns shown with -l and -f respectively): 108 * F l Flags (octal and additive) associated with the process (??) 109 * S l The state of the process 110 * UID f,l The user ID; the login name is printed with -f 111 * PID The process ID 112 * PPID f,l The parent process 113 * C f,l Processor utilization 114 * PRI l The priority of the process; higher numbers mean lower priority 115 * NI l Nice value 116 * ADDR l The address of the process 117 * SZ l The size in blocks of the core image of the process 118 * WCHAN l The event for which the process is waiting or sleeping 119 * STIME f Starting time of the process 120 * TTY The controlling terminal for the process 121 * TIME The cumulative execution time for the process 122 * CMD The command name; the full command line is shown with -f 123 */ 32 124 typedef struct { 33 125 uint16_t width; … … 49 141 unsigned long long seconds_since_boot; 50 142 #endif 51 char default_o[sizeof(DEFAULT_O_STR)];52 143 } FIX_ALIASING; 53 144 #define G (*(struct globals*)&bb_common_bufsiz1) … … 60 151 #define kernel_HZ (G.kernel_HZ ) 61 152 #define seconds_since_boot (G.seconds_since_boot) 62 #define default_o (G.default_o )63 153 #define INIT_G() do { } while (0) 64 154 … … 69 159 ptrdiff_t *ep = (ptrdiff_t *) environ; 70 160 71 while (*ep++); 161 while (*ep++) 162 continue; 72 163 while (*ep) { 73 164 if (ep[0] == findme) { … … 132 223 static unsigned get_kernel_HZ(void) 133 224 { 134 //char buf[64];135 struct sysinfo info;136 225 137 226 if (kernel_HZ) … … 143 232 kernel_HZ = get_HZ_by_waiting(); 144 233 145 //if (open_read_close("/proc/uptime", buf, sizeof(buf)) <= 0) 146 // bb_perror_msg_and_die("can't read %s", "/proc/uptime"); 147 //buf[sizeof(buf)-1] = '\0'; 148 ///sscanf(buf, "%llu", &seconds_since_boot); 149 sysinfo(&info); 150 seconds_since_boot = info.uptime; 234 seconds_since_boot = get_uptime(); 151 235 152 236 return kernel_HZ; … … 185 269 } 186 270 271 static void func_state(char *buf, int size, const procps_status_t *ps) 272 { 273 safe_strncpy(buf, ps->state, size+1); 274 } 275 187 276 static void func_args(char *buf, int size, const procps_status_t *ps) 188 277 { … … 301 390 302 391 static const ps_out_t out_spec[] = { 303 / / Mandated by POSIX:392 /* Mandated by http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html: */ 304 393 { 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID }, 305 394 { 8 , "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID }, … … 323 412 { 6 , "tty" ,"TT" ,func_tty ,PSSCAN_TTY }, 324 413 { 4 , "vsz" ,"VSZ" ,func_vsz ,PSSCAN_VSZ }, 325 // Not mandated by POSIX, but useful: 414 /* Not mandated, but useful: */ 415 { 4 , "stat" ,"STAT" ,func_state ,PSSCAN_STATE }, 326 416 { 4 , "rss" ,"RSS" ,func_rss ,PSSCAN_RSS }, 327 417 #if ENABLE_SELINUX … … 460 550 } 461 551 552 #if ENABLE_SELINUX 553 # define SELINUX_O_PREFIX "label," 554 # define DEFAULT_O_STR (SELINUX_O_PREFIX "pid,user" IF_FEATURE_PS_TIME(",time") ",args") 555 #else 556 # define DEFAULT_O_STR ("pid,user" IF_FEATURE_PS_TIME(",time") ",args") 557 #endif 558 462 559 int ps_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 463 560 int ps_main(int argc UNUSED_PARAM, char **argv) … … 465 562 procps_status_t *p; 466 563 llist_t* opt_o = NULL; 564 char default_o[sizeof(DEFAULT_O_STR)]; 467 565 int opt; 468 566 enum { … … 502 600 } while (opt_o); 503 601 } else { 504 /* Below: parse_o() needs char*, NOT const char* ...*/602 /* Below: parse_o() needs char*, NOT const char*, can't give it default_o */ 505 603 #if ENABLE_SELINUX 506 604 if (!(opt & OPT_Z) || !is_selinux_enabled()) { … … 552 650 OPT_Z = (1 << 0) * ENABLE_SELINUX, 553 651 OPT_T = (1 << ENABLE_SELINUX) * ENABLE_FEATURE_SHOW_THREADS, 652 OPT_l = (1 << ENABLE_SELINUX) * (1 << ENABLE_FEATURE_SHOW_THREADS) * ENABLE_FEATURE_PS_LONG, 554 653 }; 654 #if ENABLE_FEATURE_PS_LONG 655 time_t now = now; 656 long uptime; 657 #endif 658 /* If we support any options, parse argv */ 659 #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE || ENABLE_FEATURE_PS_LONG 555 660 int opts = 0; 556 /* If we support any options, parse argv */557 #if ENABLE_SELINUX || ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_PS_WIDE558 661 # if ENABLE_FEATURE_PS_WIDE 559 662 /* -w is a bit complicated */ 560 663 int w_count = 0; 561 664 opt_complementary = "-:ww"; 562 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")"w", &w_count); 665 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l") 666 "w", &w_count); 563 667 /* if w is given once, GNU ps sets the width to 132, 564 668 * if w is given more than once, it is "unlimited" … … 575 679 /* -w is not supported, only -Z and/or -T */ 576 680 opt_complementary = "-"; 577 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T") );681 opts = getopt32(argv, IF_SELINUX("Z")IF_FEATURE_SHOW_THREADS("T")IF_FEATURE_PS_LONG("l")); 578 682 # endif 579 #endif 580 581 #if ENABLE_SELINUX 683 684 # if ENABLE_SELINUX 582 685 if ((opts & OPT_Z) && is_selinux_enabled()) { 583 686 psscan_flags = PSSCAN_PID | PSSCAN_CONTEXT … … 585 688 puts(" PID CONTEXT STAT COMMAND"); 586 689 } else 587 #endif 588 { 690 # endif 691 if (opts & OPT_l) { 692 psscan_flags = PSSCAN_STATE | PSSCAN_UIDGID | PSSCAN_PID | PSSCAN_PPID 693 | PSSCAN_TTY | PSSCAN_STIME | PSSCAN_UTIME | PSSCAN_COMM 694 | PSSCAN_VSZ | PSSCAN_RSS; 695 /* http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ps.html 696 * mandates for -l: 697 * -F Flags (?) 698 * S State 699 * UID,PID,PPID 700 * -C CPU usage 701 * -PRI The priority of the process; higher numbers mean lower priority 702 * -NI Nice value 703 * -ADDR The address of the process (?) 704 * SZ The size in blocks of the core image 705 * -WCHAN The event for which the process is waiting or sleeping 706 * TTY 707 * TIME The cumulative execution time 708 * CMD 709 * We don't show fields marked with '-'. 710 * We show VSZ and RSS instead of SZ. 711 * We also show STIME (standard says that -f shows it, -l doesn't). 712 */ 713 puts("S UID PID PPID VSZ RSS TTY STIME TIME CMD"); 714 # if ENABLE_FEATURE_PS_LONG 715 now = time(NULL); 716 uptime = get_uptime(); 717 # endif 718 } 719 else { 589 720 puts(" PID USER VSZ STAT COMMAND"); 590 721 } … … 592 723 psscan_flags |= PSSCAN_TASKS; 593 724 } 725 #endif 594 726 595 727 p = NULL; … … 605 737 #endif 606 738 { 607 const char *user = get_cached_username(p->uid); 608 //if (p->vsz == 0) 609 // len = printf("%5u %-8.8s %s ", 610 // p->pid, user, p->state); 611 //else 739 char buf6[6]; 740 smart_ulltoa5(p->vsz, buf6, " mgtpezy"); 741 buf6[5] = '\0'; 742 #if ENABLE_FEATURE_PS_LONG 743 if (opts & OPT_l) { 744 char bufr[6], stime_str[6]; 745 char tty[2 * sizeof(int)*3 + 2]; 746 char *endp; 747 unsigned sut = (p->stime + p->utime) / 100; 748 unsigned elapsed = uptime - (p->start_time / 100); 749 time_t start = now - elapsed; 750 struct tm *tm = localtime(&start); 751 752 smart_ulltoa5(p->rss, bufr, " mgtpezy"); 753 bufr[5] = '\0'; 754 755 if (p->tty_major == 136) 756 /* It should be pts/N, not ptsN, but N > 9 757 * will overflow field width... 758 */ 759 endp = stpcpy(tty, "pts"); 760 else 761 if (p->tty_major == 4) { 762 endp = stpcpy(tty, "tty"); 763 if (p->tty_minor >= 64) { 764 p->tty_minor -= 64; 765 *endp++ = 'S'; 766 } 767 } 768 else 769 endp = tty + sprintf(tty, "%d:", p->tty_major); 770 strcpy(endp, utoa(p->tty_minor)); 771 772 strftime(stime_str, 6, (elapsed >= (24 * 60 * 60)) ? "%b%d" : "%H:%M", tm); 773 stime_str[5] = '\0'; 774 // S UID PID PPID VSZ RSS TTY STIME TIME CMD 775 len = printf("%c %5u %5u %5u %5s %5s %-5s %s %02u:%02u:%02u ", 776 p->state[0], p->uid, p->pid, p->ppid, buf6, bufr, tty, 777 stime_str, sut / 3600, (sut % 3600) / 60, sut % 60); 778 } else 779 #endif 612 780 { 613 char buf6[6]; 614 smart_ulltoa5(p->vsz, buf6, " mgtpezy"); 615 buf6[5] = '\0'; 781 const char *user = get_cached_username(p->uid); 616 782 len = printf("%5u %-8.8s %s %s ", 617 783 p->pid, user, buf6, p->state); -
branches/3.2/mindi-busybox/procps/renice.c
r2725 r3232 19 19 * following IDs (if any). Multiple switches are allowed. 20 20 */ 21 22 //usage:#define renice_trivial_usage 23 //usage: "{{-n INCREMENT} | PRIORITY} [[-p | -g | -u] ID...]" 24 //usage:#define renice_full_usage "\n\n" 25 //usage: "Change scheduling priority for a running process\n" 26 //usage: "\n -n Adjust current nice value (smaller is faster)" 27 //usage: "\n -p Process id(s) (default)" 28 //usage: "\n -g Process group id(s)" 29 //usage: "\n -u Process user name(s) and/or id(s)" 21 30 22 31 #include "libbb.h" -
branches/3.2/mindi-busybox/procps/smemcap.c
r2725 r3232 9 9 */ 10 10 11 //applet:IF_SMEMCAP(APPLET(smemcap, _BB_DIR_USR_BIN, _BB_SUID_DROP))11 //applet:IF_SMEMCAP(APPLET(smemcap, BB_DIR_USR_BIN, BB_SUID_DROP)) 12 12 13 13 //kbuild:lib-$(CONFIG_SMEMCAP) += smemcap.o … … 21 21 22 22 #include "libbb.h" 23 #include " archive.h"23 #include "bb_archive.h" 24 24 25 25 struct fileblock { -
branches/3.2/mindi-busybox/procps/sysctl.c
r2725 r3232 12 12 */ 13 13 14 //usage:#define sysctl_trivial_usage 15 //usage: "[OPTIONS] [KEY[=VALUE]]..." 16 //usage:#define sysctl_full_usage "\n\n" 17 //usage: "Show/set kernel parameters\n" 18 //usage: "\n -e Don't warn about unknown keys" 19 //usage: "\n -n Don't show key names" 20 //usage: "\n -a Show all values" 21 /* Same as -a, no need to show it */ 22 /* //usage: "\n -A Show all values in table form" */ 23 //usage: "\n -w Set values" 24 //usage: "\n -p FILE Set values from FILE (default /etc/sysctl.conf)" 25 //usage: "\n -q Set values silently" 26 //usage: 27 //usage:#define sysctl_example_usage 28 //usage: "sysctl [-n] [-e] variable...\n" 29 //usage: "sysctl [-n] [-e] [-q] -w variable=value...\n" 30 //usage: "sysctl [-n] [-e] -a\n" 31 //usage: "sysctl [-n] [-e] [-q] -p file (default /etc/sysctl.conf)\n" 32 //usage: "sysctl [-n] [-e] -A\n" 33 14 34 #include "libbb.h" 15 35 … … 20 40 FLAG_SHOW_ALL = 1 << 3, 21 41 FLAG_PRELOAD_FILE = 1 << 4, 42 /* TODO: procps 3.2.8 seems to not require -w for KEY=VAL to work: */ 22 43 FLAG_WRITE = 1 << 5, 44 FLAG_QUIET = 1 << 6, 23 45 }; 24 #define OPTION_STR "neAapw "46 #define OPTION_STR "neAapwq" 25 47 26 48 static void sysctl_dots_to_slashes(char *name) … … 127 149 xwrite_str(fd, value); 128 150 close(fd); 129 if (option_mask32 & FLAG_SHOW_KEYS) 130 printf("%s = ", outname); 131 puts(value); 151 if (!(option_mask32 & FLAG_QUIET)) { 152 if (option_mask32 & FLAG_SHOW_KEYS) 153 printf("%s = ", outname); 154 puts(value); 155 } 132 156 } else { 133 157 char c; … … 182 206 /* if path was ".", drop "./" prefix: */ 183 207 retval |= sysctl_act_recursive((next[0] == '.' && next[1] == '/') ? 184 208 next + 2 : next); 185 209 free(next); 186 210 } … … 207 231 /* Must do it _after_ config_open(): */ 208 232 xchdir("/proc/sys"); 209 /* xchroot(" .") - if you are paranoid */233 /* xchroot("/proc/sys") - if you are paranoid */ 210 234 211 235 //TODO: ';' is comment char too … … 243 267 } 244 268 xchdir("/proc/sys"); 245 /* xchroot(" .") - if you are paranoid */269 /* xchroot("/proc/sys") - if you are paranoid */ 246 270 if (opt & (FLAG_TABLE_FORMAT | FLAG_SHOW_ALL)) { 247 271 return sysctl_act_recursive("."); -
branches/3.2/mindi-busybox/procps/top.c
r2725 r3232 20 20 * Sept 2008: Vineet Gupta <vineet.gupta@arc.com> 21 21 * Added Support for reporting SMP Information 22 * - CPU where Process was last seen running22 * - CPU where process was last seen running 23 23 * (to see effect of sched_setaffinity() etc) 24 * - CPU Time Split (idle/IO/wait etc) PERCPU24 * - CPU time split (idle/IO/wait etc) per CPU 25 25 * 26 26 * Copyright (c) 1992 Branko Lankester … … 31 31 * Licensed under GPLv2, see file LICENSE in this source tree. 32 32 */ 33 /* How to snapshot /proc for debugging top problems: 34 * for f in /proc/[0-9]*""/stat; do 35 * n=${f#/proc/} 36 * n=${n%/stat}_stat 37 * cp $f $n 38 * done 39 * cp /proc/stat /proc/meminfo /proc/loadavg . 40 * top -bn1 >top.out 41 * 42 * ...and how to run top on it on another machine: 43 * rm -rf proc; mkdir proc 44 * for f in [0-9]*_stat; do 45 * p=${f%_stat} 46 * mkdir -p proc/$p 47 * cp $f proc/$p/stat 48 * done 49 * cp stat meminfo loadavg proc 50 * chroot . ./top -bn1 >top1.out 51 */ 52 53 //config:config TOP 54 //config: bool "top" 55 //config: default y 56 //config: help 57 //config: The top program provides a dynamic real-time view of a running 58 //config: system. 59 //config: 60 //config:config FEATURE_TOP_CPU_USAGE_PERCENTAGE 61 //config: bool "Show CPU per-process usage percentage" 62 //config: default y 63 //config: depends on TOP 64 //config: help 65 //config: Make top display CPU usage for each process. 66 //config: This adds about 2k. 67 //config: 68 //config:config FEATURE_TOP_CPU_GLOBAL_PERCENTS 69 //config: bool "Show CPU global usage percentage" 70 //config: default y 71 //config: depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE 72 //config: help 73 //config: Makes top display "CPU: NN% usr NN% sys..." line. 74 //config: This adds about 0.5k. 75 //config: 76 //config:config FEATURE_TOP_SMP_CPU 77 //config: bool "SMP CPU usage display ('c' key)" 78 //config: default y 79 //config: depends on FEATURE_TOP_CPU_GLOBAL_PERCENTS 80 //config: help 81 //config: Allow 'c' key to switch between individual/cumulative CPU stats 82 //config: This adds about 0.5k. 83 //config: 84 //config:config FEATURE_TOP_DECIMALS 85 //config: bool "Show 1/10th of a percent in CPU/mem statistics" 86 //config: default y 87 //config: depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE 88 //config: help 89 //config: Show 1/10th of a percent in CPU/mem statistics. 90 //config: This adds about 0.3k. 91 //config: 92 //config:config FEATURE_TOP_SMP_PROCESS 93 //config: bool "Show CPU process runs on ('j' field)" 94 //config: default y 95 //config: depends on TOP 96 //config: help 97 //config: Show CPU where process was last found running on. 98 //config: This is the 'j' field. 99 //config: 100 //config:config FEATURE_TOPMEM 101 //config: bool "Topmem command ('s' key)" 102 //config: default y 103 //config: depends on TOP 104 //config: help 105 //config: Enable 's' in top (gives lots of memory info). 33 106 34 107 #include "libbb.h" … … 74 147 top_status_t *top; 75 148 int ntop; 149 smallint inverted; 76 150 #if ENABLE_FEATURE_TOPMEM 77 151 smallint sort_field; 78 smallint inverted;79 152 #endif 80 153 #if ENABLE_FEATURE_TOP_SMP_CPU 81 154 smallint smp_cpu_info; /* one/many cpu info lines? */ 82 155 #endif 156 unsigned lines; /* screen height */ 83 157 #if ENABLE_FEATURE_USE_TERMIOS 84 158 struct termios initial_settings; 159 int scroll_ofs; 160 #define G_scroll_ofs G.scroll_ofs 161 #else 162 #define G_scroll_ofs 0 85 163 #endif 86 164 #if !ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE … … 100 178 int num_cpus; 101 179 #endif 180 #if ENABLE_FEATURE_USE_TERMIOS 181 char kbd_input[KEYCODE_BUFFER_SIZE]; 182 #endif 102 183 char line_buf[80]; 103 184 }; //FIX_ALIASING; - large code growth … … 108 189 char BUG_line_buf_too_small[LINE_BUF_SIZE > 80 ? 1 : -1]; 109 190 }; 110 #define INIT_G() do { } while (0)111 191 #define top (G.top ) 112 192 #define ntop (G.ntop ) … … 125 205 #define total_pcpu (G.total_pcpu ) 126 206 #define line_buf (G.line_buf ) 207 #define INIT_G() do { } while (0) 127 208 128 209 enum { … … 176 257 cmp_val = (*sort_function[i])(a, b); 177 258 if (cmp_val != 0) 178 return cmp_val;179 } 180 return 0;259 break; 260 } 261 return inverted ? -cmp_val : cmp_val; 181 262 } 182 263 … … 520 601 /* what info of the processes is shown */ 521 602 printf(OPT_BATCH_MODE ? "%.*s" : "\033[7m%.*s\033[0m", scr_width, 522 " PID PPID USER STAT VSZ % MEM"603 " PID PPID USER STAT VSZ %VSZ" 523 604 IF_FEATURE_TOP_SMP_PROCESS(" CPU") 524 605 IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(" %CPU") … … 538 619 #endif 539 620 /* 540 * MEM%= s->vsz/MemTotal621 * %VSZ = s->vsz/MemTotal 541 622 */ 542 623 pmem_shift = BITS_PER_INT-11; … … 547 628 pmem_shift -= 2; 548 629 } 549 pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2);630 pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2); 550 631 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 551 632 busy_jifs = cur_jif.busy - prev_jif.busy; … … 578 659 pcpu_shift -= 2; 579 660 } 580 pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2);661 pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS ? 20 : 2); 581 662 /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */ 582 663 #endif … … 584 665 /* Ok, all preliminary data is ready, go through the list */ 585 666 scr_width += 2; /* account for leading '\n' and trailing NUL */ 586 if (lines_rem > ntop )587 lines_rem = ntop ;588 s = top ;667 if (lines_rem > ntop - G_scroll_ofs) 668 lines_rem = ntop - G_scroll_ofs; 669 s = top + G_scroll_ofs; 589 670 while (--lines_rem >= 0) { 590 671 unsigned col; … … 598 679 else 599 680 sprintf(vsz_str_buf, "%7ld", s->vsz); 600 /* PID PPID USER STAT VSZ % MEM[%CPU] COMMAND */681 /* PID PPID USER STAT VSZ %VSZ [%CPU] COMMAND */ 601 682 col = snprintf(line_buf, scr_width, 602 683 "\n" "%5u%6u %-8.8s %s%s" FMT … … 631 712 free(top); 632 713 top = NULL; 633 ntop = 0;634 714 } 635 715 … … 638 718 static void reset_term(void) 639 719 { 640 tcsetattr_stdin_TCSANOW(&initial_settings); 720 if (!OPT_BATCH_MODE) 721 tcsetattr_stdin_TCSANOW(&initial_settings); 641 722 if (ENABLE_FEATURE_CLEAN_UP) { 642 723 clearmems(); … … 647 728 } 648 729 649 static void sig_catcher(int sig UNUSED_PARAM)730 static void sig_catcher(int sig) 650 731 { 651 732 reset_term(); 652 _exit(EXIT_FAILURE);733 kill_myself_with_sig(sig); 653 734 } 654 735 … … 775 856 #define HDR_STR " PID VSZ VSZRW RSS (SHR) DIRTY (SHR) STACK" 776 857 #define MIN_WIDTH sizeof(HDR_STR) 777 const topmem_status_t *s = topmem ;858 const topmem_status_t *s = topmem + G_scroll_ofs; 778 859 779 860 display_topmem_header(scr_width, &lines_rem); 780 861 strcpy(line_buf, HDR_STR " COMMAND"); 781 line_buf[ 5 + sort_field * 6] = '*';862 line_buf[11 + sort_field * 6] = "^_"[inverted]; 782 863 printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, line_buf); 783 864 lines_rem--; 784 865 785 if (lines_rem > ntop )786 lines_rem = ntop ;866 if (lines_rem > ntop - G_scroll_ofs) 867 lines_rem = ntop - G_scroll_ofs; 787 868 while (--lines_rem >= 0) { 788 869 /* PID VSZ VSZRW RSS (SHR) DIRTY (SHR) COMMAND */ … … 832 913 | PSSCAN_SMAPS 833 914 | PSSCAN_COMM, 915 EXIT_MASK = (unsigned)-1, 834 916 }; 917 918 #if ENABLE_FEATURE_USE_TERMIOS 919 static unsigned handle_input(unsigned scan_mask, unsigned interval) 920 { 921 struct pollfd pfd[1]; 922 923 if (option_mask32 & OPT_EOF) { 924 /* EOF on stdin ("top </dev/null") */ 925 sleep(interval); 926 return scan_mask; 927 } 928 929 pfd[0].fd = 0; 930 pfd[0].events = POLLIN; 931 932 while (1) { 933 int32_t c; 934 935 c = read_key(STDIN_FILENO, G.kbd_input, interval * 1000); 936 if (c == -1 && errno != EAGAIN) { 937 /* error/EOF */ 938 option_mask32 |= OPT_EOF; 939 break; 940 } 941 interval = 0; 942 943 if (c == initial_settings.c_cc[VINTR]) 944 return EXIT_MASK; 945 if (c == initial_settings.c_cc[VEOF]) 946 return EXIT_MASK; 947 948 if (c == KEYCODE_UP) { 949 G_scroll_ofs--; 950 goto normalize_ofs; 951 } 952 if (c == KEYCODE_DOWN) { 953 G_scroll_ofs++; 954 goto normalize_ofs; 955 } 956 if (c == KEYCODE_HOME) { 957 G_scroll_ofs = 0; 958 break; 959 } 960 if (c == KEYCODE_END) { 961 G_scroll_ofs = ntop - G.lines / 2; 962 goto normalize_ofs; 963 } 964 if (c == KEYCODE_PAGEUP) { 965 G_scroll_ofs -= G.lines / 2; 966 goto normalize_ofs; 967 } 968 if (c == KEYCODE_PAGEDOWN) { 969 G_scroll_ofs += G.lines / 2; 970 normalize_ofs: 971 if (G_scroll_ofs >= ntop) 972 G_scroll_ofs = ntop - 1; 973 if (G_scroll_ofs < 0) 974 G_scroll_ofs = 0; 975 break; 976 } 977 978 c |= 0x20; /* lowercase */ 979 if (c == 'q') 980 return EXIT_MASK; 981 982 if (c == 'n') { 983 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 984 sort_function[0] = pid_sort; 985 continue; 986 } 987 if (c == 'm') { 988 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 989 sort_function[0] = mem_sort; 990 # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 991 sort_function[1] = pcpu_sort; 992 sort_function[2] = time_sort; 993 # endif 994 continue; 995 } 996 # if ENABLE_FEATURE_SHOW_THREADS 997 if (c == 'h' 998 IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK) 999 ) { 1000 scan_mask ^= PSSCAN_TASKS; 1001 continue; 1002 } 1003 # endif 1004 # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 1005 if (c == 'p') { 1006 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 1007 sort_function[0] = pcpu_sort; 1008 sort_function[1] = mem_sort; 1009 sort_function[2] = time_sort; 1010 continue; 1011 } 1012 if (c == 't') { 1013 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 1014 sort_function[0] = time_sort; 1015 sort_function[1] = mem_sort; 1016 sort_function[2] = pcpu_sort; 1017 continue; 1018 } 1019 # if ENABLE_FEATURE_TOPMEM 1020 if (c == 's') { 1021 scan_mask = TOPMEM_MASK; 1022 free(prev_hist); 1023 prev_hist = NULL; 1024 prev_hist_count = 0; 1025 sort_field = (sort_field + 1) % NUM_SORT_FIELD; 1026 continue; 1027 } 1028 # endif 1029 if (c == 'r') { 1030 inverted ^= 1; 1031 continue; 1032 } 1033 # if ENABLE_FEATURE_TOP_SMP_CPU 1034 /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ 1035 if (c == 'c' || c == '1') { 1036 /* User wants to toggle per cpu <> aggregate */ 1037 if (smp_cpu_info) { 1038 free(cpu_prev_jif); 1039 free(cpu_jif); 1040 cpu_jif = &cur_jif; 1041 cpu_prev_jif = &prev_jif; 1042 } else { 1043 /* Prepare for xrealloc() */ 1044 cpu_jif = cpu_prev_jif = NULL; 1045 } 1046 num_cpus = 0; 1047 smp_cpu_info = !smp_cpu_info; 1048 get_jiffy_counts(); 1049 continue; 1050 } 1051 # endif 1052 # endif 1053 break; /* unknown key -> force refresh */ 1054 } 1055 1056 return scan_mask; 1057 } 1058 #endif 1059 1060 //usage:#if ENABLE_FEATURE_SHOW_THREADS || ENABLE_FEATURE_TOP_SMP_CPU 1061 //usage:# define IF_SHOW_THREADS_OR_TOP_SMP(...) __VA_ARGS__ 1062 //usage:#else 1063 //usage:# define IF_SHOW_THREADS_OR_TOP_SMP(...) 1064 //usage:#endif 1065 //usage:#define top_trivial_usage 1066 //usage: "[-b] [-nCOUNT] [-dSECONDS]" IF_FEATURE_TOPMEM(" [-m]") 1067 //usage:#define top_full_usage "\n\n" 1068 //usage: "Provide a view of process activity in real time." 1069 //usage: "\n""Read the status of all processes from /proc each SECONDS" 1070 //usage: "\n""and display a screenful of them." 1071 //usage: "\n""Keys:" 1072 //usage: "\n"" N/M" 1073 //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/P") 1074 //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/T") 1075 //usage: ": " IF_FEATURE_TOPMEM("show CPU usage, ") "sort by pid/mem" 1076 //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/cpu") 1077 //usage: IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE("/time") 1078 //usage: IF_FEATURE_TOPMEM( 1079 //usage: "\n"" S: show memory" 1080 //usage: ) 1081 //usage: "\n"" R: reverse sort" 1082 //usage: IF_SHOW_THREADS_OR_TOP_SMP( 1083 //usage: "\n"" " 1084 //usage: IF_FEATURE_SHOW_THREADS("H: toggle threads") 1085 //usage: IF_FEATURE_SHOW_THREADS(IF_FEATURE_TOP_SMP_CPU(", ")) 1086 //usage: IF_FEATURE_TOP_SMP_CPU("1: toggle SMP") 1087 //usage: ) 1088 //usage: "\n"" Q,^C: exit" 1089 //usage: "\n" 1090 //usage: "\n""Options:" 1091 //usage: "\n"" -b Batch mode" 1092 //usage: "\n"" -n N Exit after N iterations" 1093 //usage: "\n"" -d N Delay between updates" 1094 //usage: IF_FEATURE_TOPMEM( 1095 //usage: "\n"" -m Same as 's' key" 1096 //usage: ) 1097 1098 /* Interactive testing: 1099 * echo sss | ./busybox top 1100 * - shows memory screen 1101 * echo sss | ./busybox top -bn1 >mem 1102 * - saves memory screen - the *whole* list, not first NROWS processes! 1103 * echo .m.s.s.s.s.s.s.q | ./busybox top -b >z 1104 * - saves several different screens, and exits 1105 * 1106 * TODO: -i STRING param as a better alternative? 1107 */ 835 1108 836 1109 int top_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; … … 838 1111 { 839 1112 int iterations; 840 unsigned lines, col; 841 int lines_rem; 1113 unsigned col; 842 1114 unsigned interval; 843 1115 char *str_interval, *str_iterations; … … 845 1117 #if ENABLE_FEATURE_USE_TERMIOS 846 1118 struct termios new_settings; 847 struct pollfd pfd[1];848 unsigned char c;849 850 pfd[0].fd = 0;851 pfd[0].events = POLLIN;852 1119 #endif 853 1120 … … 886 1153 /* change to /proc */ 887 1154 xchdir("/proc"); 888 #if ENABLE_FEATURE_USE_TERMIOS889 tcgetattr(0, (void *) &initial_settings);890 memcpy(&new_settings, &initial_settings, sizeof(new_settings));891 /* unbuffered input, turn off echo */892 new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);893 894 bb_signals(BB_FATAL_SIGS, sig_catcher);895 tcsetattr_stdin_TCSANOW(&new_settings);896 #endif897 1155 898 1156 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE … … 904 1162 #endif 905 1163 906 while (1) { 1164 if (OPT_BATCH_MODE) { 1165 option_mask32 |= OPT_EOF; 1166 } 1167 #if ENABLE_FEATURE_USE_TERMIOS 1168 else { 1169 tcgetattr(0, (void *) &initial_settings); 1170 memcpy(&new_settings, &initial_settings, sizeof(new_settings)); 1171 /* unbuffered input, turn off echo */ 1172 new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL); 1173 tcsetattr_stdin_TCSANOW(&new_settings); 1174 } 1175 1176 bb_signals(BB_FATAL_SIGS, sig_catcher); 1177 1178 /* Eat initial input, if any */ 1179 scan_mask = handle_input(scan_mask, 0); 1180 #endif 1181 1182 while (scan_mask != EXIT_MASK) { 907 1183 procps_status_t *p = NULL; 908 1184 909 lines = 24; /* default */ 910 col = 79; 1185 if (OPT_BATCH_MODE) { 1186 G.lines = INT_MAX; 1187 col = LINE_BUF_SIZE - 2; /* +2 bytes for '\n', NUL */ 1188 } else { 1189 G.lines = 24; /* default */ 1190 col = 79; 911 1191 #if ENABLE_FEATURE_USE_TERMIOS 912 /* We output to stdout, we need size of stdout (not stdin)! */ 913 get_terminal_width_height(STDOUT_FILENO, &col, &lines); 914 if (lines < 5 || col < 10) { 915 sleep(interval); 916 continue; 917 } 918 #endif 919 if (col > LINE_BUF_SIZE-2) /* +2 bytes for '\n', NUL, */ 920 col = LINE_BUF_SIZE-2; 1192 /* We output to stdout, we need size of stdout (not stdin)! */ 1193 get_terminal_width_height(STDOUT_FILENO, &col, &G.lines); 1194 if (G.lines < 5 || col < 10) { 1195 sleep(interval); 1196 continue; 1197 } 1198 #endif 1199 if (col > LINE_BUF_SIZE - 2) 1200 col = LINE_BUF_SIZE - 2; 1201 } 921 1202 922 1203 /* read process IDs & status for all the processes */ 1204 ntop = 0; 923 1205 while ((p = procps_scan(p, scan_mask)) != NULL) { 924 1206 int n; … … 986 1268 } 987 1269 #endif 988 lines_rem = lines;989 if (OPT_BATCH_MODE) {990 lines_rem = INT_MAX;991 }992 1270 if (scan_mask != TOPMEM_MASK) 993 display_process_list( lines_rem, col);1271 display_process_list(G.lines, col); 994 1272 #if ENABLE_FEATURE_TOPMEM 995 1273 else 996 display_topmem_process_list( lines_rem, col);1274 display_topmem_process_list(G.lines, col); 997 1275 #endif 998 1276 clearmems(); … … 1002 1280 sleep(interval); 1003 1281 #else 1004 if (option_mask32 & (OPT_b|OPT_EOF)) 1005 /* batch mode, or EOF on stdin ("top </dev/null") */ 1006 sleep(interval); 1007 else if (safe_poll(pfd, 1, interval * 1000) > 0) { 1008 if (safe_read(STDIN_FILENO, &c, 1) != 1) { /* error/EOF? */ 1009 option_mask32 |= OPT_EOF; 1010 continue; 1011 } 1012 if (c == initial_settings.c_cc[VINTR]) 1013 break; 1014 c |= 0x20; /* lowercase */ 1015 if (c == 'q') 1016 break; 1017 if (c == 'n') { 1018 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 1019 sort_function[0] = pid_sort; 1020 } 1021 if (c == 'm') { 1022 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 1023 sort_function[0] = mem_sort; 1024 # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 1025 sort_function[1] = pcpu_sort; 1026 sort_function[2] = time_sort; 1027 # endif 1028 } 1029 # if ENABLE_FEATURE_SHOW_THREADS 1030 if (c == 'h' 1031 IF_FEATURE_TOPMEM(&& scan_mask != TOPMEM_MASK) 1032 ) { 1033 scan_mask ^= PSSCAN_TASKS; 1034 } 1035 # endif 1036 # if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 1037 if (c == 'p') { 1038 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 1039 sort_function[0] = pcpu_sort; 1040 sort_function[1] = mem_sort; 1041 sort_function[2] = time_sort; 1042 } 1043 if (c == 't') { 1044 IF_FEATURE_TOPMEM(scan_mask = TOP_MASK;) 1045 sort_function[0] = time_sort; 1046 sort_function[1] = mem_sort; 1047 sort_function[2] = pcpu_sort; 1048 } 1049 # if ENABLE_FEATURE_TOPMEM 1050 if (c == 's') { 1051 scan_mask = TOPMEM_MASK; 1052 free(prev_hist); 1053 prev_hist = NULL; 1054 prev_hist_count = 0; 1055 sort_field = (sort_field + 1) % NUM_SORT_FIELD; 1056 } 1057 if (c == 'r') 1058 inverted ^= 1; 1059 # endif 1060 # if ENABLE_FEATURE_TOP_SMP_CPU 1061 /* procps-2.0.18 uses 'C', 3.2.7 uses '1' */ 1062 if (c == 'c' || c == '1') { 1063 /* User wants to toggle per cpu <> aggregate */ 1064 if (smp_cpu_info) { 1065 free(cpu_prev_jif); 1066 free(cpu_jif); 1067 cpu_jif = &cur_jif; 1068 cpu_prev_jif = &prev_jif; 1069 } else { 1070 /* Prepare for xrealloc() */ 1071 cpu_jif = cpu_prev_jif = NULL; 1072 } 1073 num_cpus = 0; 1074 smp_cpu_info = !smp_cpu_info; 1075 get_jiffy_counts(); 1076 } 1077 # endif 1078 # endif 1079 } 1282 scan_mask = handle_input(scan_mask, interval); 1080 1283 #endif /* FEATURE_USE_TERMIOS */ 1081 } /* end of "while ( 1)" */1284 } /* end of "while (not Q)" */ 1082 1285 1083 1286 bb_putchar('\n'); -
branches/3.2/mindi-busybox/procps/uptime.c
r2725 r3232 8 8 */ 9 9 10 /* This version of uptime doesn't display the number of users on the system, 11 * since busybox init doesn't mess with utmp. For folks using utmp that are 12 * just dying to have # of users reported, feel free to write it as some type 13 * of CONFIG_FEATURE_UTMP_SUPPORT #define 10 /* 2011 Pere Orga <gotrunks@gmail.com> 11 * 12 * Added FEATURE_UPTIME_UTMP_SUPPORT flag. 14 13 */ 15 14 16 15 /* getopt not needed */ 17 16 17 //config:config UPTIME 18 //config: bool "uptime" 19 //config: default y 20 //config: select PLATFORM_LINUX #sysinfo() 21 //config: help 22 //config: uptime gives a one line display of the current time, how long 23 //config: the system has been running, how many users are currently logged 24 //config: on, and the system load averages for the past 1, 5, and 15 minutes. 25 //config: 26 //config:config FEATURE_UPTIME_UTMP_SUPPORT 27 //config: bool "Support for showing the number of users" 28 //config: default y 29 //config: depends on UPTIME && FEATURE_UTMP 30 //config: help 31 //config: Makes uptime display the number of users currently logged on. 32 33 //usage:#define uptime_trivial_usage 34 //usage: "" 35 //usage:#define uptime_full_usage "\n\n" 36 //usage: "Display the time since the last boot" 37 //usage: 38 //usage:#define uptime_example_usage 39 //usage: "$ uptime\n" 40 //usage: " 1:55pm up 2:30, load average: 0.09, 0.04, 0.00\n" 41 18 42 #include "libbb.h" 43 #ifdef __linux__ 44 # include <sys/sysinfo.h> 45 #endif 46 19 47 20 48 #ifndef FSHIFT 21 49 # define FSHIFT 16 /* nr of bits of precision */ 22 50 #endif 23 #define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */24 #define LOAD_INT(x) ((x) >> FSHIFT)25 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 -1)) * 100)51 #define FIXED_1 (1 << FSHIFT) /* 1.0 as fixed-point */ 52 #define LOAD_INT(x) (unsigned)((x) >> FSHIFT) 53 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1 - 1)) * 100) 26 54 27 55 … … 29 57 int uptime_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 30 58 { 31 intupdays, uphours, upminutes;59 unsigned updays, uphours, upminutes; 32 60 struct sysinfo info; 33 61 struct tm *current_time; … … 39 67 sysinfo(&info); 40 68 41 printf(" %02 d:%02d:%02dup ",69 printf(" %02u:%02u:%02u up ", 42 70 current_time->tm_hour, current_time->tm_min, current_time->tm_sec); 43 updays = ( int) info.uptime /(60*60*24);71 updays = (unsigned) info.uptime / (unsigned)(60*60*24); 44 72 if (updays) 45 printf("% dday%s, ", updays, (updays != 1) ? "s" : "");46 upminutes = ( int) info.uptime /60;47 uphours = (upminutes / 60) %24;73 printf("%u day%s, ", updays, (updays != 1) ? "s" : ""); 74 upminutes = (unsigned) info.uptime / (unsigned)60; 75 uphours = (upminutes / (unsigned)60) % (unsigned)24; 48 76 upminutes %= 60; 49 77 if (uphours) 50 printf("%2 d:%02d,", uphours, upminutes);78 printf("%2u:%02u", uphours, upminutes); 51 79 else 52 printf("% d min,", upminutes);80 printf("%u min", upminutes); 53 81 54 printf("load average: %ld.%02ld, %ld.%02ld, %ld.%02ld\n", 82 #if ENABLE_FEATURE_UPTIME_UTMP_SUPPORT 83 { 84 struct utmp *ut; 85 unsigned users = 0; 86 while ((ut = getutent()) != NULL) { 87 if ((ut->ut_type == USER_PROCESS) && (ut->ut_name[0] != '\0')) 88 users++; 89 } 90 printf(", %u users", users); 91 } 92 #endif 93 94 printf(", load average: %u.%02u, %u.%02u, %u.%02u\n", 55 95 LOAD_INT(info.loads[0]), LOAD_FRAC(info.loads[0]), 56 96 LOAD_INT(info.loads[1]), LOAD_FRAC(info.loads[1]), -
branches/3.2/mindi-busybox/procps/watch.c
r2725 r3232 11 11 /* BB_AUDIT SUSv3 N/A */ 12 12 /* BB_AUDIT GNU defects -- only option -n is supported. */ 13 14 //usage:#define watch_trivial_usage 15 //usage: "[-n SEC] [-t] PROG ARGS" 16 //usage:#define watch_full_usage "\n\n" 17 //usage: "Run PROG periodically\n" 18 //usage: "\n -n Loop period in seconds (default 2)" 19 //usage: "\n -t Don't print header" 20 //usage: 21 //usage:#define watch_example_usage 22 //usage: "$ watch date\n" 23 //usage: "Mon Dec 17 10:31:40 GMT 2000\n" 24 //usage: "Mon Dec 17 10:31:42 GMT 2000\n" 25 //usage: "Mon Dec 17 10:31:44 GMT 2000" 13 26 14 27 #include "libbb.h"
Note:
See TracChangeset
for help on using the changeset viewer.