*: s/BB_SIGS_FATAL/BB_FATAL_SIGS/ (latter proved easier to remember)
authorDenis Vlasenko <vda.linux@googlemail.com>
Wed, 19 Mar 2008 19:38:46 +0000 (19:38 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Wed, 19 Mar 2008 19:38:46 +0000 (19:38 -0000)
top: fix "top </dev/null" case (by Cristian Ionescu-Idbohrn)

include/libbb.h
miscutils/less.c
miscutils/watchdog.c
networking/tcpudp.c
procps/top.c

index 654643743100990289762337f504527db98ea082..d059ac9de92ea7ec058a66c5327a29c50443804f 100644 (file)
@@ -278,7 +278,7 @@ char *xmalloc_follow_symlinks(const char *path);
 
 
 enum {
-       /* bb_signals(BB_SIGS_FATAL, handler) catches all signals which
+       /* bb_signals(BB_FATAL_SIGS, handler) catches all signals which
         * otherwise would kill us, except for those resulting from bugs:
         * SIGSEGV, SIGILL, SIGFPE.
         * Other fatal signals not included (TODO?):
@@ -288,7 +288,7 @@ enum {
         * SIGSYS   Bad argument to routine
         * SIGTRAP  Trace/breakpoint trap
         */
-       BB_SIGS_FATAL = 0
+       BB_FATAL_SIGS = 0
                + (1 << SIGHUP)
                + (1 << SIGINT)
                + (1 << SIGTERM)
index 3a9dea0394ca4b27365ebcf49a553b2a018c4ccb..1a67ca7ce31017c7154750eab21932a73e5a68ee 100644 (file)
@@ -1400,7 +1400,7 @@ int less_main(int argc, char **argv)
        term_less.c_cc[VTIME] = 0;
 
        /* We want to restore term_orig on exit */
-       bb_signals(BB_SIGS_FATAL, sig_catcher);
+       bb_signals(BB_FATAL_SIGS, sig_catcher);
 
        reinitialize();
        while (1) {
index 7fb16b86181eb73326e625149fa6c07d1811ab2b..a5061f5d7d60ce5865e65b342c62fc4d4612ed7a 100644 (file)
@@ -46,7 +46,7 @@ int watchdog_main(int argc, char **argv)
                bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
        }
 
-       bb_signals(BB_SIGS_FATAL, watchdog_shutdown);
+       bb_signals(BB_FATAL_SIGS, watchdog_shutdown);
 
        /* Use known fd # - avoid needing global 'int fd' */
        xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3);
index f9778749756c2269da4394b1c5b78147a5fbc0a5..5da4de50591499c54577cfcdada83261fc7bef56 100644 (file)
@@ -264,7 +264,7 @@ int tcpudpsvd_main(int argc ATTRIBUTE_UNUSED, char **argv)
 
        sig_block(SIGCHLD);
        signal(SIGCHLD, sig_child_handler);
-       bb_signals(BB_SIGS_FATAL, sig_term_handler);
+       bb_signals(BB_FATAL_SIGS, sig_term_handler);
        signal(SIGPIPE, SIG_IGN);
 
        if (max_per_host)
index fdd7584c8a2c5fbad22672f803983af08de5a252..85ceaccf71093a3f5f44702b7a3d372a49c170cb 100644 (file)
@@ -108,8 +108,13 @@ enum { LINE_BUF_SIZE = COMMON_BUFSIZE - offsetof(struct globals, line_buf) };
 #define total_pcpu       (G.total_pcpu        )
 #define line_buf         (G.line_buf          )
 
-
-#define OPT_BATCH_MODE (option_mask32 & 0x4)
+enum {
+       OPT_d = (1 << 0),
+       OPT_n = (1 << 1),
+       OPT_b = (1 << 2),
+       OPT_EOF = (1 << 3), /* pseudo: "we saw EOF in stdin" */
+};
+#define OPT_BATCH_MODE (option_mask32 & OPT_b)
 
 
 #if ENABLE_FEATURE_USE_TERMIOS
@@ -165,7 +170,7 @@ static void get_jiffy_counts(void)
        if (fscanf(fp, "cpu  %lld %lld %lld %lld %lld %lld %lld %lld",
                        &jif.usr,&jif.nic,&jif.sys,&jif.idle,
                        &jif.iowait,&jif.irq,&jif.softirq,&jif.steal) < 4) {
-               bb_error_msg_and_die("failed to read /proc/stat");
+               bb_error_msg_and_die("can't read /proc/stat");
        }
        fclose(fp);
        jif.total = jif.usr + jif.nic + jif.sys + jif.idle
@@ -506,7 +511,7 @@ static void clearmems(void)
 
 static void reset_term(void)
 {
-       tcsetattr(0, TCSANOW, (void *) &initial_settings);
+       tcsetattr(0, TCSANOW, &initial_settings);
        if (ENABLE_FEATURE_CLEAN_UP) {
                clearmems();
 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
@@ -753,13 +758,13 @@ int top_main(int argc ATTRIBUTE_UNUSED, char **argv)
 
        INIT_G();
 
-       interval = 5; /* default update rate is 5 seconds */
+       interval = 5; /* default update interval is 5 seconds */
        iterations = 0; /* infinite */
 
-       /* do normal option parsing */
+       /* all args are options; -n NUM */
        opt_complementary = "-:n+";
        getopt32(argv, "d:n:b", &sinterval, &iterations);
-       if (option_mask32 & 0x1) {
+       if (option_mask32 & OPT_d) {
                /* Need to limit it to not overflow poll timeout */
                interval = xatou16(sinterval); // -d
        }
@@ -772,12 +777,8 @@ int top_main(int argc ATTRIBUTE_UNUSED, char **argv)
        /* unbuffered input, turn off echo */
        new_settings.c_lflag &= ~(ISIG | ICANON | ECHO | ECHONL);
 
-       bb_signals(0
-               + (1 << SIGTERM)
-               + (1 << SIGINT)
-               , sig_catcher);
+       bb_signals(BB_FATAL_SIGS, sig_catcher);
        tcsetattr(0, TCSANOW, (void *) &new_settings);
-       atexit(reset_term);
 #endif /* FEATURE_USE_TERMIOS */
 
 #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
@@ -794,7 +795,8 @@ int top_main(int argc ATTRIBUTE_UNUSED, char **argv)
                lines = 24; /* default */
                col = 79;
 #if ENABLE_FEATURE_USE_TERMIOS
-               get_terminal_width_height(0, &col, &lines);
+               /* We output to stdout, we need size of stdout (not stdin)! */
+               get_terminal_width_height(STDOUT_FILENO, &col, &lines);
                if (lines < 5 || col < 10) {
                        sleep(interval);
                        continue;
@@ -839,9 +841,10 @@ int top_main(int argc ATTRIBUTE_UNUSED, char **argv)
                                topmem[n].stack    = p->stack;
 #endif
                        }
-               }
+               } /* end of "while we read /proc" */
                if (ntop == 0) {
-                       bb_error_msg_and_die("no process info in /proc");
+                       bb_error_msg("no process info in /proc");
+                       break;
                }
 
                if (scan_mask == TOP_MASK) {
@@ -875,9 +878,14 @@ int top_main(int argc ATTRIBUTE_UNUSED, char **argv)
 #if !ENABLE_FEATURE_USE_TERMIOS
                sleep(interval);
 #else
-               if (safe_poll(pfd, 1, interval * 1000) > 0) {
-                       if (read(0, &c, 1) != 1)    /* signal */
-                               break;
+               if (option_mask32 & (OPT_b|OPT_EOF))
+                        /* batch mode, or EOF on stdin ("top </dev/null") */
+                       sleep(interval);
+               else if (safe_poll(pfd, 1, interval * 1000) > 0) {
+                       if (safe_read(0, &c, 1) != 1) { /* error/EOF? */
+                               option_mask32 |= OPT_EOF;
+                               continue;
+                       }
                        if (c == initial_settings.c_cc[VINTR])
                                break;
                        c |= 0x20; /* lowercase */
@@ -922,7 +930,9 @@ int top_main(int argc ATTRIBUTE_UNUSED, char **argv)
 #endif
                }
 #endif /* FEATURE_USE_TERMIOS */
-       }
+       } /* end of "while (1)" */
+
        bb_putchar('\n');
+       reset_term();
        return EXIT_SUCCESS;
 }