Changeset 1765 in MondoRescue for branches/2.2.5/mindi-busybox/procps
- Timestamp:
- Nov 4, 2007, 3:16:40 AM (16 years ago)
- Location:
- branches/2.2.5/mindi-busybox/procps
- Files:
-
- 4 added
- 2 deleted
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.5/mindi-busybox/procps/Config.in
r821 r1765 6 6 menu "Process Utilities" 7 7 8 config CONFIG_FREE8 config FREE 9 9 bool "free" 10 10 default n … … 14 14 The shared memory column should be ignored; it is obsolete. 15 15 16 config CONFIG_FUSER16 config FUSER 17 17 bool "fuser" 18 18 default n … … 22 22 (TCP or UDP) port open. 23 23 24 config CONFIG_KILL24 config KILL 25 25 bool "kill" 26 26 default n … … 30 30 signal is sent. 31 31 32 config CONFIG_KILLALL32 config KILLALL 33 33 bool "killall" 34 34 default n 35 depends on CONFIG_KILL35 depends on KILL 36 36 help 37 37 killall sends a signal to all processes running any of the … … 39 39 sent. 40 40 41 config CONFIG_PIDOF 41 config KILLALL5 42 bool "killall5" 43 default n 44 depends on KILL 45 46 config NMETER 47 bool "nmeter" 48 default n 49 help 50 Prints selected system stats continuously, one line per update. 51 52 config PIDOF 42 53 bool "pidof" 43 54 default n … … 46 57 those id's on the standard output. 47 58 48 config CONFIG_FEATURE_PIDOF_SINGLE59 config FEATURE_PIDOF_SINGLE 49 60 bool "Enable argument for single shot (-s)" 50 61 default n 51 depends on CONFIG_PIDOF62 depends on PIDOF 52 63 help 53 64 Support argument '-s' for returning only the first pid found. 54 65 55 config CONFIG_FEATURE_PIDOF_OMIT66 config FEATURE_PIDOF_OMIT 56 67 bool "Enable argument for omitting pids (-o)" 57 68 default n 58 depends on CONFIG_PIDOF69 depends on PIDOF 59 70 help 60 71 Support argument '-o' for omitting the given pids in output. … … 62 73 of the pidof, in other words the calling shell or shell script. 63 74 64 config CONFIG_PS75 config PS 65 76 bool "ps" 66 77 default n … … 68 79 ps gives a snapshot of the current processes. 69 80 70 config CONFIG_FEATURE_PS_WIDE81 config FEATURE_PS_WIDE 71 82 bool "Enable argument for wide output (-w)" 72 83 default n 73 depends on CONFIG_PS84 depends on PS 74 85 help 75 86 Support argument 'w' for wide output. … … 77 88 one, the length is unlimited. 78 89 79 config CONFIG_RENICE90 config RENICE 80 91 bool "renice" 81 92 default n … … 84 95 processes. 85 96 86 config CONFIG_BB_SYSCTL97 config BB_SYSCTL 87 98 bool "sysctl" 88 99 default n … … 90 101 Configure kernel parameters at runtime. 91 102 92 config CONFIG_TOP103 config TOP 93 104 bool "top" 94 105 default n … … 97 108 system. 98 109 99 config CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE100 bool "S upport showing CPU usage percentage (add2k bytes)"110 config FEATURE_TOP_CPU_USAGE_PERCENTAGE 111 bool "Show CPU per-process usage percentage (adds 2k bytes)" 101 112 default y 102 depends on CONFIG_TOP113 depends on TOP 103 114 help 104 Make top display CPU usage .115 Make top display CPU usage for each process. 105 116 106 config CONFIG_UPTIME 117 config FEATURE_TOP_CPU_GLOBAL_PERCENTS 118 bool "Show CPU global usage percentage (adds 0.5k bytes)" 119 default y 120 depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE 121 help 122 Makes top display "CPU: NN% usr NN% sys..." line. 123 124 config FEATURE_TOP_DECIMALS 125 bool "Show 1/10th of a percent in CPU/mem statistics (adds 0.3k bytes)" 126 default n 127 depends on FEATURE_TOP_CPU_USAGE_PERCENTAGE 128 help 129 Show 1/10th of a percent in CPU/mem statistics. 130 131 config UPTIME 107 132 bool "uptime" 108 133 default n … … 112 137 on, and the system load averages for the past 1, 5, and 15 minutes. 113 138 139 config WATCH 140 bool "watch" 141 default n 142 #huh?? select DATE 143 help 144 watch is used to execute a program periodically, showing 145 output to the screen. 146 114 147 115 148 endmenu -
branches/2.2.5/mindi-busybox/procps/free.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * Licensed under the GPL v 2 or later, see the file LICENSE in this tarball.7 * Licensed under the GPL version 2, see the file LICENSE in this tarball. 8 8 */ 9 9 10 10 /* getopt not needed */ 11 11 12 #include "busybox.h" 13 #include <stdio.h> 14 #include <errno.h> 15 #include <stdlib.h> 12 #include "libbb.h" 16 13 14 int free_main(int argc, char **argv); 17 15 int free_main(int argc, char **argv) 18 16 { … … 21 19 22 20 /* Kernels prior to 2.4.x will return info.mem_unit==0, so cope... */ 23 if (info.mem_unit ==0) {21 if (info.mem_unit == 0) { 24 22 info.mem_unit=1; 25 23 } 26 if ( info.mem_unit == 1) {24 if (info.mem_unit == 1) { 27 25 info.mem_unit=1024; 28 26 … … 49 47 } 50 48 51 if (argc > 1 && * *(argv + 1)== '-')49 if (argc > 1 && *argv[1] == '-') 52 50 bb_show_usage(); 53 51 … … 69 67 return EXIT_SUCCESS; 70 68 } 71 -
branches/2.2.5/mindi-busybox/procps/fuser.c
r821 r1765 9 9 */ 10 10 11 #include "busybox.h" 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <unistd.h> 15 #include <string.h> 16 #include <limits.h> 17 #include <dirent.h> 18 #include <signal.h> 19 #include <sys/types.h> 20 #include <sys/ioctl.h> 21 #include <sys/stat.h> 22 #include <sys/socket.h> 23 #include <sys/sysmacros.h> 11 #include "libbb.h" 24 12 25 13 #define FUSER_PROC_DIR "/proc" … … 47 35 int opt = 0; 48 36 49 if(!(strlen(option))) return 0; 50 if(option[0] != '-') return 0; 37 if (!option[0]) 38 return 0; 39 if (option[0] != '-') 40 return 0; 51 41 ++option; 52 while(*option != '\0') { 53 if(*option == 'm') opt |= FUSER_OPT_MOUNT; 54 else if(*option == 'k') opt |= FUSER_OPT_KILL; 55 else if(*option == 's') opt |= FUSER_OPT_SILENT; 56 else if(*option == '6') opt |= FUSER_OPT_IP6; 57 else if(*option == '4') opt |= FUSER_OPT_IP4; 58 else { 59 bb_error_msg_and_die( 60 "Unsupported option '%c'", *option); 61 } 42 while (*option != '\0') { 43 if (*option == 'm') opt |= FUSER_OPT_MOUNT; 44 else if (*option == 'k') opt |= FUSER_OPT_KILL; 45 else if (*option == 's') opt |= FUSER_OPT_SILENT; 46 else if (*option == '6') opt |= FUSER_OPT_IP6; 47 else if (*option == '4') opt |= FUSER_OPT_IP4; 48 else 49 bb_error_msg_and_die("unsupported option '%c'", *option); 62 50 ++option; 63 51 } … … 69 57 { 70 58 struct stat f_stat; 71 if((stat(filename, &f_stat)) < 0) return 0; 59 if ((stat(filename, &f_stat)) < 0) 60 return 0; 72 61 *inode = f_stat.st_ino; 73 62 *dev = f_stat.st_dev; … … 81 70 82 71 if (fd >= 0 && (fstat(fd, &buf)) == 0) { 83 *dev = 72 *dev = buf.st_dev; 84 73 close(fd); 85 74 return 1; … … 93 82 char path[sizeof(FUSER_PROC_DIR)+12], tproto[5]; 94 83 95 if((sscanf(filename, "%d/%4s", port, tproto)) != 2) return 0; 96 sprintf(path, "%s/net/%s", FUSER_PROC_DIR, tproto); 97 if((access(path, R_OK)) != 0) return 0; 98 *proto = bb_xstrdup(tproto); 84 if ((sscanf(filename, "%d/%4s", port, tproto)) != 2) 85 return 0; 86 sprintf(path, FUSER_PROC_DIR "/net/%s", tproto); 87 if ((access(path, R_OK)) != 0) 88 return 0; 89 *proto = xstrdup(tproto); 99 90 return 1; 100 91 } … … 104 95 pid_list *curr = NULL, *last = NULL; 105 96 106 if(plist->pid == 0) plist->pid = pid; 97 if (plist->pid == 0) 98 plist->pid = pid; 107 99 curr = plist; 108 while(curr != NULL) { 109 if(curr->pid == pid) return 1; 100 while (curr != NULL) { 101 if (curr->pid == pid) 102 return 1; 110 103 last = curr; 111 104 curr = curr->next; 112 105 } 113 curr = x malloc(sizeof(pid_list));106 curr = xzalloc(sizeof(pid_list)); 114 107 last->next = curr; 115 108 curr->pid = pid; 116 curr->next = NULL;109 /*curr->next = NULL;*/ 117 110 return 1; 118 111 } … … 122 115 inode_list *curr = NULL, *last = NULL; 123 116 124 if (!ilist->inode && !ilist->dev) {117 if (!ilist->inode && !ilist->dev) { 125 118 ilist->dev = dev; 126 119 ilist->inode = inode; 127 120 } 128 121 curr = ilist; 129 while(curr != NULL) { 130 if(curr->inode == inode && curr->dev == dev) return 1; 122 while (curr != NULL) { 123 if (curr->inode == inode && curr->dev == dev) 124 return 1; 131 125 last = curr; 132 126 curr = curr->next; 133 127 } 134 curr = x malloc(sizeof(inode_list));128 curr = xzalloc(sizeof(inode_list)); 135 129 last->next = curr; 136 130 curr->dev = dev; 137 131 curr->inode = inode; 138 curr->next = NULL;132 /*curr->next = NULL;*/ 139 133 return 1; 140 134 } … … 147 141 ino_t tmp_inode; 148 142 dev_t tmp_dev; 149 long long 143 long long uint64_inode; 150 144 int tmp_port; 151 145 FILE *f; 152 146 153 if(!fuser_find_socket_dev(&tmp_dev)) tmp_dev = 0; 154 sprintf(path, "%s/net/%s", FUSER_PROC_DIR, proto); 155 156 if (!(f = fopen(path, "r"))) return 0; 157 while(fgets(line, FUSER_MAX_LINE, f)) { 158 if(sscanf(line, 159 "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x %*x:%*x " 160 "%*x:%*x %*x %*d %*d %llu", 161 addr, &tmp_port, &uint64_inode) == 3) { 162 if((strlen(addr) == 8) && 163 (opts & FUSER_OPT_IP6)) continue; 164 else if((strlen(addr) > 8) && 165 (opts & FUSER_OPT_IP4)) continue; 166 if(tmp_port == port) { 147 if (!fuser_find_socket_dev(&tmp_dev)) 148 tmp_dev = 0; 149 sprintf(path, FUSER_PROC_DIR "/net/%s", proto); 150 151 f = fopen(path, "r"); 152 if (!f) 153 return 0; 154 while (fgets(line, FUSER_MAX_LINE, f)) { 155 if (sscanf(line, "%*d: %64[0-9A-Fa-f]:%x %*x:%*x %*x %*x:%*x " 156 "%*x:%*x %*x %*d %*d %llu", 157 addr, &tmp_port, &uint64_inode) == 3 158 ) { 159 if (strlen(addr) == 8 && (opts & FUSER_OPT_IP6)) 160 continue; 161 if (strlen(addr) > 8 && (opts & FUSER_OPT_IP4)) 162 continue; 163 if (tmp_port == port) { 167 164 tmp_inode = uint64_inode; 168 165 fuser_add_inode(ilist, tmp_dev, tmp_inode); 169 166 } 170 167 } 171 172 168 } 173 169 fclose(f); … … 181 177 curr = ilist; 182 178 183 while (curr) {184 if ((opts & FUSER_OPT_MOUNT) &&curr->dev == dev)179 while (curr) { 180 if ((opts & FUSER_OPT_MOUNT) && curr->dev == dev) 185 181 return 1; 186 if (curr->inode == inode && curr->dev == dev)182 if (curr->inode == inode && curr->dev == dev) 187 183 return 1; 188 184 curr = curr->next; … … 201 197 dev_t dev; 202 198 203 if (!(file = fopen(fname, "r"))) return 0; 199 file = fopen(fname, "r"); 200 if (!file) 201 return 0; 204 202 while (fgets(line, FUSER_MAX_LINE, file)) { 205 if (sscanf(line, "%*s %*s %*s %x:%x %llu",206 &major, &minor, &uint64_inode) != 3)continue;203 if (sscanf(line, "%*s %*s %*s %x:%x %llu", &major, &minor, &uint64_inode) != 3) 204 continue; 207 205 inode = uint64_inode; 208 if(major == 0 && minor == 0 && inode == 0) continue; 206 if (major == 0 && minor == 0 && inode == 0) 207 continue; 209 208 dev = makedev(major, minor); 210 if (fuser_search_dev_inode(opts, ilist, dev, inode)) {209 if (fuser_search_dev_inode(opts, ilist, dev, inode)) { 211 210 fuser_add_pid(plist, pid); 212 211 } 213 214 212 } 215 213 fclose(file); … … 223 221 dev_t dev; 224 222 225 if(!fuser_file_to_dev_inode(lname, &dev, &inode)) return 0; 226 if(fuser_search_dev_inode(opts, ilist, dev, inode)) 223 if (!fuser_file_to_dev_inode(lname, &dev, &inode)) 224 return 0; 225 if (fuser_search_dev_inode(opts, ilist, dev, inode)) 227 226 fuser_add_pid(plist, pid); 228 227 return 1; … … 236 235 char *lname; 237 236 238 if((d = opendir(dname))) { 239 while((de = readdir(d)) != NULL) { 240 lname = concat_subpath_file(dname, de->d_name); 241 if(lname == NULL) 242 continue; 243 fuser_scan_link(opts, lname, pid, ilist, plist); 244 free(lname); 245 } 246 closedir(d); 247 } 248 else return 0; 249 return 1; 250 237 d = opendir(dname); 238 if (!d) 239 return 0; 240 while ((de = readdir(d)) != NULL) { 241 lname = concat_subpath_file(dname, de->d_name); 242 if (lname == NULL) 243 continue; 244 fuser_scan_link(opts, lname, pid, ilist, plist); 245 free(lname); 246 } 247 closedir(d); 248 return 1; 251 249 } 252 250 … … 258 256 char *dname; 259 257 260 if(!(d = opendir(FUSER_PROC_DIR))) return 0; 261 while((de = readdir(d)) != NULL) { 258 d = opendir(FUSER_PROC_DIR); 259 if (!d) 260 return 0; 261 while ((de = readdir(d)) != NULL) { 262 262 pid = (pid_t)atoi(de->d_name); 263 if(!pid) continue; 263 if (!pid) 264 continue; 264 265 dname = concat_subpath_file(FUSER_PROC_DIR, de->d_name); 265 if (chdir(dname) < 0) {266 if (chdir(dname) < 0) { 266 267 free(dname); 267 268 continue; … … 285 286 pid_list *curr = plist; 286 287 287 if(plist == NULL) return 0; 288 while(curr != NULL) { 289 if(curr->pid > 0) printf("%d ", curr->pid); 290 curr = curr->next; 291 } 292 printf("\n"); 288 if (plist == NULL) 289 return 0; 290 while (curr != NULL) { 291 if (curr->pid > 0) 292 printf("%d ", curr->pid); 293 curr = curr->next; 294 } 295 puts(""); 293 296 return 1; 294 297 } … … 300 303 int success = 1; 301 304 302 if(plist == NULL) return 0; 303 while(curr != NULL) { 304 if(curr->pid > 0 && curr->pid != mypid) { 305 if (plist == NULL) 306 return 0; 307 while (curr != NULL) { 308 if (curr->pid > 0 && curr->pid != mypid) { 305 309 if (kill(curr->pid, sig) != 0) { 306 bb_perror_msg( 307 "Could not kill pid '%d'", curr->pid); 310 bb_perror_msg("kill pid '%d'", curr->pid); 308 311 success = 0; 309 312 } … … 314 317 } 315 318 319 int fuser_main(int argc, char **argv); 316 320 int fuser_main(int argc, char **argv) 317 321 { 322 /*static -- huh???*/ int opt = 0; /* FUSER_OPT_ */ 323 318 324 int port, i, optn; 319 325 int* fni; /* file name indexes of argv */ 320 326 int fnic = 0; /* file name index count */ 321 327 const char *proto; 322 static int opt = 0; /* FUSER_OPT_ */323 328 dev_t dev; 324 329 ino_t inode; … … 332 337 333 338 fni = xmalloc(sizeof(int)); 334 for (i=1;i<argc;i++) {339 for (i = 1; i < argc; i++) { 335 340 optn = fuser_option(argv[i]); 336 if(optn) opt |= optn; 337 else if(argv[i][0] == '-') { 338 if(!(u_signal_names(argv[i]+1, &killsig, 0))) 341 if (optn) 342 opt |= optn; 343 else if (argv[i][0] == '-') { 344 killsig = get_signum(argv[i]+1); 345 if (killsig < 0) 339 346 killsig = SIGTERM; 340 } 341 else { 347 } else { 342 348 fni = xrealloc(fni, sizeof(int) * (fnic+2)); 343 349 fni[fnic++] = i; 344 350 } 345 351 } 346 if(!fnic) return 1; 347 348 pids = xmalloc(sizeof(pid_list)); 352 353 if (!fnic) 354 return 1; 355 349 356 inodes = xmalloc(sizeof(inode_list)); 350 for (i=0;i<fnic;i++) {351 if (fuser_parse_net_arg(argv[fni[i]], &proto, &port)) {357 for (i = 0; i < fnic; i++) { 358 if (fuser_parse_net_arg(argv[fni[i]], &proto, &port)) { 352 359 fuser_scan_proc_net(opt, proto, port, inodes); 353 } 354 else { 355 if(!fuser_file_to_dev_inode( 356 argv[fni[i]], &dev, &inode)) { 357 free(pids); 358 free(inodes); 359 bb_perror_msg_and_die( 360 "Could not open '%s'", argv[fni[i]]); 360 } else { 361 if (!fuser_file_to_dev_inode(argv[fni[i]], &dev, &inode)) { 362 if (ENABLE_FEATURE_CLEAN_UP) 363 free(inodes); 364 bb_perror_msg_and_die("cannot open '%s'", argv[fni[i]]); 361 365 } 362 366 fuser_add_inode(inodes, dev, inode); 363 367 } 364 368 } 369 pids = xmalloc(sizeof(pid_list)); 365 370 success = fuser_scan_proc_pids(opt, inodes, pids); 366 371 /* if the first pid in the list is 0, none have been found */ 367 if(pids->pid == 0) success = 0; 368 if(success) { 369 if(opt & FUSER_OPT_KILL) { 372 if (pids->pid == 0) 373 success = 0; 374 if (success) { 375 if (opt & FUSER_OPT_KILL) { 370 376 success = fuser_kill_pid_list(pids, killsig); 371 } 372 else if(!(opt & FUSER_OPT_SILENT)) { 377 } else if (!(opt & FUSER_OPT_SILENT)) { 373 378 success = fuser_print_pid_list(pids); 374 379 } 375 380 } 376 free(pids); 377 free(inodes); 381 if (ENABLE_FEATURE_CLEAN_UP) { 382 free(pids); 383 free(inodes); 384 } 378 385 /* return 0 on (success == 1) 1 otherwise */ 379 386 return (success != 1); -
branches/2.2.5/mindi-busybox/procps/kill.c
r821 r1765 1 1 /* vi: set sw=4 ts=4: */ 2 2 /* 3 * Mini kill/killall implementation for busybox3 * Mini kill/killall[5] implementation for busybox 4 4 * 5 5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>. … … 9 9 */ 10 10 11 #include "busybox.h" 12 #include <stdio.h> 13 #include <stdlib.h> 14 #include <errno.h> 15 #include <unistd.h> 16 #include <signal.h> 17 #include <ctype.h> 18 #include <string.h> 19 #include <unistd.h> 11 #include "libbb.h" 20 12 21 #define KILL 0 22 #define KILLALL 1 13 /* Note: kill_main is directly called from shell in order to implement 14 * kill built-in. Shell substitutes job ids with process groups first. 15 * 16 * This brings some complications: 17 * 18 * + we can't use xfunc here 19 * + we can't use applet_name 20 * + we can't use bb_show_usage 21 * (Above doesn't apply for killall[5] cases) 22 * 23 * kill %n gets translated into kill ' -<process group>' by shell (note space!) 24 * This is needed to avoid collision with kill -9 ... syntax 25 */ 23 26 27 int kill_main(int argc, char **argv); 24 28 int kill_main(int argc, char **argv) 25 29 { 26 int whichApp, signo = SIGTERM; 27 const char *name; 28 int errors = 0; 29 30 #ifdef CONFIG_KILLALL 31 int quiet=0; 32 /* Figure out what we are trying to do here */ 33 whichApp = (strcmp(bb_applet_name, "killall") == 0)? KILLALL : KILL; 30 char *arg; 31 pid_t pid; 32 int signo = SIGTERM, errors = 0, quiet = 0; 33 #if !ENABLE_KILLALL && !ENABLE_KILLALL5 34 #define killall 0 35 #define killall5 0 34 36 #else 35 whichApp = KILL; 37 /* How to determine who we are? find 3rd char from the end: 38 * kill, killall, killall5 39 * ^i ^a ^l - it's unique 40 * (checking from the start is complicated by /bin/kill... case) */ 41 const char char3 = argv[0][strlen(argv[0]) - 3]; 42 #define killall (ENABLE_KILLALL && char3 == 'a') 43 #define killall5 (ENABLE_KILLALL5 && char3 == 'l') 36 44 #endif 37 45 38 46 /* Parse any options */ 39 if (argc < 2)40 bb_show_usage();47 argc--; 48 arg = *++argv; 41 49 42 if(argv[1][0] != '-'){ 43 argv++; 44 argc--; 50 if (argc < 1 || arg[0] != '-') { 45 51 goto do_it_now; 46 52 } 47 53 48 /* The -l option, which prints out signal names. */ 49 if(argv[1][1]=='l' && argv[1][2]=='\0'){ 50 if(argc==2) { 54 /* The -l option, which prints out signal names. 55 * Intended usage in shell: 56 * echo "Died of SIG`kill -l $?`" 57 * We try to mimic what kill from coreutils-6.8 does */ 58 if (arg[1] == 'l' && arg[2] == '\0') { 59 if (argc == 1) { 51 60 /* Print the whole signal list */ 52 int col = 0; 53 for(signo=1; signo < NSIG; signo++) { 54 name = u_signal_names(0, &signo, 1); 55 if(name==NULL) /* unnamed */ 56 continue; 57 col += printf("%2d) %-16s", signo, name); 58 if (col > 60) { 59 printf("\n"); 60 col = 0; 61 for (signo = 1; signo < 32; signo++) { 62 const char *name = get_signame(signo); 63 if (!isdigit(name[0])) 64 puts(name); 65 } 66 } else { /* -l <sig list> */ 67 while ((arg = *++argv)) { 68 if (isdigit(arg[0])) { 69 signo = bb_strtou(arg, NULL, 10); 70 if (errno) { 71 bb_error_msg("unknown signal '%s'", arg); 72 return EXIT_FAILURE; 73 } 74 /* Exitcodes >= 0x80 are to be treated 75 * as "killed by signal (exitcode & 0x7f)" */ 76 puts(get_signame(signo & 0x7f)); 77 /* TODO: 'bad' signal# - coreutils says: 78 * kill: 127: invalid signal 79 * we just print "127" instead */ 80 } else { 81 signo = get_signum(arg); 82 if (signo < 0) { 83 bb_error_msg("unknown signal '%s'", arg); 84 return EXIT_FAILURE; 85 } 86 printf("%d\n", signo); 61 87 } 62 88 } 63 printf("\n");64 65 } else {66 for(argv++; *argv; argv++) {67 name = u_signal_names(*argv, &signo, -1);68 if(name!=NULL)69 printf("%s\n", name);70 }71 89 } 72 /* If they specified -l, we re all done */90 /* If they specified -l, we are all done */ 73 91 return EXIT_SUCCESS; 74 92 } 75 93 76 #ifdef CONFIG_KILLALL77 94 /* The -q quiet option */ 78 if (whichApp != KILL && argv[1][1]=='q' && argv[1][2]=='\0'){79 quiet ++;80 arg v++;95 if (killall && arg[1] == 'q' && arg[2] == '\0') { 96 quiet = 1; 97 arg = *++argv; 81 98 argc--; 82 if(argc<2 || argv[1][0] != '-'){ 83 goto do_it_now; 84 } 99 if (argc < 1) bb_show_usage(); 100 if (arg[0] != '-') goto do_it_now; 85 101 } 86 #endif87 102 88 if(!u_signal_names(argv[1]+1, &signo, 0)) 89 bb_error_msg_and_die( "bad signal name '%s'", argv[1]+1); 90 argv+=2; 91 argc-=2; 103 /* -SIG */ 104 signo = get_signum(&arg[1]); 105 if (signo < 0) { /* || signo > MAX_SIGNUM ? */ 106 bb_error_msg("bad signal name '%s'", &arg[1]); 107 return EXIT_FAILURE; 108 } 109 arg = *++argv; 110 argc--; 92 111 93 112 do_it_now: 94 113 95 /* Pid or name required */96 if (argc <= 0)97 bb_show_usage();114 if (killall5) { 115 pid_t sid; 116 procps_status_t* p = NULL; 98 117 99 if (whichApp == KILL) { 100 /* Looks like they want to do a kill. Do that */ 101 while (--argc >= 0) { 102 int pid; 118 /* Now stop all processes */ 119 kill(-1, SIGSTOP); 120 /* Find out our own session id */ 121 pid = getpid(); 122 sid = getsid(pid); 123 /* Now kill all processes except our session */ 124 while ((p = procps_scan(p, PSSCAN_PID|PSSCAN_SID))) { 125 if (p->sid != sid && p->pid != pid && p->pid != 1) 126 kill(p->pid, signo); 127 } 128 /* And let them continue */ 129 kill(-1, SIGCONT); 130 return 0; 131 } 103 132 104 if (!isdigit(**argv) && **argv != '-') 105 bb_error_msg_and_die( "Bad PID '%s'", *argv); 106 pid = strtol(*argv, NULL, 0); 107 if (kill(pid, signo) != 0) { 108 bb_perror_msg( "Could not kill pid '%d'", pid); 133 /* Pid or name is required for kill/killall */ 134 if (argc < 1) { 135 puts("You need to specify whom to kill"); 136 return EXIT_FAILURE; 137 } 138 139 if (killall) { 140 /* Looks like they want to do a killall. Do that */ 141 pid = getpid(); 142 while (arg) { 143 pid_t* pidList; 144 145 pidList = find_pid_by_name(arg); 146 if (*pidList == 0) { 109 147 errors++; 110 } 111 argv++; 112 } 148 if (!quiet) 149 bb_error_msg("%s: no process killed", arg); 150 } else { 151 pid_t *pl; 113 152 114 } 115 #ifdef CONFIG_KILLALL 116 else { 117 pid_t myPid=getpid(); 118 /* Looks like they want to do a killall. Do that */ 119 while (--argc >= 0) { 120 long* pidList; 121 122 pidList = find_pid_by_name(*argv); 123 if (!pidList || *pidList<=0) { 124 errors++; 125 if (quiet==0) 126 bb_error_msg( "%s: no process killed", *argv); 127 } else { 128 long *pl; 129 130 for(pl = pidList; *pl !=0 ; pl++) { 131 if (*pl==myPid) 153 for (pl = pidList; *pl; pl++) { 154 if (*pl == pid) 132 155 continue; 133 if (kill(*pl, signo) != 0) {134 errors++;135 if (quiet==0)136 bb_perror_msg( "Could not kill pid '%ld'", *pl);137 }156 if (kill(*pl, signo) == 0) 157 continue; 158 errors++; 159 if (!quiet) 160 bb_perror_msg("cannot kill pid %u", (unsigned)*pl); 138 161 } 139 162 } 140 163 free(pidList); 141 arg v++;164 arg = *++argv; 142 165 } 166 return errors; 143 167 } 144 #endif 168 169 /* Looks like they want to do a kill. Do that */ 170 while (arg) { 171 /* Support shell 'space' trick */ 172 if (arg[0] == ' ') 173 arg++; 174 pid = bb_strtoi(arg, NULL, 10); 175 if (errno) { 176 bb_error_msg("bad pid '%s'", arg); 177 errors++; 178 } else if (kill(pid, signo) != 0) { 179 bb_perror_msg("cannot kill pid %d", (int)pid); 180 errors++; 181 } 182 arg = *++argv; 183 } 145 184 return errors; 146 185 } -
branches/2.2.5/mindi-busybox/procps/pidof.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * Licensed under the GPL v 2, see the file LICENSE in this tarball.7 * Licensed under the GPL version 2, see the file LICENSE in this tarball. 8 8 */ 9 9 10 #include "busybox.h" 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <errno.h> 14 #include <unistd.h> 15 #include <signal.h> 16 #include <ctype.h> 17 #include <string.h> 18 #include <sys/types.h> 19 #include <unistd.h> 10 #include "libbb.h" 20 11 21 #if ENABLE_FEATURE_PIDOF_SINGLE 22 #define _SINGLE_COMPL(a) a 23 #define SINGLE (1<<0) 24 #else 25 #define _SINGLE_COMPL(a) 26 #define SINGLE (0) 27 #endif 12 enum { 13 USE_FEATURE_PIDOF_SINGLE(OPTBIT_SINGLE,) 14 USE_FEATURE_PIDOF_OMIT( OPTBIT_OMIT ,) 15 OPT_SINGLE = USE_FEATURE_PIDOF_SINGLE((1<<OPTBIT_SINGLE)) + 0, 16 OPT_OMIT = USE_FEATURE_PIDOF_OMIT( (1<<OPTBIT_OMIT )) + 0, 17 }; 28 18 29 #if ENABLE_FEATURE_PIDOF_OMIT 30 #define _OMIT_COMPL(a) a 31 #define _OMIT(a) ,a 32 #if ENABLE_FEATURE_PIDOF_SINGLE 33 #define OMIT (1<<1) 34 #else 35 #define OMIT (1<<0) 36 #endif 37 #else 38 #define _OMIT_COMPL(a) "" 39 #define _OMIT(a) 40 #define OMIT (0) 41 #define omitted (0) 42 #endif 43 19 int pidof_main(int argc, char **argv); 44 20 int pidof_main(int argc, char **argv) 45 21 { 46 unsigned n = 0; 47 unsigned fail = 1; 48 unsigned long int opt; 22 unsigned first = 1; 23 unsigned opt; 49 24 #if ENABLE_FEATURE_PIDOF_OMIT 25 char ppid_str[sizeof(int)*3 + 1]; 50 26 llist_t *omits = NULL; /* list of pids to omit */ 51 bb_opt_complementally = _OMIT_COMPL("o::");27 opt_complementary = "o::"; 52 28 #endif 53 29 54 30 /* do unconditional option parsing */ 55 opt = bb_getopt_ulflags(argc, argv,56 _SINGLE_COMPL("s") _OMIT_COMPL("o:")57 _OMIT(&omits));31 opt = getopt32(argv, "" 32 USE_FEATURE_PIDOF_SINGLE ("s") 33 USE_FEATURE_PIDOF_OMIT("o:", &omits)); 58 34 59 35 #if ENABLE_FEATURE_PIDOF_OMIT 60 36 /* fill omit list. */ 61 37 { 62 char getppid_str[32]; 63 llist_t * omits_p = omits; 38 llist_t *omits_p = omits; 64 39 while (omits_p) { 65 40 /* are we asked to exclude the parent's process ID? */ 66 if (!strncmp(omits_p->data, "%PPID", 5)) { 67 llist_pop(&omits_p); 68 snprintf(getppid_str, sizeof(getppid_str), "%d", getppid()); 69 llist_add_to(&omits_p, getppid_str); 41 if (strcmp(omits_p->data, "%PPID") == 0) { 42 sprintf(ppid_str, "%u", (unsigned)getppid()); 43 omits_p->data = ppid_str; 70 44 } 71 45 omits_p = omits_p->link; … … 74 48 #endif 75 49 /* Looks like everything is set to go. */ 76 while (optind < argc) {77 long*pidList;78 long*pl;50 while (optind < argc) { 51 pid_t *pidList; 52 pid_t *pl; 79 53 80 54 /* reverse the pidlist like GNU pidof does. */ 81 55 pidList = pidlist_reverse(find_pid_by_name(argv[optind])); 82 for (pl = pidList; *pl > 0; pl++) {56 for (pl = pidList; *pl; pl++) { 83 57 #if ENABLE_FEATURE_PIDOF_OMIT 84 unsigned omitted = 0; 85 if (opt & OMIT) { 58 if (opt & OPT_OMIT) { 86 59 llist_t *omits_p = omits; 87 while (omits_p) 88 if (strtol(omits_p->data, NULL, 10) == *pl) { 89 omitted = 1; break; 90 } else 91 omits_p = omits_p->link; 60 while (omits_p) { 61 if (xatoul(omits_p->data) == *pl) { 62 goto omitting; 63 } 64 omits_p = omits_p->link; 65 } 92 66 } 93 67 #endif 94 if (!omitted) { 95 if (n) { 96 putchar(' '); 97 } else { 98 n = 1; 99 } 100 printf("%ld", *pl); 101 } 102 fail = (!ENABLE_FEATURE_PIDOF_OMIT && omitted); 103 104 if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & SINGLE)) 68 printf(" %u" + first, (unsigned)*pl); 69 first = 0; 70 if (ENABLE_FEATURE_PIDOF_SINGLE && (opt & OPT_SINGLE)) 105 71 break; 72 #if ENABLE_FEATURE_PIDOF_OMIT 73 omitting: ; 74 #endif 106 75 } 107 76 free(pidList); … … 114 83 llist_free(omits, NULL); 115 84 #endif 116 return f ail ? EXIT_FAILURE : EXIT_SUCCESS;85 return first; /* 1 (failure) - no processes found */ 117 86 } -
branches/2.2.5/mindi-busybox/procps/ps.c
r821 r1765 4 4 * 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * Fix for SELinux Support:(c)2007 Hiroshi Shinji <shiroshi@my.email.ne.jp> 7 (c)2007 Yuichi Nakamura <ynakam@hitachisoft.jp> 6 8 * 7 * Licensed under the GPL v 2, see the file LICENSE in this tarball.9 * Licensed under the GPL version 2, see the file LICENSE in this tarball. 8 10 */ 9 11 10 #include "busybox.h" 11 #include <stdio.h> 12 #include <stdlib.h> 13 #include <unistd.h> 14 #include <dirent.h> 15 #include <errno.h> 16 #include <fcntl.h> 17 #include <ctype.h> 18 #include <string.h> 19 #include <termios.h> 20 #include <sys/ioctl.h> 21 #if ENABLE_SELINUX 22 #include <selinux/selinux.h> /* for is_selinux_enabled() */ 23 #endif 24 12 #include "libbb.h" 13 14 /* Absolute maximum on output line length */ 15 enum { MAX_WIDTH = 2*1024 }; 16 17 #if ENABLE_DESKTOP 18 19 /* Print value to buf, max size+1 chars (including trailing '\0') */ 20 21 static void func_user(char *buf, int size, const procps_status_t *ps) 22 { 23 safe_strncpy(buf, get_cached_username(ps->uid), size+1); 24 } 25 26 static void func_comm(char *buf, int size, const procps_status_t *ps) 27 { 28 safe_strncpy(buf, ps->comm, size+1); 29 } 30 31 static void func_args(char *buf, int size, const procps_status_t *ps) 32 { 33 read_cmdline(buf, size, ps->pid, ps->comm); 34 } 35 36 static void func_pid(char *buf, int size, const procps_status_t *ps) 37 { 38 sprintf(buf, "%*u", size, ps->pid); 39 } 40 41 static void func_ppid(char *buf, int size, const procps_status_t *ps) 42 { 43 sprintf(buf, "%*u", size, ps->ppid); 44 } 45 46 static void func_pgid(char *buf, int size, const procps_status_t *ps) 47 { 48 sprintf(buf, "%*u", size, ps->pgid); 49 } 50 51 static void put_u(char *buf, int size, unsigned u) 52 { 53 char buf5[5]; 54 smart_ulltoa5( ((unsigned long long)u) << 10, buf5); 55 sprintf(buf, "%.*s", size, buf5); 56 } 57 58 static void func_vsz(char *buf, int size, const procps_status_t *ps) 59 { 60 put_u(buf, size, ps->vsz); 61 } 62 63 static void func_rss(char *buf, int size, const procps_status_t *ps) 64 { 65 put_u(buf, size, ps->rss); 66 } 67 68 static void func_tty(char *buf, int size, const procps_status_t *ps) 69 { 70 buf[0] = '?'; 71 buf[1] = '\0'; 72 if (ps->tty_major) /* tty field of "0" means "no tty" */ 73 snprintf(buf, size+1, "%u,%u", ps->tty_major, ps->tty_minor); 74 } 75 76 #if ENABLE_SELINUX 77 static void func_label(char *buf, int size, const procps_status_t *ps) 78 { 79 safe_strncpy(buf, ps->context ? ps->context : "unknown", size+1); 80 } 81 #endif 82 83 /* 84 static void func_nice(char *buf, int size, const procps_status_t *ps) 85 { 86 ps->??? 87 } 88 89 static void func_etime(char *buf, int size, const procps_status_t *ps) 90 { 91 elapled time [[dd-]hh:]mm:ss 92 } 93 94 static void func_time(char *buf, int size, const procps_status_t *ps) 95 { 96 cumulative time [[dd-]hh:]mm:ss 97 } 98 99 static void func_pcpu(char *buf, int size, const procps_status_t *ps) 100 { 101 } 102 */ 103 104 typedef struct { 105 uint16_t width; 106 char name[6]; 107 const char *header; 108 void (*f)(char *buf, int size, const procps_status_t *ps); 109 int ps_flags; 110 } ps_out_t; 111 112 static const ps_out_t out_spec[] = { 113 // Mandated by POSIX: 114 { 8 , "user" ,"USER" ,func_user ,PSSCAN_UIDGID }, 115 { 16 , "comm" ,"COMMAND",func_comm ,PSSCAN_COMM }, 116 { 256 , "args" ,"COMMAND",func_args ,PSSCAN_COMM }, 117 { 5 , "pid" ,"PID" ,func_pid ,PSSCAN_PID }, 118 { 5 , "ppid" ,"PPID" ,func_ppid ,PSSCAN_PPID }, 119 { 5 , "pgid" ,"PGID" ,func_pgid ,PSSCAN_PGID }, 120 // { sizeof("ELAPSED")-1, "etime" ,"ELAPSED",func_etime ,PSSCAN_ }, 121 // { sizeof("GROUP" )-1, "group" ,"GROUP" ,func_group ,PSSCAN_UIDGID }, 122 // { sizeof("NI" )-1, "nice" ,"NI" ,func_nice ,PSSCAN_ }, 123 // { sizeof("%CPU" )-1, "pcpu" ,"%CPU" ,func_pcpu ,PSSCAN_ }, 124 // { sizeof("RGROUP" )-1, "rgroup","RGROUP" ,func_rgroup,PSSCAN_UIDGID }, 125 // { sizeof("RUSER" )-1, "ruser" ,"RUSER" ,func_ruser ,PSSCAN_UIDGID }, 126 // { sizeof("TIME" )-1, "time" ,"TIME" ,func_time ,PSSCAN_ }, 127 { 6 , "tty" ,"TT" ,func_tty ,PSSCAN_TTY }, 128 { 4 , "vsz" ,"VSZ" ,func_vsz ,PSSCAN_VSZ }, 129 // Not mandated by POSIX, but useful: 130 { 4 , "rss" ,"RSS" ,func_rss ,PSSCAN_RSS }, 131 #if ENABLE_SELINUX 132 { 35 , "label" ,"LABEL" ,func_label ,PSSCAN_CONTEXT }, 133 #endif 134 }; 135 136 #if ENABLE_SELINUX 137 #define SELINIX_O_PREFIX "label," 138 #define DEFAULT_O_STR SELINIX_O_PREFIX "pid,user" /* TODO: ,vsz,stat */ ",args" 139 #else 140 #define DEFAULT_O_STR "pid,user" /* TODO: ,vsz,stat */ ",args" 141 #endif 142 143 struct globals { 144 ps_out_t* out; 145 int out_cnt; 146 int print_header; 147 int need_flags; 148 char *buffer; 149 unsigned terminal_width; 150 char default_o[sizeof(DEFAULT_O_STR)]; 151 }; 152 #define G (*(struct globals*)&bb_common_bufsiz1) 153 #define out (G.out ) 154 #define out_cnt (G.out_cnt ) 155 #define print_header (G.print_header ) 156 #define need_flags (G.need_flags ) 157 #define buffer (G.buffer ) 158 #define terminal_width (G.terminal_width) 159 #define default_o (G.default_o ) 160 161 static ps_out_t* new_out_t(void) 162 { 163 int i = out_cnt++; 164 out = xrealloc(out, out_cnt * sizeof(*out)); 165 return &out[i]; 166 } 167 168 static const ps_out_t* find_out_spec(const char *name) 169 { 170 int i; 171 for (i = 0; i < ARRAY_SIZE(out_spec); i++) { 172 if (!strcmp(name, out_spec[i].name)) 173 return &out_spec[i]; 174 } 175 bb_error_msg_and_die("bad -o argument '%s'", name); 176 } 177 178 static void parse_o(char* opt) 179 { 180 ps_out_t* new; 181 // POSIX: "-o is blank- or comma-separated list" (FIXME) 182 char *comma, *equal; 183 while (1) { 184 comma = strchr(opt, ','); 185 equal = strchr(opt, '='); 186 if (comma && (!equal || equal > comma)) { 187 *comma = '\0'; 188 *new_out_t() = *find_out_spec(opt); 189 *comma = ','; 190 opt = comma + 1; 191 continue; 192 } 193 break; 194 } 195 // opt points to last spec in comma separated list. 196 // This one can have =HEADER part. 197 new = new_out_t(); 198 if (equal) 199 *equal = '\0'; 200 *new = *find_out_spec(opt); 201 if (equal) { 202 *equal = '='; 203 new->header = equal + 1; 204 // POSIX: the field widths shall be ... at least as wide as 205 // the header text (default or overridden value). 206 // If the header text is null, such as -o user=, 207 // the field width shall be at least as wide as the 208 // default header text 209 if (new->header[0]) { 210 new->width = strlen(new->header); 211 print_header = 1; 212 } 213 } else 214 print_header = 1; 215 } 216 217 static void post_process(void) 218 { 219 int i; 220 int width = 0; 221 for (i = 0; i < out_cnt; i++) { 222 need_flags |= out[i].ps_flags; 223 if (out[i].header[0]) { 224 print_header = 1; 225 } 226 width += out[i].width + 1; /* "FIELD " */ 227 } 228 #if ENABLE_SELINUX 229 if (!is_selinux_enabled()) 230 need_flags &= ~PSSCAN_CONTEXT; 231 #endif 232 buffer = xmalloc(width + 1); /* for trailing \0 */ 233 } 234 235 static void format_header(void) 236 { 237 int i; 238 ps_out_t* op; 239 char *p; 240 241 if (!print_header) 242 return; 243 p = buffer; 244 i = 0; 245 if (out_cnt) { 246 while (1) { 247 op = &out[i]; 248 if (++i == out_cnt) /* do not pad last field */ 249 break; 250 p += sprintf(p, "%-*s ", op->width, op->header); 251 } 252 strcpy(p, op->header); 253 } 254 printf("%.*s\n", terminal_width, buffer); 255 } 256 257 static void format_process(const procps_status_t *ps) 258 { 259 int i, len; 260 char *p = buffer; 261 i = 0; 262 if (out_cnt) while (1) { 263 out[i].f(p, out[i].width, ps); 264 // POSIX: Any field need not be meaningful in all 265 // implementations. In such a case a hyphen ( '-' ) 266 // should be output in place of the field value. 267 if (!p[0]) { 268 p[0] = '-'; 269 p[1] = '\0'; 270 } 271 len = strlen(p); 272 p += len; 273 len = out[i].width - len + 1; 274 if (++i == out_cnt) /* do not pad last field */ 275 break; 276 p += sprintf(p, "%*s", len, ""); 277 } 278 printf("%.*s\n", terminal_width, buffer); 279 } 280 281 int ps_main(int argc, char **argv); 25 282 int ps_main(int argc, char **argv) 26 283 { 27 procps_status_t * p; 28 int i, len; 29 30 #if ENABLE_SELINUX 31 int use_selinux = 0; 32 security_context_t sid=NULL; 33 #endif 34 35 #if ENABLE_FEATURE_PS_WIDE 284 procps_status_t *p; 285 llist_t* opt_o = NULL; 286 USE_SELINUX(int opt;) 287 288 // POSIX: 289 // -a Write information for all processes associated with terminals 290 // Implementations may omit session leaders from this list 291 // -A Write information for all processes 292 // -d Write information for all processes, except session leaders 293 // -e Write information for all processes (equivalent to -A.) 294 // -f Generate a full listing 295 // -l Generate a long listing 296 // -o col1,col2,col3=header 297 // Select which columns to display 298 /* We allow (and ignore) most of the above. FIXME */ 299 opt_complementary = "o::"; 300 USE_SELINUX(opt =) getopt32(argv, "Zo:aAdefl", &opt_o); 301 if (opt_o) { 302 do { 303 parse_o(opt_o->data); 304 opt_o = opt_o->link; 305 } while (opt_o); 306 } else { 307 /* Below: parse_o() needs char*, NOT const char*... */ 308 #if ENABLE_SELINUX 309 if (!(opt & 1) || !is_selinux_enabled()) { 310 /* no -Z or no SELinux: do not show LABEL */ 311 strcpy(default_o, DEFAULT_O_STR + sizeof(SELINIX_O_PREFIX)-1); 312 } else 313 #endif 314 { 315 strcpy(default_o, DEFAULT_O_STR); 316 } 317 parse_o(default_o); 318 } 319 post_process(); 320 321 /* Was INT_MAX, but some libc's go belly up with printf("%.*s") 322 * and such large widths */ 323 terminal_width = MAX_WIDTH; 324 if (isatty(1)) { 325 get_terminal_width_height(0, &terminal_width, NULL); 326 if (--terminal_width > MAX_WIDTH) 327 terminal_width = MAX_WIDTH; 328 } 329 format_header(); 330 331 p = NULL; 332 while ((p = procps_scan(p, need_flags))) { 333 format_process(p); 334 } 335 336 return EXIT_SUCCESS; 337 } 338 339 340 #else /* !ENABLE_DESKTOP */ 341 342 343 int ps_main(int argc, char **argv); 344 int ps_main(int argc, char **argv) 345 { 346 procps_status_t *p = NULL; 347 int len; 348 SKIP_SELINUX(const) int use_selinux = 0; 349 USE_SELINUX(int i;) 350 #if !ENABLE_FEATURE_PS_WIDE 351 enum { terminal_width = 79 }; 352 #else 36 353 int terminal_width; 37 354 int w_count = 0; 38 39 bb_opt_complementally="-:ww";40 #else41 # define terminal_width 7942 355 #endif 43 356 44 357 #if ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX 45 /* handle arguments */46 #if ENABLE_FEATURE_PS_WIDE && ENABLE_SELINUX47 i = bb_getopt_ulflags(argc, argv, "wc", &w_count);48 #elif ENABLE_FEATURE_PS_WIDE && !ENABLE_SELINUX49 bb_getopt_ulflags(argc, argv, "w", &w_count);50 #else /* !ENABLE_FEATURE_PS_WIDE && ENABLE_SELINUX */51 i = bb_getopt_ulflags(argc, argv, "c");52 #endif53 358 #if ENABLE_FEATURE_PS_WIDE 359 opt_complementary = "-:ww"; 360 USE_SELINUX(i =) getopt32(argv, USE_SELINUX("Z") "w", &w_count); 54 361 /* if w is given once, GNU ps sets the width to 132, 55 362 * if w is given more than once, it is "unlimited" 56 363 */ 57 if (w_count) {58 terminal_width = (w_count==1) ? 132 : INT_MAX;364 if (w_count) { 365 terminal_width = (w_count==1) ? 132 : MAX_WIDTH; 59 366 } else { 60 get_terminal_width_height( 1, &terminal_width, NULL);367 get_terminal_width_height(0, &terminal_width, NULL); 61 368 /* Go one less... */ 62 terminal_width--; 63 } 64 #endif 65 #if ENABLE_SELINUX 66 if ((i & (1+ENABLE_FEATURE_PS_WIDE)) && is_selinux_enabled()) 67 use_selinux = 1; 68 #endif 69 #endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */ 70 71 #if ENABLE_SELINUX 369 if (--terminal_width > MAX_WIDTH) 370 terminal_width = MAX_WIDTH; 371 } 372 #else /* only ENABLE_SELINUX */ 373 i = getopt32(argv, "Z"); 374 #endif 375 #if ENABLE_SELINUX 376 if ((i & 1) && is_selinux_enabled()) 377 use_selinux = PSSCAN_CONTEXT; 378 #endif 379 #endif /* ENABLE_FEATURE_PS_WIDE || ENABLE_SELINUX */ 380 72 381 if (use_selinux) 73 printf(" PID Context Stat Command\n");382 puts(" PID Context Stat Command"); 74 383 else 75 #endif 76 printf(" PID Uid VmSize Stat Command\n"); 77 78 while ((p = procps_scan(1)) != 0) { 79 char *namecmd = p->cmd; 80 #if ENABLE_SELINUX 81 if (use_selinux) 82 { 83 char sbuf[128]; 84 len = sizeof(sbuf); 85 86 if (is_selinux_enabled()) { 87 if (getpidcon(p->pid,&sid)<0) 88 sid=NULL; 89 } 90 91 if (sid) { 92 /* I assume sid initilized with NULL */ 93 len = strlen(sid)+1; 94 safe_strncpy(sbuf, sid, len); 95 freecon(sid); 96 sid=NULL; 97 }else { 98 safe_strncpy(sbuf, "unknown",7); 99 } 100 len = printf("%5d %-32s %s ", p->pid, sbuf, p->state); 101 } 102 else 103 #endif 104 if(p->rss == 0) 105 len = printf("%5d %-8s %s ", p->pid, p->user, p->state); 106 else 107 len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state); 108 109 i = terminal_width-len; 110 111 if(namecmd && namecmd[0]) { 112 if(i < 0) 113 i = 0; 114 if(strlen(namecmd) > (size_t)i) 115 namecmd[i] = 0; 116 printf("%s\n", namecmd); 117 } else { 118 namecmd = p->short_cmd; 119 if(i < 2) 120 i = 2; 121 if(strlen(namecmd) > ((size_t)i-2)) 122 namecmd[i-2] = 0; 123 printf("[%s]\n", namecmd); 124 } 125 /* no check needed, but to make valgrind happy.. */ 126 if (ENABLE_FEATURE_CLEAN_UP && p->cmd) 127 free(p->cmd); 128 } 384 puts(" PID Uid VSZ Stat Command"); 385 386 while ((p = procps_scan(p, 0 387 | PSSCAN_PID 388 | PSSCAN_UIDGID 389 | PSSCAN_STATE 390 | PSSCAN_VSZ 391 | PSSCAN_COMM 392 | use_selinux 393 ))) { 394 #if ENABLE_SELINUX 395 if (use_selinux) { 396 len = printf("%5u %-32s %s ", 397 p->pid, 398 p->context ? p->context : "unknown", 399 p->state); 400 } else 401 #endif 402 { 403 const char *user = get_cached_username(p->uid); 404 if (p->vsz == 0) 405 len = printf("%5u %-8s %s ", 406 p->pid, user, p->state); 407 else 408 len = printf("%5u %-8s %6u %s ", 409 p->pid, user, p->vsz, p->state); 410 } 411 412 { 413 int sz = terminal_width - len; 414 char buf[sz + 1]; 415 read_cmdline(buf, sz, p->pid, p->comm); 416 puts(buf); 417 } 418 } 419 if (ENABLE_FEATURE_CLEAN_UP) 420 clear_username_cache(); 129 421 return EXIT_SUCCESS; 130 422 } 423 424 #endif /* ENABLE_DESKTOP */ -
branches/2.2.5/mindi-busybox/procps/renice.c
r821 r1765 20 20 */ 21 21 22 #include "busybox.h" 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 #include <limits.h> 27 #include <errno.h> 28 #include <unistd.h> 22 #include "libbb.h" 29 23 #include <sys/resource.h> 30 24 31 #if (PRIO_PROCESS < CHAR_MIN) || (PRIO_PROCESS > CHAR_MAX) 32 #error Assumption violated : PRIO_PROCESS value 33 #endif 34 #if (PRIO_PGRP < CHAR_MIN) || (PRIO_PGRP > CHAR_MAX) 35 #error Assumption violated : PRIO_PGRP value 36 #endif 37 #if (PRIO_USER < CHAR_MIN) || (PRIO_USER > CHAR_MAX) 38 #error Assumption violated : PRIO_USER value 39 #endif 25 void BUG_bad_PRIO_PROCESS(void); 26 void BUG_bad_PRIO_PGRP(void); 27 void BUG_bad_PRIO_USER(void); 40 28 41 static inline int int_add_no_wrap(int a, int b) 42 { 43 int s = a + b; 44 45 if (b < 0) { 46 if (s > a) s = INT_MIN; 47 } else { 48 if (s < a) s = INT_MAX; 49 } 50 51 return s; 52 } 53 29 int renice_main(int argc, char **argv); 54 30 int renice_main(int argc, char **argv) 55 31 { 56 static const char Xetpriority_msg[] = "%d :%cetpriority";32 static const char Xetpriority_msg[] ALIGN1 = "%cetpriority"; 57 33 58 34 int retval = EXIT_SUCCESS; … … 60 36 int use_relative = 0; 61 37 int adjustment, new_priority; 62 id_t who; 38 unsigned who; 39 char *arg; 63 40 64 ++argv; 41 /* Yes, they are not #defines in glibc 2.4! #if won't work */ 42 if (PRIO_PROCESS < CHAR_MIN || PRIO_PROCESS > CHAR_MAX) 43 BUG_bad_PRIO_PROCESS(); 44 if (PRIO_PGRP < CHAR_MIN || PRIO_PGRP > CHAR_MAX) 45 BUG_bad_PRIO_PGRP(); 46 if (PRIO_USER < CHAR_MIN || PRIO_USER > CHAR_MAX) 47 BUG_bad_PRIO_USER(); 48 49 arg = *++argv; 65 50 66 51 /* Check if we are using a relative adjustment. */ 67 if (arg v[0] && (argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) {52 if (arg && arg[0] == '-' && arg[1] == 'n') { 68 53 use_relative = 1; 69 ++argv; 54 if (!arg[2]) 55 arg = *++argv; 56 else 57 arg += 2; 70 58 } 71 59 72 if (! *argv) { /* No args? Then show usage. */60 if (!arg) { /* No args? Then show usage. */ 73 61 bb_show_usage(); 74 62 } 75 63 76 64 /* Get the priority adjustment (absolute or relative). */ 77 adjustment = bb_xgetlarg(*argv, 10, INT_MIN, INT_MAX);65 adjustment = xatoi_range(arg, INT_MIN/2, INT_MAX/2); 78 66 79 while ( *++argv) {67 while ((arg = *++argv) != NULL) { 80 68 /* Check for a mode switch. */ 81 if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) { 82 static const char opts[] 83 = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER }; 84 const char *p; 85 if ((p = strchr(opts, argv[0][1]))) { 69 if (arg[0] == '-' && arg[1]) { 70 static const char opts[] ALIGN1 = { 71 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER 72 }; 73 const char *p = strchr(opts, arg[1]); 74 if (p) { 86 75 which = p[4]; 87 continue; 76 if (!arg[2]) 77 continue; 78 arg += 2; 88 79 } 89 80 } … … 92 83 if (which == PRIO_USER) { 93 84 struct passwd *p; 94 if (!(p = getpwnam(*argv))) { 95 bb_error_msg("unknown user: %s", *argv); 85 p = getpwnam(arg); 86 if (!p) { 87 bb_error_msg("unknown user: %s", arg); 96 88 goto HAD_ERROR; 97 89 } 98 90 who = p->pw_uid; 99 91 } else { 100 char *e; 101 errno = 0; 102 who = strtoul(*argv, &e, 10); 103 if (*e || (*argv == e) || errno) { 104 bb_error_msg("bad value: %s", *argv); 92 who = bb_strtou(arg, NULL, 10); 93 if (errno) { 94 bb_error_msg("bad value: %s", arg); 105 95 goto HAD_ERROR; 106 96 } … … 114 104 old_priority = getpriority(which, who); 115 105 if (errno) { 116 bb_perror_msg(Xetpriority_msg, who,'g');106 bb_perror_msg(Xetpriority_msg, 'g'); 117 107 goto HAD_ERROR; 118 108 } 119 109 120 new_priority = int_add_no_wrap(old_priority, adjustment);110 new_priority = old_priority + adjustment; 121 111 } else { 122 112 new_priority = adjustment; … … 127 117 } 128 118 129 bb_perror_msg(Xetpriority_msg, who,'s');130 119 bb_perror_msg(Xetpriority_msg, 's'); 120 HAD_ERROR: 131 121 retval = EXIT_FAILURE; 132 122 } -
branches/2.2.5/mindi-busybox/procps/sysctl.c
r821 r1765 15 15 */ 16 16 17 #include "busybox.h" 18 #include <stdio.h> 19 #include <stdlib.h> 20 #include <unistd.h> 21 #include <sys/stat.h> 22 #include <sys/types.h> 23 #include <dirent.h> 24 #include <string.h> 25 #include <errno.h> 26 #include <fcntl.h> 17 #include "libbb.h" 27 18 28 19 /* … … 37 28 * Globals... 38 29 */ 39 static const char PROC_PATH[] = "/proc/sys/";40 static const char DEFAULT_PRELOAD[] = "/etc/sysctl.conf";30 static const char PROC_PATH[] ALIGN1 = "/proc/sys/"; 31 static const char DEFAULT_PRELOAD[] ALIGN1 = "/etc/sysctl.conf"; 41 32 42 33 /* error messages */ 43 static const char ERR_UNKNOWN_PARAMETER[] = "error: Unknown parameter '%s'\n"; 44 static const char ERR_MALFORMED_SETTING[] = "error: Malformed setting '%s'\n"; 45 static const char ERR_NO_EQUALS[] = 34 static const char ERR_UNKNOWN_PARAMETER[] ALIGN1 = 35 "error: Unknown parameter '%s'\n"; 36 static const char ERR_MALFORMED_SETTING[] ALIGN1 = 37 "error: Malformed setting '%s'\n"; 38 static const char ERR_NO_EQUALS[] ALIGN1 = 46 39 "error: '%s' must be of the form name=value\n"; 47 static const char ERR_INVALID_KEY[] = "error: '%s' is an unknown key\n"; 48 static const char ERR_UNKNOWN_WRITING[] = 40 static const char ERR_INVALID_KEY[] ALIGN1 = 41 "error: '%s' is an unknown key\n"; 42 static const char ERR_UNKNOWN_WRITING[] ALIGN1 = 49 43 "error: unknown error %d setting key '%s'\n"; 50 static const char ERR_UNKNOWN_READING[] =44 static const char ERR_UNKNOWN_READING[] ALIGN1 = 51 45 "error: unknown error %d reading key '%s'\n"; 52 static const char ERR_PERMISSION_DENIED[] =46 static const char ERR_PERMISSION_DENIED[] ALIGN1 = 53 47 "error: permission denied on key '%s'\n"; 54 static const char ERR_PRELOAD_FILE[] =55 "error: unable toopen preload file '%s'\n";56 static const char WARN_BAD_LINE[] =48 static const char ERR_PRELOAD_FILE[] ALIGN1 = 49 "error: cannot open preload file '%s'\n"; 50 static const char WARN_BAD_LINE[] ALIGN1 = 57 51 "warning: %s(%d): invalid syntax, continuing...\n"; 58 52 … … 66 60 * sysctl_main()... 67 61 */ 62 int sysctl_main(int argc, char **argv); 68 63 int sysctl_main(int argc, char **argv) 69 64 { … … 139 134 140 135 while (fgets(oneline, sizeof(oneline) - 1, fp)) { 141 oneline[sizeof(oneline) - 1] = 0;136 oneline[sizeof(oneline) - 1] = '\0'; 142 137 lineno++; 143 138 trim(oneline); … … 166 161 while ((*value == ' ' || *value == '\t') && *value != 0) 167 162 value++; 168 strcpy(buffer, name); 169 strcat(buffer, "="); 170 strcat(buffer, value); 163 /* safe because sizeof(oneline) == sizeof(buffer) */ 164 sprintf(buffer, "%s=%s", name, value); 171 165 sysctl_write_setting(buffer, output); 172 166 } … … 203 197 } 204 198 205 tmpname = bb_xasprintf("%s%.*s", PROC_PATH, (int)(equals - name), name);206 outname = bb_xstrdup(tmpname + strlen(PROC_PATH));199 tmpname = xasprintf("%s%.*s", PROC_PATH, (int)(equals - name), name); 200 outname = xstrdup(tmpname + strlen(PROC_PATH)); 207 201 208 202 while ((cptr = strchr(tmpname, '.')) != NULL) … … 212 206 *cptr = '.'; 213 207 214 if ((fd = open(tmpname, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { 208 fd = open(tmpname, O_WRONLY | O_CREAT | O_TRUNC, 0666); 209 if (fd < 0) { 215 210 switch (errno) { 216 211 case ENOENT: … … 259 254 260 255 tmpname = concat_path_file(PROC_PATH, name); 261 outname = bb_xstrdup(tmpname + strlen(PROC_PATH));256 outname = xstrdup(tmpname + strlen(PROC_PATH)); 262 257 263 258 while ((cptr = strchr(tmpname, '.')) != NULL) … … 310 305 struct stat ts; 311 306 312 if (!(dp = bb_opendir(path))) { 307 dp = opendir(path); 308 if (!dp) { 313 309 retval = -1; 314 310 } else { 315 311 while ((de = readdir(dp)) != NULL) { 316 312 tmpdir = concat_subpath_file(path, de->d_name); 317 if (tmpdir == NULL)313 if (tmpdir == NULL) 318 314 continue; 319 if ((retval2 = stat(tmpdir, &ts)) != 0) 315 retval2 = stat(tmpdir, &ts); 316 if (retval2 != 0) 320 317 bb_perror_msg(tmpdir); 321 318 else { -
branches/2.2.5/mindi-busybox/procps/top.c
r821 r1765 29 29 */ 30 30 31 #include "busybox.h" 32 #include <sys/types.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <unistd.h> 36 #include <string.h> 37 #include <sys/ioctl.h> 38 39 //#define CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE /* + 2k */ 40 41 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE 42 #include <time.h> 43 #include <fcntl.h> 44 #include <netinet/in.h> /* htons */ 45 #endif 46 47 48 typedef int (*cmp_t)(procps_status_t *P, procps_status_t *Q); 49 50 static procps_status_t *top; /* Hehe */ 51 static int ntop; 52 53 #ifdef CONFIG_FEATURE_USE_TERMIOS 54 static int pid_sort(procps_status_t *P, procps_status_t *Q) 55 { 31 #include "libbb.h" 32 33 34 typedef struct top_status_t { 35 unsigned long vsz; 36 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 37 unsigned long ticks; 38 unsigned pcpu; /* delta of ticks */ 39 #endif 40 unsigned pid, ppid; 41 unsigned uid; 42 char state[4]; 43 char comm[COMM_LEN]; 44 } top_status_t; 45 46 typedef struct jiffy_counts_t { 47 unsigned long long usr,nic,sys,idle,iowait,irq,softirq,steal; 48 unsigned long long total; 49 unsigned long long busy; 50 } jiffy_counts_t; 51 52 /* This structure stores some critical information from one frame to 53 the next. Used for finding deltas. */ 54 typedef struct save_hist { 55 unsigned long ticks; 56 unsigned pid; 57 } save_hist; 58 59 typedef int (*cmp_funcp)(top_status_t *P, top_status_t *Q); 60 61 enum { SORT_DEPTH = 3 }; 62 63 struct globals { 64 top_status_t *top; 65 int ntop; 66 #if ENABLE_FEATURE_USE_TERMIOS 67 struct termios initial_settings; 68 #endif 69 #if !ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 70 cmp_funcp sort_function; 71 #else 72 cmp_funcp sort_function[SORT_DEPTH]; 73 struct save_hist *prev_hist; 74 int prev_hist_count; 75 jiffy_counts_t jif, prev_jif; 76 /* int hist_iterations; */ 77 unsigned total_pcpu; 78 /* unsigned long total_vsz; */ 79 #endif 80 }; 81 #define G (*(struct globals*)&bb_common_bufsiz1) 82 #define top (G.top ) 83 #define ntop (G.ntop ) 84 #if ENABLE_FEATURE_USE_TERMIOS 85 #define initial_settings (G. initial_settings ) 86 #endif 87 #define sort_function (G.sort_function ) 88 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 89 #define prev_hist (G.prev_hist ) 90 #define prev_hist_count (G.prev_hist_count ) 91 #define jif (G.jif ) 92 #define prev_jif (G.prev_jif ) 93 #define total_pcpu (G.total_pcpu ) 94 #endif 95 96 #define OPT_BATCH_MODE (option_mask32 & 0x4) 97 98 99 #if ENABLE_FEATURE_USE_TERMIOS 100 static int pid_sort(top_status_t *P, top_status_t *Q) 101 { 102 /* Buggy wrt pids with high bit set */ 103 /* (linux pids are in [1..2^15-1]) */ 56 104 return (Q->pid - P->pid); 57 105 } 58 106 #endif 59 107 60 static int mem_sort(procps_status_t *P, procps_status_t *Q) 61 { 62 return (int)(Q->rss - P->rss); 63 } 64 65 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE 66 67 #define sort_depth 3 68 static cmp_t sort_function[sort_depth]; 69 70 static int pcpu_sort(procps_status_t *P, procps_status_t *Q) 71 { 72 return (Q->pcpu - P->pcpu); 73 } 74 75 static int time_sort(procps_status_t *P, procps_status_t *Q) 76 { 77 return (int)((Q->stime + Q->utime) - (P->stime + P->utime)); 78 } 79 80 static int mult_lvl_cmp(void* a, void* b) { 108 static int mem_sort(top_status_t *P, top_status_t *Q) 109 { 110 /* We want to avoid unsigned->signed and truncation errors */ 111 if (Q->vsz < P->vsz) return -1; 112 return Q->vsz != P->vsz; /* 0 if ==, 1 if > */ 113 } 114 115 116 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 117 118 static int pcpu_sort(top_status_t *P, top_status_t *Q) 119 { 120 /* Buggy wrt ticks with high bit set */ 121 /* Affects only processes for which ticks overflow */ 122 return (int)Q->pcpu - (int)P->pcpu; 123 } 124 125 static int time_sort(top_status_t *P, top_status_t *Q) 126 { 127 /* We want to avoid unsigned->signed and truncation errors */ 128 if (Q->ticks < P->ticks) return -1; 129 return Q->ticks != P->ticks; /* 0 if ==, 1 if > */ 130 } 131 132 static int mult_lvl_cmp(void* a, void* b) 133 { 81 134 int i, cmp_val; 82 135 83 for (i = 0; i < sort_depth; i++) {136 for (i = 0; i < SORT_DEPTH; i++) { 84 137 cmp_val = (*sort_function[i])(a, b); 85 138 if (cmp_val != 0) … … 89 142 } 90 143 91 /* This structure stores some critical information from one frame to92 the next. mostly used for sorting. Added cumulative and resident fields. */93 struct save_hist {94 int ticks;95 int pid;96 };97 98 /*99 * Calculates percent cpu usage for each task.100 */101 102 static struct save_hist *prev_hist;103 static int prev_hist_count;104 /* static int hist_iterations; */105 106 107 static unsigned total_pcpu;108 /* static unsigned long total_rss; */109 110 struct jiffy_counts {111 unsigned long long usr,nic,sys,idle,iowait,irq,softirq,steal;112 unsigned long long total;113 unsigned long long busy;114 };115 static struct jiffy_counts jif, prev_jif;116 144 117 145 static void get_jiffy_counts(void) 118 146 { 119 FILE* fp = bb_xfopen("stat", "r");147 FILE* fp = xfopen("stat", "r"); 120 148 prev_jif = jif; 121 149 if (fscanf(fp, "cpu %lld %lld %lld %lld %lld %lld %lld %lld", 122 150 &jif.usr,&jif.nic,&jif.sys,&jif.idle, 123 151 &jif.iowait,&jif.irq,&jif.softirq,&jif.steal) < 4) { 124 bb_error_msg_and_die("failed to read 'stat'");152 bb_error_msg_and_die("failed to read /proc/stat"); 125 153 } 126 154 fclose(fp); … … 131 159 } 132 160 161 133 162 static void do_stats(void) 134 163 { 135 procps_status_t *cur; 136 int pid, total_time, i, last_i, n; 164 top_status_t *cur; 165 pid_t pid; 166 int i, last_i, n; 137 167 struct save_hist *new_hist; 138 168 139 169 get_jiffy_counts(); 140 170 total_pcpu = 0; 141 /* total_ rss= 0; */171 /* total_vsz = 0; */ 142 172 new_hist = xmalloc(sizeof(struct save_hist)*ntop); 143 173 /* … … 154 184 */ 155 185 pid = cur->pid; 156 total_time = cur->stime + cur->utime; 157 new_hist[n].ticks = total_time; 186 new_hist[n].ticks = cur->ticks; 158 187 new_hist[n].pid = pid; 159 188 … … 165 194 if (prev_hist_count) do { 166 195 if (prev_hist[i].pid == pid) { 167 cur->pcpu = total_time - prev_hist[i].ticks; 196 cur->pcpu = cur->ticks - prev_hist[i].ticks; 197 total_pcpu += cur->pcpu; 168 198 break; 169 199 } … … 171 201 /* hist_iterations++; */ 172 202 } while (i != last_i); 173 total_pcpu += cur->pcpu; 174 /* total_rss += cur->rss; */ 203 /* total_vsz += cur->vsz; */ 175 204 } 176 205 … … 182 211 prev_hist_count = ntop; 183 212 } 184 #else 185 static cmp_t sort_function; 186 #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */ 213 #endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ 214 215 #if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS && ENABLE_FEATURE_TOP_DECIMALS 216 /* formats 7 char string (8 with terminating NUL) */ 217 static char *fmt_100percent_8(char pbuf[8], unsigned value, unsigned total) 218 { 219 unsigned t; 220 if (value >= total) { /* 100% ? */ 221 strcpy(pbuf, " 100% "); 222 return pbuf; 223 } 224 /* else generate " [N/space]N.N% " string */ 225 value = 1000 * value / total; 226 t = value / 100; 227 value = value % 100; 228 pbuf[0] = ' '; 229 pbuf[1] = t ? t + '0' : ' '; 230 pbuf[2] = '0' + (value / 10); 231 pbuf[3] = '.'; 232 pbuf[4] = '0' + (value % 10); 233 pbuf[5] = '%'; 234 pbuf[6] = ' '; 235 pbuf[7] = '\0'; 236 return pbuf; 237 } 238 #endif 187 239 188 240 /* display generic info (meminfo / loadavg) */ … … 192 244 char buf[80]; 193 245 char scrbuf[80]; 194 char *end;195 246 unsigned long total, used, mfree, shared, buffers, cached; 196 unsigned int needs_conversion = 1; 247 #if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS 248 unsigned total_diff; 249 #endif 197 250 198 251 /* read memory info */ 199 fp = bb_xfopen("meminfo", "r");252 fp = xfopen("meminfo", "r"); 200 253 201 254 /* … … 213 266 214 267 fscanf(fp, "Mem: %lu %lu %lu %lu %lu %lu", 215 &total, &used, &mfree, &shared, &buffers, &cached); 216 } else { 217 /* 218 * Revert to manual parsing, which incidentally already has the 219 * sizes in kilobytes. This should be safe for both 2.4 and 220 * 2.6. 221 */ 222 needs_conversion = 0; 223 224 fscanf(fp, "MemFree: %lu %s\n", &mfree, buf); 225 226 /* 227 * MemShared: is no longer present in 2.6. Report this as 0, 228 * to maintain consistent behavior with normal procps. 229 */ 230 if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2) 231 shared = 0; 232 233 fscanf(fp, "Buffers: %lu %s\n", &buffers, buf); 234 fscanf(fp, "Cached: %lu %s\n", &cached, buf); 235 236 used = total - mfree; 237 } 238 fclose(fp); 239 240 /* read load average as a string */ 241 fp = bb_xfopen("loadavg", "r"); 242 buf[0] = '\0'; 243 fgets(buf, sizeof(buf), fp); 244 end = strchr(buf, ' '); 245 if (end) end = strchr(end+1, ' '); 246 if (end) end = strchr(end+1, ' '); 247 if (end) *end = '\0'; 248 fclose(fp); 249 250 if (needs_conversion) { 268 &total, &used, &mfree, &shared, &buffers, &cached); 251 269 /* convert to kilobytes */ 252 270 used /= 1024; … … 256 274 cached /= 1024; 257 275 total /= 1024; 258 } 259 260 /* output memory info and load average */ 261 /* clear screen & go to top */ 276 } else { 277 /* 278 * Revert to manual parsing, which incidentally already has the 279 * sizes in kilobytes. This should be safe for both 2.4 and 280 * 2.6. 281 */ 282 283 fscanf(fp, "MemFree: %lu %s\n", &mfree, buf); 284 285 /* 286 * MemShared: is no longer present in 2.6. Report this as 0, 287 * to maintain consistent behavior with normal procps. 288 */ 289 if (fscanf(fp, "MemShared: %lu %s\n", &shared, buf) != 2) 290 shared = 0; 291 292 fscanf(fp, "Buffers: %lu %s\n", &buffers, buf); 293 fscanf(fp, "Cached: %lu %s\n", &cached, buf); 294 295 used = total - mfree; 296 } 297 fclose(fp); 298 299 /* output memory info */ 262 300 if (scr_width > sizeof(scrbuf)) 263 301 scr_width = sizeof(scrbuf); 264 302 snprintf(scrbuf, scr_width, 265 "Mem: %l dK used, %ldK free, %ldK shrd, %ldK buff, %ldK cached",303 "Mem: %luK used, %luK free, %luK shrd, %luK buff, %luK cached", 266 304 used, mfree, shared, buffers, cached); 267 printf("\e[H\e[J%s\n", scrbuf); 268 snprintf(scrbuf, scr_width, 269 "Load average: %s (Status: S=sleeping R=running, W=waiting)", buf); 270 printf("%s\n", scrbuf); 305 /* clear screen & go to top */ 306 printf(OPT_BATCH_MODE ? "%s\n" : "\e[H\e[J%s\n", scrbuf); 307 308 #if ENABLE_FEATURE_TOP_CPU_GLOBAL_PERCENTS 309 /* 310 * xxx% = (jif.xxx - prev_jif.xxx) / (jif.total - prev_jif.total) * 100% 311 */ 312 /* using (unsigned) casts to make operations cheaper */ 313 total_diff = ((unsigned)(jif.total - prev_jif.total) ? : 1); 314 #if ENABLE_FEATURE_TOP_DECIMALS 315 /* Generated code is approx +0.3k */ 316 #define CALC_STAT(xxx) char xxx[8] 317 #define SHOW_STAT(xxx) fmt_100percent_8(xxx, (unsigned)(jif.xxx - prev_jif.xxx), total_diff) 318 #define FMT "%s" 319 #else 320 #define CALC_STAT(xxx) unsigned xxx = 100 * (unsigned)(jif.xxx - prev_jif.xxx) / total_diff 321 #define SHOW_STAT(xxx) xxx 322 #define FMT "%4u%% " 323 #endif 324 { /* need block: CALC_STAT are declarations */ 325 CALC_STAT(usr); 326 CALC_STAT(sys); 327 CALC_STAT(nic); 328 CALC_STAT(idle); 329 CALC_STAT(iowait); 330 CALC_STAT(irq); 331 CALC_STAT(softirq); 332 //CALC_STAT(steal); 333 334 snprintf(scrbuf, scr_width, 335 /* Barely fits in 79 chars when in "decimals" mode. */ 336 "CPU:"FMT"usr"FMT"sys"FMT"nice"FMT"idle"FMT"io"FMT"irq"FMT"softirq", 337 SHOW_STAT(usr), SHOW_STAT(sys), SHOW_STAT(nic), SHOW_STAT(idle), 338 SHOW_STAT(iowait), SHOW_STAT(irq), SHOW_STAT(softirq) 339 //, SHOW_STAT(steal) - what is this 'steal' thing? 340 // I doubt anyone wants to know it 341 ); 342 } 343 puts(scrbuf); 344 #undef SHOW_STAT 345 #undef CALC_STAT 346 #undef FMT 347 #endif 348 349 /* read load average as a string */ 350 buf[0] = '\0'; 351 open_read_close("loadavg", buf, sizeof("N.NN N.NN N.NN")-1); 352 buf[sizeof("N.NN N.NN N.NN")-1] = '\0'; 353 snprintf(scrbuf, scr_width, "Load average: %s", buf); 354 puts(scrbuf); 271 355 272 356 return total; 273 357 } 274 275 358 276 359 /* display process statuses */ … … 278 361 { 279 362 enum { 280 bits_per_int= sizeof(int)*8363 BITS_PER_INT = sizeof(int)*8 281 364 }; 282 365 283 procps_status_t *s = top; 284 char rss_str_buf[8]; 285 unsigned long total_memory = display_generic(scr_width); /* or use total_rss? */ 286 unsigned pmem_shift, pmem_scale; 287 288 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE 289 unsigned pcpu_shift, pcpu_scale; 366 top_status_t *s = top; 367 char vsz_str_buf[8]; 368 unsigned long total_memory = display_generic(scr_width); /* or use total_vsz? */ 369 /* xxx_shift and xxx_scale variables allow us to replace 370 * expensive divides with multiply and shift */ 371 unsigned pmem_shift, pmem_scale, pmem_half; 372 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 373 unsigned pcpu_shift, pcpu_scale, pcpu_half; 374 unsigned busy_jifs; 290 375 291 376 /* what info of the processes is shown */ 292 printf( "\e[7m%.*s\e[0m", scr_width,293 " PID USER STATUS RSS PPID %CPU %MEMCOMMAND");377 printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, 378 " PID PPID USER STAT VSZ %MEM %CPU COMMAND"); 294 379 #define MIN_WIDTH \ 295 sizeof( " PID USER STATUS RSS PPID %CPU %MEM C") 296 #else 297 printf("\e[7m%.*s\e[0m", scr_width, 298 " PID USER STATUS RSS PPID %MEM COMMAND"); 380 sizeof( " PID PPID USER STAT VSZ %MEM %CPU C") 381 #else 382 383 /* !CPU_USAGE_PERCENTAGE */ 384 printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, 385 " PID PPID USER STAT VSZ %MEM COMMAND"); 299 386 #define MIN_WIDTH \ 300 sizeof( " PID USER STATUS RSS PPID %MEM C") 301 #endif 302 387 sizeof( " PID PPID USER STAT VSZ %MEM C") 388 #endif 389 390 #if ENABLE_FEATURE_TOP_DECIMALS 391 #define UPSCALE 1000 392 #define CALC_STAT(name, val) div_t name = div((val), 10) 393 #define SHOW_STAT(name) name.quot, '0'+name.rem 394 #define FMT "%3u.%c" 395 #else 396 #define UPSCALE 100 397 #define CALC_STAT(name, val) unsigned name = (val) 398 #define SHOW_STAT(name) name 399 #define FMT "%4u%%" 400 #endif 303 401 /* 304 * MEM% = s-> rss/MemTotal402 * MEM% = s->vsz/MemTotal 305 403 */ 306 pmem_shift = bits_per_int-11;307 pmem_scale = 1000*(1U<<(bits_per_int-11)) / total_memory;308 /* s-> rss is in kb. we want (s->rss* pmem_scale) to never overflow */404 pmem_shift = BITS_PER_INT-11; 405 pmem_scale = UPSCALE*(1U<<(BITS_PER_INT-11)) / total_memory; 406 /* s->vsz is in kb. we want (s->vsz * pmem_scale) to never overflow */ 309 407 while (pmem_scale >= 512) { 310 408 pmem_scale /= 4; 311 409 pmem_shift -= 2; 312 410 } 313 #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE 411 pmem_half = (1U << pmem_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2); 412 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 413 busy_jifs = jif.busy - prev_jif.busy; 414 /* This happens if there were lots of short-lived processes 415 * between two top updates (e.g. compilation) */ 416 if (total_pcpu < busy_jifs) total_pcpu = busy_jifs; 417 314 418 /* 315 419 * CPU% = s->pcpu/sum(s->pcpu) * busy_cpu_ticks/total_cpu_ticks … … 321 425 */ 322 426 pcpu_shift = 6; 323 pcpu_scale = ( 1000*64*(uint16_t)(jif.busy-prev_jif.busy)? : 1);324 while (pcpu_scale < (1U<<( bits_per_int-2))) {427 pcpu_scale = (UPSCALE*64*(uint16_t)busy_jifs ? : 1); 428 while (pcpu_scale < (1U<<(BITS_PER_INT-2))) { 325 429 pcpu_scale *= 4; 326 430 pcpu_shift += 2; … … 332 436 pcpu_shift -= 2; 333 437 } 438 pcpu_half = (1U << pcpu_shift) / (ENABLE_FEATURE_TOP_DECIMALS? 20 : 2); 334 439 /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */ 335 440 #endif 336 441 337 while (count--) { 338 div_t pmem = div( (s->rss*pmem_scale) >> pmem_shift, 10); 339 int col = scr_width+1; 340 USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(div_t pcpu;) 341 342 if (s->rss >= 100*1024) 343 sprintf(rss_str_buf, "%6ldM", s->rss/1024); 442 /* Ok, all prelim data is ready, go thru the list */ 443 while (count-- > 0) { 444 int col = scr_width; 445 CALC_STAT(pmem, (s->vsz*pmem_scale + pmem_half) >> pmem_shift); 446 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 447 CALC_STAT(pcpu, (s->pcpu*pcpu_scale + pcpu_half) >> pcpu_shift); 448 #endif 449 450 if (s->vsz >= 100*1024) 451 sprintf(vsz_str_buf, "%6ldM", s->vsz/1024); 344 452 else 345 sprintf(rss_str_buf, "%7ld", s->rss); 346 USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(pcpu = div((s->pcpu*pcpu_scale) >> pcpu_shift, 10);) 347 col -= printf("\n%5d %-8s %s %s%6d%3u.%c" \ 348 USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE("%3u.%c") " ", 349 s->pid, s->user, s->state, rss_str_buf, s->ppid, 350 USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(pcpu.quot, '0'+pcpu.rem,) 351 pmem.quot, '0'+pmem.rem); 352 if (col>0) 353 printf("%.*s", col, s->short_cmd); 453 sprintf(vsz_str_buf, "%7ld", s->vsz); 454 // PID PPID USER STAT VSZ %MEM [%CPU] COMMAND 455 col -= printf("\n" "%5u%6u %-8.8s %s%s" FMT 456 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 457 FMT 458 #endif 459 " ", 460 s->pid, s->ppid, get_cached_username(s->uid), 461 s->state, vsz_str_buf, 462 SHOW_STAT(pmem) 463 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 464 , SHOW_STAT(pcpu) 465 #endif 466 ); 467 if (col > 0) { 468 char buf[col + 1]; 469 read_cmdline(buf, col, s->pid, s->comm); 470 fputs(buf, stdout); 471 } 354 472 /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, 355 473 jif.busy - prev_jif.busy, jif.total - prev_jif.total); */ … … 357 475 } 358 476 /* printf(" %d", hist_iterations); */ 359 putchar( '\r');477 putchar(OPT_BATCH_MODE ? '\n' : '\r'); 360 478 fflush(stdout); 361 479 } 480 #undef UPSCALE 481 #undef SHOW_STAT 482 #undef CALC_STAT 483 #undef FMT 484 362 485 363 486 static void clearmems(void) 364 487 { 488 clear_username_cache(); 365 489 free(top); 366 490 top = 0; … … 368 492 } 369 493 370 #ifdef CONFIG_FEATURE_USE_TERMIOS 494 495 #if ENABLE_FEATURE_USE_TERMIOS 371 496 #include <termios.h> 372 497 #include <signal.h> 373 498 374 375 static struct termios initial_settings;376 377 499 static void reset_term(void) 378 500 { 379 501 tcsetattr(0, TCSANOW, (void *) &initial_settings); 380 #if def CONFIG_FEATURE_CLEAN_UP502 #if ENABLE_FEATURE_CLEAN_UP 381 503 clearmems(); 382 #if def CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE504 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 383 505 free(prev_hist); 384 506 #endif 385 #endif /* CONFIG_FEATURE_CLEAN_UP */507 #endif /* FEATURE_CLEAN_UP */ 386 508 } 387 509 … … 391 513 exit(1); 392 514 } 393 #endif /* CONFIG_FEATURE_USE_TERMIOS */ 394 395 515 #endif /* FEATURE_USE_TERMIOS */ 516 517 518 int top_main(int argc, char **argv); 396 519 int top_main(int argc, char **argv) 397 520 { 398 int opt, interval, lines, col; 399 char *sinterval; 400 #ifdef CONFIG_FEATURE_USE_TERMIOS 521 int count, lines, col; 522 unsigned interval = 5; /* default update rate is 5 seconds */ 523 unsigned iterations = UINT_MAX; /* 2^32 iterations by default :) */ 524 char *sinterval, *siterations; 525 #if ENABLE_FEATURE_USE_TERMIOS 401 526 struct termios new_settings; 402 527 struct timeval tv; 403 528 fd_set readfds; 404 529 unsigned char c; 405 #endif /* CONFIG_FEATURE_USE_TERMIOS */ 530 #endif /* FEATURE_USE_TERMIOS */ 531 532 interval = 5; 406 533 407 534 /* do normal option parsing */ 408 opt = bb_getopt_ulflags(argc, argv, "d:", &sinterval); 409 if ((opt & 1)) { 410 interval = atoi(sinterval); 411 } else { 412 /* Default update rate is 5 seconds */ 413 interval = 5; 414 } 535 opt_complementary = "-"; 536 getopt32(argv, "d:n:b", &sinterval, &siterations); 537 if (option_mask32 & 0x1) interval = xatou(sinterval); // -d 538 if (option_mask32 & 0x2) iterations = xatou(siterations); // -n 539 //if (option_mask32 & 0x4) // -b 415 540 416 541 /* change to /proc */ 417 bb_xchdir("/proc");418 #if def CONFIG_FEATURE_USE_TERMIOS542 xchdir("/proc"); 543 #if ENABLE_FEATURE_USE_TERMIOS 419 544 tcgetattr(0, (void *) &initial_settings); 420 545 memcpy(&new_settings, &initial_settings, sizeof(struct termios)); 421 new_settings.c_lflag &= ~(ISIG | ICANON); /* unbuffered input */ 422 /* Turn off echoing */ 423 new_settings.c_lflag &= ~(ECHO | ECHONL); 546 /* unbuffered input, turn off echo */ 547 new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL); 424 548 425 549 signal(SIGTERM, sig_catcher); … … 427 551 tcsetattr(0, TCSANOW, (void *) &new_settings); 428 552 atexit(reset_term); 429 #endif /* CONFIG_FEATURE_USE_TERMIOS */430 431 #if def CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE553 #endif /* FEATURE_USE_TERMIOS */ 554 555 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 432 556 sort_function[0] = pcpu_sort; 433 557 sort_function[1] = mem_sort; … … 435 559 #else 436 560 sort_function = mem_sort; 437 #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */561 #endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ 438 562 439 563 while (1) { 440 procps_status_t *p ;564 procps_status_t *p = NULL; 441 565 442 566 /* Default to 25 lines - 5 lines for status */ 443 lines = 24 - 3 ;567 lines = 24 - 3 USE_FEATURE_TOP_CPU_GLOBAL_PERCENTS( - 1); 444 568 col = 79; 445 #if def CONFIG_FEATURE_USE_TERMIOS569 #if ENABLE_FEATURE_USE_TERMIOS 446 570 get_terminal_width_height(0, &col, &lines); 447 571 if (lines < 5 || col < MIN_WIDTH) { … … 449 573 continue; 450 574 } 451 lines -= 3 ;452 #endif /* CONFIG_FEATURE_USE_TERMIOS */575 lines -= 3 USE_FEATURE_TOP_CPU_GLOBAL_PERCENTS( + 1); 576 #endif /* FEATURE_USE_TERMIOS */ 453 577 454 578 /* read process IDs & status for all the processes */ 455 while ((p = procps_scan(0)) != 0) { 579 while ((p = procps_scan(p, 0 580 | PSSCAN_PID 581 | PSSCAN_PPID 582 | PSSCAN_VSZ 583 | PSSCAN_STIME 584 | PSSCAN_UTIME 585 | PSSCAN_STATE 586 | PSSCAN_COMM 587 | PSSCAN_SID 588 | PSSCAN_UIDGID 589 ))) { 456 590 int n = ntop; 457 458 top = xrealloc(top, (++ntop)*sizeof(procps_status_t)); 459 memcpy(top + n, p, sizeof(procps_status_t)); 591 top = xrealloc(top, (++ntop) * sizeof(*top)); 592 top[n].pid = p->pid; 593 top[n].ppid = p->ppid; 594 top[n].vsz = p->vsz; 595 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 596 top[n].ticks = p->stime + p->utime; 597 #endif 598 top[n].uid = p->uid; 599 strcpy(top[n].state, p->state); 600 strcpy(top[n].comm, p->comm); 460 601 } 461 602 if (ntop == 0) { 462 bb_error_msg_and_die(" Can't findprocess info in /proc");603 bb_error_msg_and_die("no process info in /proc"); 463 604 } 464 #if def CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE605 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 465 606 if (!prev_hist_count) { 466 607 do_stats(); … … 470 611 } 471 612 do_stats(); 472 qsort(top, ntop, sizeof(procps_status_t), (void*)mult_lvl_cmp); 473 #else 474 qsort(top, ntop, sizeof(procps_status_t), (void*)sort_function); 475 #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */ 476 opt = lines; 477 if (opt > ntop) { 478 opt = ntop; 613 /* TODO: we don't need to sort all 10000 processes, we need to find top 24! */ 614 qsort(top, ntop, sizeof(top_status_t), (void*)mult_lvl_cmp); 615 #else 616 qsort(top, ntop, sizeof(top_status_t), (void*)sort_function); 617 #endif /* FEATURE_TOP_CPU_USAGE_PERCENTAGE */ 618 count = lines; 619 if (OPT_BATCH_MODE || count > ntop) { 620 count = ntop; 479 621 } 480 622 /* show status for each of the processes */ 481 display_status( opt, col);482 #if def CONFIG_FEATURE_USE_TERMIOS623 display_status(count, col); 624 #if ENABLE_FEATURE_USE_TERMIOS 483 625 tv.tv_sec = interval; 484 626 tv.tv_usec = 0; … … 493 635 break; 494 636 if (c == 'M') { 495 #if def CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE637 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 496 638 sort_function[0] = mem_sort; 497 639 sort_function[1] = pcpu_sort; … … 501 643 #endif 502 644 } 503 #if def CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE645 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 504 646 if (c == 'P') { 505 647 sort_function[0] = pcpu_sort; … … 514 656 #endif 515 657 if (c == 'N') { 516 #if def CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE658 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE 517 659 sort_function[0] = pid_sort; 518 660 #else … … 521 663 } 522 664 } 665 if (!--iterations) 666 break; 523 667 #else 524 668 sleep(interval); 525 #endif /* CONFIG_FEATURE_USE_TERMIOS */669 #endif /* FEATURE_USE_TERMIOS */ 526 670 clearmems(); 527 671 } -
branches/2.2.5/mindi-busybox/procps/uptime.c
r821 r1765 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 6 * 7 * Licensed under the GPL v 2 or later, see the file LICENSE in this tarball.7 * Licensed under the GPL version 2, see the file LICENSE in this tarball. 8 8 */ 9 9 … … 16 16 /* getopt not needed */ 17 17 18 #include "busybox.h" 19 #include <stdio.h> 20 #include <time.h> 21 #include <errno.h> 22 #include <stdlib.h> 18 #include "libbb.h" 23 19 24 20 #ifndef FSHIFT … … 30 26 31 27 28 int uptime_main(int argc, char **argv); 32 29 int uptime_main(int argc, char **argv) 33 30 { … … 50 47 uphours = (upminutes / 60) % 24; 51 48 upminutes %= 60; 52 if (uphours)49 if (uphours) 53 50 printf("%2d:%02d, ", uphours, upminutes); 54 51 else
Note:
See TracChangeset
for help on using the changeset viewer.