Changeset 3621 in MondoRescue for branches/3.3/mindi-busybox/procps/nmeter.c
- Timestamp:
- Dec 20, 2016, 4:07:32 PM (7 years ago)
- Location:
- branches/3.3
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/3.3/mindi-busybox/procps/nmeter.c
r3232 r3621 22 22 //usage: "Monitor system in real time" 23 23 //usage: "\n" 24 //usage: "\n -d MSEC Milliseconds between updates (default:1000)"24 //usage: "\n -d MSEC Milliseconds between updates, default:1000, none:-1" 25 25 //usage: "\n" 26 26 //usage: "\nFormat specifiers:" … … 54 54 55 55 #include "libbb.h" 56 #include "common_bufsiz.h" 56 57 57 58 typedef unsigned long long ullong; … … 84 85 // 1 if sample delay is not an integer fraction of a second 85 86 smallint need_seconds; 87 char final_char; 86 88 char *cur_outbuf; 87 const char *final_str;88 89 int delta; 89 intdeltanz;90 unsigned deltanz; 90 91 struct timeval tv; 91 92 #define first_proc_file proc_stat … … 102 103 #define need_seconds (G.need_seconds ) 103 104 #define cur_outbuf (G.cur_outbuf ) 104 #define final_str (G.final_str )105 #define delta (G.delta )106 #define deltanz (G.deltanz )107 105 #define tv (G.tv ) 108 106 #define proc_stat (G.proc_stat ) … … 112 110 #define proc_diskstats (G.proc_diskstats ) 113 111 #define proc_sys_fs_filenr (G.proc_sys_fs_filenr) 112 #define outbuf bb_common_bufsiz1 114 113 #define INIT_G() do { \ 114 setup_common_bufsiz(); \ 115 115 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 116 116 cur_outbuf = outbuf; \ 117 final_str = "\n"; \118 deltanz =delta = 1000000; \117 G.final_char = '\n'; \ 118 G.deltanz = G.delta = 1000000; \ 119 119 } while (0) 120 121 // We depend on this being a char[], not char* - we take sizeof() of it122 #define outbuf bb_common_bufsiz1123 120 124 121 static inline void reset_outbuf(void) … … 143 140 static void put(const char *s) 144 141 { 145 int sz = strlen(s);146 i f (sz > outbuf + sizeof(outbuf) - cur_outbuf)147 sz = outbuf + sizeof(outbuf) - cur_outbuf;148 memcpy(cur_outbuf, s, sz);149 cur_outbuf += sz;142 char *p = cur_outbuf; 143 int sz = outbuf + COMMON_BUFSIZE - p; 144 while (*s && --sz >= 0) 145 *p++ = *s++; 146 cur_outbuf = p; 150 147 } 151 148 152 149 static void put_c(char c) 153 150 { 154 if (cur_outbuf < outbuf + sizeof(outbuf))151 if (cur_outbuf < outbuf + COMMON_BUFSIZE) 155 152 *cur_outbuf++ = c; 156 153 } … … 209 206 } 210 207 211 enum conv_type { conv_decimal, conv_slash }; 208 enum conv_type { 209 conv_decimal = 0, 210 conv_slash = 1 211 }; 212 212 213 213 // Reads decimal values from line. Values start after key, for example: 214 214 // "cpu 649369 0 341297 4336769..." - key is "cpu" here. 215 // Values are stored in vec[]. arg_ptr has list of positions216 // we are interested in: for example: 1,2,5 - we want 1st, 2nd and 5th value.217 static int vrdval(const char* p, const char* key, 218 enum conv_type conv, ullong *vec, va_list arg_ptr) 219 { 220 int indexline; 221 int indexnext;215 // Values are stored in vec[]. 216 // posbits is a bit lit of positions we are interested in. 217 // for example: 00100110 - we want 1st, 2nd and 5th value. 218 // posbits.bit0 encodes conversion type. 219 static int rdval(const char* p, const char* key, ullong *vec, long posbits) 220 { 221 unsigned curpos; 222 222 223 223 p = strstr(p, key); … … 225 225 226 226 p += strlen(key); 227 indexline = 1; 228 indexnext = va_arg(arg_ptr, int); 227 curpos = 1 << 1; 229 228 while (1) { 230 229 while (*p == ' ' || *p == '\t') p++; 231 230 if (*p == '\n' || *p == '\0') break; 232 231 233 if ( indexline == indexnext) { // read this value234 *vec++ = conv==conv_decimal ?232 if (curpos & posbits) { // read this value 233 *vec++ = (posbits & 1) == conv_decimal ? 235 234 strtoull(p, NULL, 10) : 236 235 read_after_slash(p); 237 indexnext = va_arg(arg_ptr, int); 236 posbits -= curpos; 237 if (posbits <= 1) 238 return 0; 238 239 } 239 while (*p > ' ') p++; // skip over value 240 indexline++; 240 while (*p > ' ') // skip over the value 241 p++; 242 curpos <<= 1; 241 243 } 242 244 return 0; 243 245 } 244 246 245 // Parses files with lines like "cpu0 21727 0 15718 1813856 9461 10485 0 0": 246 // rdval(file_contents, "string_to_find", result_vector, value#, value#...) 247 // value# start with 1 248 static int rdval(const char* p, const char* key, ullong *vec, ...) 249 { 250 va_list arg_ptr; 247 // Parses files with lines like "... ... ... 3/148 ...." 248 static int rdval_loadavg(const char* p, ullong *vec, long posbits) 249 { 251 250 int result; 252 253 va_start(arg_ptr, vec); 254 result = vrdval(p, key, conv_decimal, vec, arg_ptr); 255 va_end(arg_ptr); 256 257 return result; 258 } 259 260 // Parses files with lines like "... ... ... 3/148 ...." 261 static int rdval_loadavg(const char* p, ullong *vec, ...) 262 { 263 va_list arg_ptr; 264 int result; 265 266 va_start(arg_ptr, vec); 267 result = vrdval(p, "", conv_slash, vec, arg_ptr); 268 va_end(arg_ptr); 269 251 result = rdval(p, "", vec, posbits | conv_slash); 270 252 return result; 271 253 } … … 334 316 335 317 /* see http://en.wikipedia.org/wiki/Tera */ 336 smart_ulltoa4(ul, buf, " kmgtpezy"); 337 buf[4] = '\0'; 318 smart_ulltoa4(ul, buf, " kmgtpezy")[0] = '\0'; 338 319 put(buf); 339 320 } 340 341 321 342 322 #define S_STAT(a) \ … … 361 341 } 362 342 363 static s_stat* init_delay(const char *param) 364 { 365 delta = strtoul(param, NULL, 0) * 1000; /* param can be "" */ 366 deltanz = delta > 0 ? delta : 1; 367 need_seconds = (1000000%deltanz) != 0; 343 static s_stat* init_cr(const char *param UNUSED_PARAM) 344 { 345 G.final_char = '\r'; 368 346 return NULL; 369 347 } 370 371 static s_stat* init_cr(const char *param UNUSED_PARAM)372 {373 final_str = "\r";374 return (s_stat*)0;375 }376 377 348 378 349 // user nice system idle iowait irq softirq (last 3 only in 2.6) … … 383 354 ullong old[CPU_FIELDCNT]; 384 355 int bar_sz; 385 char *bar;356 char bar[1]; 386 357 S_STAT_END(cpu_stat) 387 388 358 389 359 static void FAST_FUNC collect_cpu(cpu_stat *s) … … 397 367 int i; 398 368 399 if (rdval(get_file(&proc_stat), "cpu ", data, 1, 2, 3, 4, 5, 6, 7)) { 369 if (rdval(get_file(&proc_stat), "cpu ", data, 0 370 | (1 << 1) 371 | (1 << 2) 372 | (1 << 3) 373 | (1 << 4) 374 | (1 << 5) 375 | (1 << 6) 376 | (1 << 7)) 377 ) { 400 378 put_question_marks(bar_sz); 401 379 return; … … 440 418 } 441 419 442 443 420 static s_stat* init_cpu(const char *param) 444 421 { 445 422 int sz; 446 cpu_stat *s = xzalloc(sizeof(*s)); 447 s->collect = collect_cpu; 423 cpu_stat *s; 448 424 sz = strtoul(param, NULL, 0); /* param can be "" */ 449 425 if (sz < 10) sz = 10; 450 426 if (sz > 1000) sz = 1000; 451 s ->bar = xzalloc(sz+1);427 s = xzalloc(sizeof(*s) + sz); 452 428 /*s->bar[sz] = '\0'; - xzalloc did it */ 453 429 s->bar_sz = sz; 454 return (s_stat*)s;455 } 456 430 s->collect = collect_cpu; 431 return (s_stat*)s; 432 } 457 433 458 434 S_STAT(int_stat) … … 466 442 ullong old; 467 443 468 if (rdval(get_file(&proc_stat), "intr", data, s->no)) {444 if (rdval(get_file(&proc_stat), "intr", data, 1 << s->no)) { 469 445 put_question_marks(4); 470 446 return; … … 490 466 } 491 467 492 493 468 S_STAT(ctx_stat) 494 469 ullong old; … … 500 475 ullong old; 501 476 502 if (rdval(get_file(&proc_stat), "ctxt", data, 1 )) {477 if (rdval(get_file(&proc_stat), "ctxt", data, 1 << 1)) { 503 478 put_question_marks(4); 504 479 return; … … 518 493 } 519 494 520 521 495 S_STAT(blk_stat) 522 496 const char* lookfor; … … 532 506 i = rdval_diskstats(get_file(&proc_diskstats), data); 533 507 } else { 534 i = rdval(get_file(&proc_stat), s->lookfor, data, 1, 2); 508 i = rdval(get_file(&proc_stat), s->lookfor, data, 0 509 | (1 << 1) 510 | (1 << 2) 511 ); 535 512 // Linux 2.4 reports bio in Kbytes, convert to sectors: 536 513 data[0] *= 2; … … 561 538 } 562 539 563 564 540 S_STAT(fork_stat) 565 541 ullong old; … … 570 546 ullong data[1]; 571 547 572 if (rdval_loadavg(get_file(&proc_loadavg), data, 4)) {548 if (rdval_loadavg(get_file(&proc_loadavg), data, 1 << 4)) { 573 549 put_question_marks(4); 574 550 return; … … 582 558 ullong old; 583 559 584 if (rdval(get_file(&proc_stat), "processes", data, 1 )) {560 if (rdval(get_file(&proc_stat), "processes", data, 1 << 1)) { 585 561 put_question_marks(4); 586 562 return; … … 604 580 } 605 581 606 607 582 S_STAT(if_stat) 608 583 ullong old[4]; … … 616 591 int i; 617 592 618 if (rdval(get_file(&proc_net_dev), s->device_colon, data, 1, 3, 9, 11)) { 593 if (rdval(get_file(&proc_net_dev), s->device_colon, data, 0 594 | (1 << 1) 595 | (1 << 3) 596 | (1 << 9) 597 | (1 << 11)) 598 ) { 619 599 put_question_marks(10); 620 600 return; … … 645 625 return (s_stat*)s; 646 626 } 647 648 627 649 628 S_STAT(mem_stat) … … 694 673 ullong m_slab = 0; 695 674 696 if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1 )) {675 if (rdval(get_file(&proc_meminfo), "MemTotal:", &m_total, 1 << 1)) { 697 676 put_question_marks(4); 698 677 return; … … 703 682 } 704 683 705 if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1 )706 || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1 )707 || rdval(proc_meminfo.file, "Cached:", &m_cached, 1 )708 || rdval(proc_meminfo.file, "Slab:", &m_slab , 1 )684 if (rdval(proc_meminfo.file, "MemFree:", &m_free , 1 << 1) 685 || rdval(proc_meminfo.file, "Buffers:", &m_bufs , 1 << 1) 686 || rdval(proc_meminfo.file, "Cached:", &m_cached, 1 << 1) 687 || rdval(proc_meminfo.file, "Slab:", &m_slab , 1 << 1) 709 688 ) { 710 689 put_question_marks(4); … … 729 708 } 730 709 731 732 710 S_STAT(swp_stat) 733 711 S_STAT_END(swp_stat) … … 737 715 ullong s_total[1]; 738 716 ullong s_free[1]; 739 if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1 )740 || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1 )717 if (rdval(get_file(&proc_meminfo), "SwapTotal:", s_total, 1 << 1) 718 || rdval(proc_meminfo.file, "SwapFree:" , s_free, 1 << 1) 741 719 ) { 742 720 put_question_marks(4); … … 753 731 } 754 732 755 756 733 S_STAT(fd_stat) 757 734 S_STAT_END(fd_stat) … … 761 738 ullong data[2]; 762 739 763 if (rdval(get_file(&proc_sys_fs_filenr), "", data, 1, 2)) { 740 if (rdval(get_file(&proc_sys_fs_filenr), "", data, 0 741 | (1 << 1) 742 | (1 << 2)) 743 ) { 764 744 put_question_marks(4); 765 745 return; … … 776 756 } 777 757 778 779 758 S_STAT(time_stat) 780 intprec;781 intscale;759 unsigned prec; 760 unsigned scale; 782 761 S_STAT_END(time_stat) 783 762 … … 786 765 char buf[sizeof("12:34:56.123456")]; 787 766 struct tm* tm; 788 intus = tv.tv_usec + s->scale/2;767 unsigned us = tv.tv_usec + s->scale/2; 789 768 time_t t = tv.tv_sec; 790 769 … … 827 806 } 828 807 829 830 808 typedef s_stat* init_func(const char *param); 831 809 832 // Deprecated %NNNd is to be removed, -d MSEC supersedes it 833 static const char options[] ALIGN1 = "ncmsfixptbdr"; 810 static const char options[] ALIGN1 = "ncmsfixptbr"; 834 811 static init_func *const init_functions[] = { 835 812 init_if, … … 843 820 init_time, 844 821 init_blk, 845 init_delay,846 822 init_cr 847 823 }; … … 866 842 } 867 843 868 if (getopt32(argv, "d:", &opt_d)) 869 init_delay(opt_d); 844 if (getopt32(argv, "d:", &opt_d)) { 845 G.delta = xatoi(opt_d) * 1000; 846 G.deltanz = G.delta > 0 ? G.delta : 1; 847 need_seconds = (1000000 % G.deltanz) != 0; 848 } 870 849 argv += optind; 871 850 … … 922 901 last = s; 923 902 } else { 924 // % NNNNd or %r option. remove it from string925 strcpy(prev + strlen(prev), cur);903 // %r option. remove it from string 904 overlapping_strcpy(prev + strlen(prev), cur); 926 905 cur = prev; 927 906 } … … 941 920 collect_info(first); 942 921 reset_outbuf(); 943 if ( delta >= 0) {922 if (G.delta >= 0) { 944 923 gettimeofday(&tv, NULL); 945 usleep( delta > 1000000 ? 1000000 : delta - tv.tv_usec%deltanz);924 usleep(G.delta > 1000000 ? 1000000 : G.delta - tv.tv_usec % G.deltanz); 946 925 } 947 926 … … 949 928 gettimeofday(&tv, NULL); 950 929 collect_info(first); 951 put (final_str);930 put_c(G.final_char); 952 931 print_outbuf(); 953 932 … … 957 936 // TODO: detect and avoid useless updates 958 937 // (like: nothing happens except time) 959 if ( delta >= 0) {938 if (G.delta >= 0) { 960 939 int rem; 961 940 // can be commented out, will sacrifice sleep time precision a bit 962 941 gettimeofday(&tv, NULL); 963 942 if (need_seconds) 964 rem = delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) %deltanz;943 rem = G.delta - ((ullong)tv.tv_sec*1000000 + tv.tv_usec) % G.deltanz; 965 944 else 966 rem = delta - tv.tv_usec%deltanz;945 rem = G.delta - (unsigned)tv.tv_usec % G.deltanz; 967 946 // Sometimes kernel wakes us up just a tiny bit earlier than asked 968 947 // Do not go to very short sleep in this case 969 if (rem < delta/128) {970 rem += delta;948 if (rem < (unsigned)G.delta / 128) { 949 rem += G.delta; 971 950 } 972 951 usleep(rem);
Note:
See TracChangeset
for help on using the changeset viewer.