📄 top.c
字号:
fputc('\n', stderr); } /* setup the jump buffer for stops */ if (setjmp(jmp_int) != 0) { /* control ends up here after an interrupt */ reset_display(); } /* * main loop -- repeat while display count is positive or while it * indicates infinity (by being -1) */ while ((displays == -1) || (displays-- > 0)) { /* get the current stats */ get_system_info(&system_info); /* get the current set of processes */ processes = get_process_info(&system_info, &ps,#ifdef ORDER proc_compares[order_index]);#else proc_compare);#endif /* display the load averages */ (*d_loadave)(system_info.last_pid, system_info.load_avg); /* display the current time */ /* this method of getting the time SHOULD be fairly portable */ time(&curr_time); i_timeofday(&curr_time); /* display process state breakdown */ (*d_procstates)(system_info.p_total, system_info.procstates); /* display the cpu state percentage breakdown */ if (dostates) /* but not the first time */ { (*d_cpustates)(system_info.cpustates); } else { /* we'll do it next time */ if (smart_terminal) { z_cpustates(); } else { putchar('\n'); } dostates = Yes; } /* display memory stats */ (*d_memory)(system_info.memory); /* handle message area */ (*d_message)(); /* update the header area */ (*d_header)(header_text); if (topn > 0) { /* determine number of processes to actually display */ /* this number will be the smallest of: active processes, number user requested, number current screen accomodates */ active_procs = system_info.P_ACTIVE; if (active_procs > topn) { active_procs = topn; } if (active_procs > max_topn) { active_procs = max_topn; } /* now show the top "n" processes. */ for (i = 0; i < active_procs; i++) { (*d_process)(i, format_next_process(processes, get_userid)); } } else { i = 0; } /* do end-screen processing */ u_endscreen(i); /* now, flush the output buffer */ if (fflush(stdout) != 0) { new_message(MT_standout, " Write error on stdout"); putchar('\r'); quit(1); /*NOTREACHED*/ } /* only do the rest if we have more displays to show */ if (displays) { /* switch out for new display on smart terminals */ if (smart_terminal) { if (overstrike) { reset_display(); } else { d_loadave = u_loadave; d_procstates = u_procstates; d_cpustates = u_cpustates; d_memory = u_memory; d_message = u_message; d_header = u_header; d_process = u_process; } } no_command = Yes; if (!interactive) { /* set up alarm */ (void) signal(SIGALRM, onalrm); (void) alarm((unsigned)delay); /* wait for the rest of it .... */ pause(); } else while (no_command) { /* assume valid command unless told otherwise */ no_command = No; /* set up arguments for select with timeout */ FD_ZERO(&readfds); FD_SET(0, &readfds); /* for standard input */ timeout.tv_sec = delay; timeout.tv_usec = 0; /* wait for either input or the end of the delay period */ if (select(32, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timeout) > 0) { int newval; char *errmsg; /* something to read -- clear the message area first */ clear_message(); /* now read it and convert to command strchr */ /* (use "change" as a temporary to hold strchr) */ if (read(0, &ch, 1) != 1) { /* read error: either 0 or -1 */ new_message(MT_standout, " Read error on stdin"); putchar('\r'); quit(1); /*NOTREACHED*/ } if ((iptr = strchr(command_chars, ch)) == NULL) { /* illegal command */ new_message(MT_standout, " Command not understood"); putchar('\r'); no_command = Yes; } else { change = iptr - command_chars; if (overstrike && change > CMD_OSLIMIT) { /* error */ new_message(MT_standout, " Command cannot be handled by this terminal"); putchar('\r'); no_command = Yes; } else switch(change) { case CMD_redraw: /* redraw screen */ reset_display(); break; case CMD_update: /* merely update display */ /* is the load average high? */ if (system_info.load_avg[0] > LoadMax) { /* yes, go home for visual feedback */ go_home(); fflush(stdout); } break; case CMD_quit: /* quit */ quit(0); /*NOTREACHED*/ break; case CMD_help1: /* help */ case CMD_help2: reset_display(); clear(); show_help(); standout("Hit any key to continue: "); fflush(stdout); (void) read(0, &ch, 1); break; case CMD_errors: /* show errors */ if (error_count() == 0) { new_message(MT_standout, " Currently no errors to report."); putchar('\r'); no_command = Yes; } else { reset_display(); clear(); show_errors(); standout("Hit any key to continue: "); fflush(stdout); (void) read(0, &ch, 1); } break; case CMD_number1: /* new number */ case CMD_number2: new_message(MT_standout, "Number of processes to show: "); newval = readline(tempbuf1, 8, Yes); if (newval > -1) { if (newval > max_topn) { new_message(MT_standout | MT_delayed, " This terminal can only display %d processes.", max_topn); putchar('\r'); } if (newval == 0) { /* inhibit the header */ display_header(No); } else if (newval > topn && topn == 0) { /* redraw the header */ display_header(Yes); d_header = i_header; } topn = newval; } break; case CMD_delay: /* new seconds delay */ new_message(MT_standout, "Seconds to delay: "); if ((i = readline(tempbuf1, 8, Yes)) > -1) { if ((delay = i) == 0 && getuid() != 0) { delay = 1; } } clear_message(); break; case CMD_displays: /* change display count */ new_message(MT_standout, "Displays to show (currently %s): ", displays == -1 ? "infinite" : itoa(displays)); if ((i = readline(tempbuf1, 10, Yes)) > 0) { displays = i; } else if (i == 0) { quit(0); } clear_message(); break; case CMD_kill: /* kill program */ new_message(0, "kill "); if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) { if ((errmsg = kill_procs(tempbuf2)) != NULL) { new_message(MT_standout, errmsg); putchar('\r'); no_command = Yes; } } else { clear_message(); } break; case CMD_renice: /* renice program */ new_message(0, "renice "); if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) { if ((errmsg = renice_procs(tempbuf2)) != NULL) { new_message(MT_standout, errmsg); putchar('\r'); no_command = Yes; } } else { clear_message(); } break; case CMD_idletog: case CMD_idletog2: ps.idle = !ps.idle; new_message(MT_standout | MT_delayed, " %sisplaying idle processes.", ps.idle ? "D" : "Not d"); putchar('\r'); break; case CMD_user: new_message(MT_standout, "Username to show: "); if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) { if (tempbuf2[0] == '+' && tempbuf2[1] == '\0') { ps.uid = -1; } else if ((i = userid(tempbuf2)) == -1) { new_message(MT_standout, " %s: unknown user", tempbuf2); no_command = Yes; } else { ps.uid = i; } putchar('\r'); } else { clear_message(); } break; #ifdef ORDER case CMD_order: new_message(MT_standout, "Order to sort: "); if (readline(tempbuf2, sizeof(tempbuf2), No) > 0) { if ((i = string_index(tempbuf2, statics.order_names)) == -1) { new_message(MT_standout, " %s: unrecognized sorting order", tempbuf2); no_command = Yes; } else { order_index = i; } putchar('\r'); } else { clear_message(); } break;#endif default: new_message(MT_standout, " BAD CASE IN SWITCH!"); putchar('\r'); } } /* flush out stuff that may have been written */ fflush(stdout); } } } }#ifdef DEBUG fclose(debug);#endif quit(0); /*NOTREACHED*/}/* * reset_display() - reset all the display routine pointers so that entire * screen will get redrawn. */reset_display(){ d_loadave = i_loadave; d_procstates = i_procstates; d_cpustates = i_cpustates; d_memory = i_memory; d_message = i_message; d_header = i_header; d_process = i_process;}/* * signal handlers */sigret_t leave() /* exit under normal conditions -- INT handler */{ end_screen(); exit(0);}sigret_t tstop(i) /* SIGTSTP handler */int i;{ /* move to the lower left */ end_screen(); fflush(stdout); /* default the signal handler action */ (void) signal(SIGTSTP, SIG_DFL); /* unblock the signal and send ourselves one */#ifdef SIGRELSE sigrelse(SIGTSTP);#else (void) sigsetmask(sigblock(0) & ~(1 << (SIGTSTP - 1)));#endif (void) kill(0, SIGTSTP); /* reset the signal handler */ (void) signal(SIGTSTP, tstop); /* reinit screen */ reinit_screen(); /* jump to appropriate place */ longjmp(jmp_int, 1); /*NOTREACHED*/}#ifdef SIGWINCHsigret_t winch(i) /* SIGWINCH handler */int i;{ /* reascertain the screen dimensions */ get_screensize(); /* tell display to resize */ max_topn = display_resize(); /* reset the signal handler */ (void) signal(SIGWINCH, winch); /* jump to appropriate place */ longjmp(jmp_int, 1);}#endifvoid quit(status) /* exit under duress */int status;{ end_screen(); exit(status); /*NOTREACHED*/}sigret_t onalrm() /* SIGALRM handler */{ /* this is only used in batch mode to break out of the pause() */ /* return; */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -