apps/top.c
/**
 * @brief Collect information for a process from its procfs entry.
 *
 * @p dent Directory entry from calling readdir on /proc.
 * @returns Process information that must be freed by the caller.
 */
@brief Collect information for a process from its procfs entry.
@p dent Directory entry from calling readdir on /proc.
@returns Process information that must be freed by the caller.
@brief Collect information for a process from its procfs entry . @p dent Directory entry from calling readdir on / proc . @returns Process information that must be freed by the caller .
struct process * process_entry(struct dirent *dent) {
	char tmp[300];
	FILE * f;
	char line[LINE_LEN];
	int pid = 0, uid = 0, tgid = 0, mem = 0, shm = 0, vsz = 0, cpu = 0, cpua = 0;
	char name[100];
	sprintf(tmp, "/proc/%s/status", dent->d_name);
	f = fopen(tmp, "r");
	if (!f) {
		return NULL;
	}
	line[0] = 0;
	while (fgets(line, LINE_LEN, f) != NULL) {
		char * n = strstr(line,"\n");
		if (n) { *n = '\0'; }
		char * tab = strstr(line,"\t");
		if (tab) {
			*tab = '\0';
			tab++;
		}
		if (strstr(line, "Pid:") == line) {
			pid = atoi(tab);
		} else if (strstr(line, "Uid:") == line) {
			uid = atoi(tab);
		} else if (strstr(line, "Tgid:") == line) {
			tgid = atoi(tab);
		} else if (strstr(line, "Name:") == line) {
			strcpy(name, tab);
		} else if (strstr(line, "VmSize:") == line) {
			vsz = atoi(tab);
		} else if (strstr(line, "RssShmem:") == line) {
			shm = atoi(tab);
		} else if (strstr(line, "MemPermille:") == line) {
			mem = atoi(tab);
		} else if (strstr(line, "CpuPermille:") == line) {
			cpu = strtoul(tab, &tab, 10);
			cpua = cpu;
			cpua += strtoul(tab, &tab, 10);
			cpua += strtoul(tab, &tab, 10);
			cpua += strtoul(tab, &tab, 10);
			cpua /= 4;
		}
	}
	fclose(f);
	if (tgid != pid) {
		struct process * parent = process_from_pid(tgid);
		if (parent) {
			parent->cpu += cpu;
			parent->cpua += cpua;
		}
		return NULL;
	}
	struct process * out = malloc(sizeof(struct process));
	out->uid = uid;
	out->pid = tgid;
	out->tid = pid;
	out->mem = mem;
	out->shm = shm;
	out->vsz = vsz;
	out->cpu = cpu;
	out->cpua = cpua;
	out->process = strdup(name);
	out->command_line = NULL;
	out->user = format_username(out->uid);
	hashmap_set(process_ents, (void*)(uintptr_t)pid, out);
	sprintf(tmp, "/proc/%s/cmdline", dent->d_name);
	f = fopen(tmp, "r");
	char foo[1024];
	int s = fread(foo, 1, 1024, f);
	if (s > 0) {
		out->command_line = malloc(s + 1);
		memset(out->command_line, 0, s + 1);
		memcpy(out->command_line, foo, s);
		for (int i = 0; i < s; ++i) {
			if (out->command_line[i] == 30) {
				out->command_line[i] = ' ';
			}
		}
	}
	fclose(f);
	update_column_widths(out);
	return out;
}
struct process * process_entry ( struct dirent * dent ) { char tmp [ 300 ] ; FILE * f ; char line [ LINE_LEN ] ; int pid = 0 , uid = 0 , tgid = 0 , mem = 0 , shm = 0 , vsz = 0 , cpu = 0 , cpua = 0 ; char name [ 100 ] ; sprintf ( tmp , " " , dent -> d_name ) ; f = fopen ( tmp , " " ) ; if ( ! f ) { return NULL ; } line [ 0 ] = 0 ; while ( fgets ( line , LINE_LEN , f ) != NULL ) { char * n = strstr ( line , " \n " ) ; if ( n ) { * n = ' \0 ' ; } char * tab = strstr ( line , " \t " ) ; if ( tab ) { * tab = ' \0 ' ; tab ++ ; } if ( strstr ( line , " " ) == line ) { pid = atoi ( tab ) ; } else if ( strstr ( line , " " ) == line ) { uid = atoi ( tab ) ; } else if ( strstr ( line , " " ) == line ) { tgid = atoi ( tab ) ; } else if ( strstr ( line , " " ) == line ) { strcpy ( name , tab ) ; } else if ( strstr ( line , " " ) == line ) { vsz = atoi ( tab ) ; } else if ( strstr ( line , " " ) == line ) { shm = atoi ( tab ) ; } else if ( strstr ( line , " " ) == line ) { mem = atoi ( tab ) ; } else if ( strstr ( line , " " ) == line ) { cpu = strtoul ( tab , & tab , 10 ) ; cpua = cpu ; cpua += strtoul ( tab , & tab , 10 ) ; cpua += strtoul ( tab , & tab , 10 ) ; cpua += strtoul ( tab , & tab , 10 ) ; cpua /= 4 ; } } fclose ( f ) ; if ( tgid != pid ) { struct process * parent = process_from_pid ( tgid ) ; if ( parent ) { parent -> cpu += cpu ; parent -> cpua += cpua ; } return NULL ; } struct process * out = malloc ( sizeof ( struct process ) ) ; out -> uid = uid ; out -> pid = tgid ; out -> tid = pid ; out -> mem = mem ; out -> shm = shm ; out -> vsz = vsz ; out -> cpu = cpu ; out -> cpua = cpua ; out -> process = strdup ( name ) ; out -> command_line = NULL ; out -> user = format_username ( out -> uid ) ; hashmap_set ( process_ents , ( void * ) ( uintptr_t ) pid , out ) ; sprintf ( tmp , " " , dent -> d_name ) ; f = fopen ( tmp , " " ) ; char foo [ 1024 ] ; int s = fread ( foo , 1 , 1024 , f ) ; if ( s > 0 ) { out -> command_line = malloc ( s + 1 ) ; memset ( out -> command_line , 0 , s + 1 ) ; memcpy ( out -> command_line , foo , s ) ; for ( int i = 0 ; i < s ; ++ i ) { if ( out -> command_line [ i ] == 30 ) { out -> command_line [ i ] = ' ' ; } } } fclose ( f ) ; update_column_widths ( out ) ; return out ; }
@brief Collect information for a process from its procfs entry.
@brief Collect information for a process from its procfs entry .
/* Add this thread's CPU usage to the parent */