⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 top.c

📁 Linux下进程监控相关源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
 	        exit(1);	    }	    cp++;	}    breakargv:    }        if (nr_cpu > 1 && CPU_states)      header_lines++;    setup_terminal();    window_size(0);    /*     * Set up signal handlers.     */    sact.sa_handler = end;    sact.sa_flags = 0;    sigemptyset(&sact.sa_mask);    sigaction(SIGHUP, &sact, NULL);    sigaction(SIGINT, &sact, NULL);    sigaction(SIGQUIT, &sact, NULL);    sact.sa_handler = stop;    sact.sa_flags = SA_RESTART;    sigaction(SIGTSTP, &sact, NULL);    sact.sa_handler = window_size;    sigaction(SIGWINCH, &sact, NULL);    sigaction(SIGCONT, &sact, NULL);    /* loop, collecting process info and sleeping */    while (1) {	if (Loops > 0)		Loops--;	/* display the tasks */	show_procs();	/* sleep & wait for keyboard input */	if (Loops == 0)	    end(0);        if (!Batch)        {		tv.tv_sec = Sleeptime;		tv.tv_usec = (Sleeptime - (int) Sleeptime) * 1000000;		FD_ZERO(&in);		FD_SET(0, &in);		if (select(1, &in, 0, 0, &tv) > 0 && read(0, &c, 1) == 1)	    		do_key(c);        } else {	   sleep(Sleeptime);	}    }}/*####################################################################### *#### Signal handled routines: error_end, end, stop, window_size     ### *#### Small utilities: make_header, getstr, getint, getfloat, getsig ### *####################################################################### */	/*	 *  end when exiting with an error.	 */void error_end(int rno){    if (psdbsucc)        close_psdb();    if (!Batch)	tcsetattr(0, TCSAFLUSH, &Savetty);    PUTP(tgoto(cm, 0, Lines - 1));    fputs("\r\n", stdout);    exit(rno);}/*	 * Normal end of execution.	 */void end(int signo){    if (psdbsucc)	close_psdb();    if (!Batch)	tcsetattr(0, TCSAFLUSH, &Savetty);    PUTP(tgoto(cm, 0, Lines - 1));    fputs("\r\n", stdout);    exit(0);}/*	 * SIGTSTP catcher.	 */void stop(int signo){    /* Reset terminal. */    if (!Batch)	tcsetattr(0, TCSAFLUSH, &Savetty);    PUTP(tgoto(cm, 0, Lines - 3));    fflush(stdout);    raise(SIGSTOP);    /* Later... */    if (!Batch)	tcsetattr (0, TCSAFLUSH, &Rawtty);}/*       * Reads the window size and clear the window.  This is called on setup,       * and also catches SIGWINCHs, and adjusts Maxlines.  Basically, this is       * the central place for window size stuff.       */void window_size(int signo){    struct winsize ws;    if((ioctl(1, TIOCGWINSZ, &ws) != -1) && (ws.ws_col>73) && (ws.ws_row>7)){	Cols = ws.ws_col;	Lines = ws.ws_row;    }else{	Cols = tgetnum("co");	Lines = tgetnum("li");    }    if (!Batch)        clear_screen();    /*     * calculate header size, length of cmdline field ...     */     Numfields = make_header();}/*	* this prints a possible message from open_psdb_message	*/static void top_message(const char *format, ...) {    va_list arg;    int n;    char buffer[512];    va_start (arg, format);    n = vsnprintf (buffer, 512, format, arg);    va_end (arg);    if (n > -1 && n < 512)	SHOWMESSAGE(("%s", buffer));}/*       * this adjusts the lines needed for the header to the current value       */int make_header(void){    int i, j;    j = 0;    for (i = 0; i < strlen(Fields); i++) {	if (Fields[i] < 'a') {	    pflags[j++] = Fields[i] - 'A';	    if (Fields[i] == 'U' && CL_wchan_nout == -1) {		CL_wchan_nout = 0;		/* for correct handling of WCHAN fields, we have to do distinguish 		 * between kernel versions */		/* get kernel symbol table, if needed */		if (open_psdb_message(NULL, top_message)) {		    CL_wchan_nout = 1;		} else {		    psdbsucc = 1;		}	    }	}    }    strcpy(Header, "");    for (i = 0; i < j; i++)	strcat(Header, headers[pflags[i]]);    /* readjust window size ... */    Maxcmd = Cols - strlen(Header) + 7;    Maxlines = Display_procs ? Display_procs : Lines - header_lines;    if (Maxlines > Lines - header_lines)	Maxlines = Lines - header_lines;    return (j);}/* * Get a string from the user; the base of getint(), et al.  This really * ought to handle long input lines and errors better.  NB: The pointer * returned is a statically allocated buffer, so don't expect it to * persist between calls. */char *getstr(void){    static char line[BUFSIZ];	/* BUFSIZ from <stdio.h>; arbitrary */    int i = 0;    /* Must make sure that buffered IO doesn't kill us. */    fflush(stdout);    fflush(stdin);		/* Not POSIX but ok */    do {	read(STDIN_FILENO, &line[i], 1);    } while (line[i++] != '\n' && i < sizeof(line));    line[--i] = 0;    return (line);}/* * Get an integer from the user.  Display an error message and return BAD_INPUT * if it's invalid; else return the number. */int getint(void){    char *line;    int i;    int r;    line = getstr();    for (i = 0; line[i]; i++) {	if (!isdigit(line[i]) && line[i] != '-') {	    SHOWMESSAGE(("That's not a number!"));	    return (BAD_INPUT);	}    }    /* An empty line is a legal error (hah!). */    if (!line[0])	return (BAD_INPUT);    sscanf(line, "%d", &r);    return (r);}/*	 * Get a float from the user.  Just like getint().	 */float getfloat(void){    char *line;    int i;    float r;    line = getstr();    for (i = 0; line[i]; i++) {	if (!isdigit(line[i]) && line[i] != '.' && line[i] != '-') {	    SHOWMESSAGE(("That's not a float!"));	    return (BAD_INPUT);	}    }    /* An empty line is a legal error (hah!). */    if (!line[0])	return (BAD_INPUT);    sscanf(line, "%f", &r);    return (r);}/*	 * Get a signal number or name from the user.  Return the number, or -1	 * on error.	 */int getsig(void){    char *line;    /* This is easy. */    line = getstr();    return (get_signal2(line));}/*####################################################################### *####  Routine for sorting on used time, resident memory and %CPU  ##### *####  It would be easy to include full sorting capability as in   ##### *####  ps, but I think there is no real use for something that     ##### *####  complicated. Using register_sort_function or parse_sort_opt ##### *####  you just have to do the natural thing and it will work.     ##### *####################################################################### */int time_sort (proc_t **P, proc_t **Q){    if (Cumulative) {	if( ((*P)->cutime + (*P)->cstime + (*P)->utime + (*P)->stime) < 	    ((*Q)->cutime + (*Q)->cstime + (*Q)->utime + (*Q)->stime) )	    return -1;	if( ((*P)->cutime + (*P)->cstime + (*P)->utime + (*P)->stime) >	    ((*Q)->cutime + (*Q)->cstime + (*Q)->utime + (*Q)->stime) )	    return 1;    } else {	if( ((*P)->utime + (*P)->stime) < ((*Q)->utime + (*Q)->stime))	    return -1;	if( ((*P)->utime + (*P)->stime) > ((*Q)->utime + (*Q)->stime))	    return 1;    }    return 0;}int pcpu_sort (proc_t **P, proc_t **Q){    if( (*P)->pcpu < (*Q)->pcpu )      return -1;    if( (*P)->pcpu > (*Q)->pcpu )      return 1;    return 0;}int mem_sort (proc_t **P, proc_t **Q){    if( (*P)->resident < (*Q)->resident )      return -1;    if( (*P)->resident > (*Q)->resident )      return 1;      return 0;}int age_sort (proc_t **P, proc_t **Q){    if( (*P)->start_time < (*Q)->start_time )      return -1;    if( (*P)->start_time > (*Q)->start_time )      return 1;    return 0;}/*####################################################################### *####  Routines handling the field selection/ordering screens:  ######## *####    show_fields, change_order, change_fields               ######## *####################################################################### */        /*	 * Display the specification line of all fields. Upper case indicates	 * a displayed field, display order is according to the order of the 	 * letters. A short description of each field is shown as well.	 * The description of a displayed field is marked by a leading 	 * asterisk (*).	 */void show_fields(void){    int i, row, col;    char *p;    clear_screen();    PUTP(tgoto(cm, 3, 0));    printf("Current Field Order: %s\n", Fields);    for (i = 0; i < sizeof headers / sizeof headers[0]; ++i) {	row = i % (Lines - 3) + 3;	col = i / (Lines - 3) * 40;	PUTP(tgoto(cm, col, row));	for (p = headers[i]; *p == ' '; ++p);	printf("%c %c: %-10s = %s", (strchr(Fields, i + 'A') != NULL) ? '*' : ' ', i + 'A',	       p, headers2[i]);    }}/*	 * change order of displayed fields	 */void change_order(void){    char c, ch, *p;    int i;    show_fields();    for (;;) {	PUTP(tgoto(cm, 0, 0));	PUTP(top_clrtoeol);	PUTP(tgoto(cm, 3, 0));	PUTP(mr);	printf("Current Field Order: %s", Fields);	PUTP(me);	putchar('\n');	PUTP(tgoto(cm, 0, 1));	printf("Upper case characters move a field to the left, lower case to the right");	fflush(stdout);	if (!Batch) { /* should always be true, but... */	    tcsetattr(0, TCSAFLUSH, &Rawtty);	    read(0, &c, 1);	    tcsetattr(0, TCSAFLUSH, &Savetty);	}	i = toupper(c) - 'A';	if ((p = strchr(Fields, i + 'A')) != NULL) {	    if (isupper(c))		p--;	    if ((p[1] != '\0') && (p >= Fields)) {		ch = p[0];		p[0] = p[1];		p[1] = ch;	    }	} else if ((p = strchr(Fields, i + 'a')) != NULL) {	    if (isupper(c))		p--;	    if ((p[1] != '\0') && (p >= Fields)) {		ch = p[0];		p[0] = p[1];		p[1] = ch;	    }	} else {	    break;	}    }    Numfields = make_header();}/*	 * toggle displayed fields	 */void change_fields(void){    int i, changed = 0;    int row, col;    char c, *p;    char tmp[2] = " ";    show_fields();    for (;;) {	PUTP(tgoto(cm, 0, 0));	PUTP(top_clrtoeol);	PUTP(tgoto(cm, 3, 0));	PUTP(mr);	printf("Current Field Order: %s", Fields);	PUTP(me);	putchar('\n');	PUTP(tgoto(cm, 0, 1));	printf("Toggle fields with a-x, any other key to return: ");	fflush(stdout);	if (!Batch) { /* should always be true, but... */	    tcsetattr(0, TCSAFLUSH, &Rawtty);	    read(0, &c, 1);	    tcsetattr(0, TCSAFLUSH, &Savetty);	}	i = toupper(c) - 'A';	if (i >= 0 && i < sizeof headers / sizeof headers[0]) {	    row = i % (Lines - 3) + 3;	    col = i / (Lines - 3) * 40;	    PUTP(tgoto(cm, col, row));	    if ((p = strchr(Fields, i + 'A')) != NULL) {	/* deselect Field */		*p = i + 'a';		putchar(' ');	    } else if ((p = strchr(Fields, i + 'a')) != NULL) {		/* select previously */		*p = i + 'A';	/* deselected field */		putchar('*');	    } else {		/* select new field */		tmp[0] = i + 'A';		strcat(Fields, tmp);		putchar('*');	    }	    changed = 1;	    fflush(stdout);	} else	    break;    }    if (changed)	Numfields = make_header();}/* Do the scaling stuff   scale_time(time,width) - interprets time in seconds, formats it to fit width   Both return pointer to static char*.*/char *scale_time(int time,int width) {	static char buf[100];	/* Try successively higher units until it fits */	sprintf(buf,"%d:%02d",time/60,time%60);	/* minutes:seconds */	if (strlen(buf)<=width) 		return buf;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -