Пример #1
0
int find_fd_for_pid(pid_t pid, int *fd_list, int max_fd)
{
DIR *proc;
struct dirent *direntp;
char path_dir[MAXPATHLEN + 1];
char fullpath[MAXPATHLEN + 1];
char link_dest[MAXPATHLEN + 1];
struct stat stat_buf;
int count = 0;
ssize_t len;

snprintf(path_dir, MAXPATHLEN, "%s/%d/fd", PROC_PATH, pid);

proc = opendir(path_dir);
if (!proc) {
    nperror("opendir");
    nfprintf(stderr,"Can't open %s\n",path_dir);
    return 0;
}

while ((direntp = readdir(proc)) != NULL) {
    snprintf(fullpath, MAXPATHLEN, "%s/%s", path_dir, direntp->d_name);
    if (stat(fullpath, &stat_buf) == -1) {
        if (flag_debug)
            nperror("stat (find_fd_for_pid)");
        continue;
    }

    // if not a regular file or a block device
    if(!S_ISREG(stat_buf.st_mode) && !S_ISBLK(stat_buf.st_mode))
        continue;

    // try to read link ...
    len = readlink(fullpath, link_dest, MAXPATHLEN);
    if (len != -1)
        link_dest[len] = 0;
    else
        continue;

    // try to stat link target (invalid link ?)
    if (stat(link_dest, &stat_buf) == -1)
        continue;

    if (is_ignored_file(fullpath) || is_ignored_file(link_dest))
        continue;

    // OK, we've found a potential interesting file.

    fd_list[count++] = atoi(direntp->d_name);
    //~ printf("[debug] %s\n",fullpath);
    if (count == max_fd)
        break;
}

closedir(proc);
return count;
}
Пример #2
0
int find_pids_by_binary_name(char *bin_name, pidinfo_t *pid_list, int max_pids)
{
DIR *proc;
struct dirent *direntp;
struct stat stat_buf;
char fullpath_dir[MAXPATHLEN + 1];
char fullpath_exe[MAXPATHLEN + 1];
char exe[MAXPATHLEN + 1];
ssize_t len;
int pid_count=0;

proc=opendir(PROC_PATH);
if (!proc) {
    nperror("opendir");
    nfprintf(stderr,"Can't open %s\n",PROC_PATH);
    exit(EXIT_FAILURE);
}

while ((direntp = readdir(proc)) != NULL) {
    snprintf(fullpath_dir, MAXPATHLEN, "%s/%s", PROC_PATH, direntp->d_name);

    if (stat(fullpath_dir, &stat_buf) == -1) {
        if (flag_debug)
            nperror("stat (find_pids_by_binary_name)");
        continue;
    }

    if ((S_ISDIR(stat_buf.st_mode) && is_numeric(direntp->d_name))) {
        snprintf(fullpath_exe, MAXPATHLEN, "%s/exe", fullpath_dir);
        len=readlink(fullpath_exe, exe, MAXPATHLEN);
        if (len != -1)
            exe[len] = 0;
        else {
            // Will be mostly "Permission denied"
            //~ nperror("readlink");
            continue;
        }

        if (!strcmp(basename(exe), bin_name)) {
            pid_list[pid_count].pid = atol(direntp->d_name);
            strcpy(pid_list[pid_count].name, bin_name);
            pid_count++;
            if(pid_count == max_pids)
                break;
        }
    }
}

closedir(proc);
return pid_count;
}
Пример #3
0
int monitor_processes(int *nb_pid)
{
int pid_count, fd_count, result_count;
int i,j;
pidinfo_t pidinfo_list[MAX_PIDS];
fdinfo_t fdinfo;
fdinfo_t biggest_fd;
int fdnum_list[MAX_FD_PER_PID];
off_t max_size;
char fsize[64];
char fpos[64];
char ftroughput[64];
float perc;
result_t results[MAX_RESULTS];
signed char still_there;
signed char search_all = 1;

pid_count = 0;

if (proc_specifiq_name_cnt) {
    for (i = 0; i < proc_specifiq_name_cnt; ++i)
        pid_count += find_pids_by_binary_name(proc_specifiq_name[i],
                                              pidinfo_list + pid_count,
                                              MAX_PIDS - pid_count);
    search_all = 0;
}

if (proc_specifiq_pid) {
    pid_count += find_pid_by_id(proc_specifiq_pid,
                                  pidinfo_list + pid_count);
    search_all = 0;
}

if (search_all) {
    for (i = 0 ; proc_names[i] ; i++) {
        pid_count += find_pids_by_binary_name(proc_names[i],
                                              pidinfo_list + pid_count,
                                              MAX_PIDS - pid_count);
        if(pid_count >= MAX_PIDS) {
            nfprintf(stderr, "Found too much procs (max = %d)\n",MAX_PIDS);
            break;
        }
    }
}

*nb_pid = pid_count;

if (!pid_count) {
    if (flag_quiet)
        return 0;
    if (flag_monitor || flag_monitor_continous) {
        clear();
	refresh();
    }
    nfprintf(stderr,"No command currently running: ");
    for (i = 0 ; proc_names[i] ; i++) {
        nfprintf(stderr,"%s, ", proc_names[i]);
    }
    nfprintf(stderr,"exiting.\n");
    return 0;
}

result_count = 0;

for (i = 0 ; i < pid_count ; i++) {
    fd_count = find_fd_for_pid(pidinfo_list[i].pid, fdnum_list, MAX_FD_PER_PID);

    max_size = 0;

    // let's find the biggest opened file
    for (j = 0 ; j < fd_count ; j++) {
        get_fdinfo(pidinfo_list[i].pid, fdnum_list[j], &fdinfo);

        if (fdinfo.size > max_size) {
            biggest_fd = fdinfo;
            max_size = fdinfo.size;
        }
    }

    if (!max_size) { // nothing found
        nprintf("[%5d] %s inactive/flushing/streaming/...\n",
                pidinfo_list[i].pid,
                pidinfo_list[i].name);
        continue;
    }

    // We've our biggest_fd now, let's store the result
    results[result_count].pid = pidinfo_list[i];
    results[result_count].fd = biggest_fd;
    results[result_count].hbegin = NULL;
    results[result_count].hend = NULL;
    results[result_count].hsize = 0;

    result_count++;
}

// wait a bit, so we can estimate the throughput
if (flag_throughput)
    usleep(1000000 * throughput_wait_secs);
if (flag_monitor || flag_monitor_continous) {
    clear();
    refresh();
}
copy_and_clean_results(results, result_count, 1);
for (i = 0 ; i < result_count ; i++) {

    if (flag_throughput) {
        still_there = get_fdinfo(results[i].pid.pid, results[i].fd.num, &fdinfo);
        if (still_there && strcmp(results[i].fd.name, fdinfo.name))
            still_there = 0; // still there, but it's not the same file !
    } else
        still_there = 0;

    if (!still_there) {
        // pid is no more here (or no throughput was asked), use initial info
        format_size(results[i].fd.pos, fpos);
        format_size(results[i].fd.size, fsize);
        perc = ((double)100 / (double)results[i].fd.size) * (double)results[i].fd.pos;
    } else {
        // use the newest info
        format_size(fdinfo.pos, fpos);
        format_size(fdinfo.size, fsize);
        perc = ((double)100 / (double)fdinfo.size) * (double)fdinfo.pos;

    }

    nprintf("[%5d] %s %s %.1f%% (%s / %s)",
        results[i].pid.pid,
        results[i].pid.name,
        results[i].fd.name,
        perc,
        fpos,
        fsize);

    if (flag_throughput && still_there) {
        // results[i] vs fdinfo
        long long usec_diff;
        off_t byte_diff;
        off_t bytes_per_sec;

        usec_diff =   (fdinfo.tv.tv_sec  - results[i].fd.tv.tv_sec) * 1000000L
                    + (fdinfo.tv.tv_usec - results[i].fd.tv.tv_usec);
        byte_diff = fdinfo.pos - results[i].fd.pos;
        results[i].hsize += add_to_hlist(&results[i].hbegin, &results[i].hend, results[i].hsize, byte_diff / (usec_diff / 1000000.0));
        bytes_per_sec = get_hlist_average(results[i].hbegin, results[i].hsize);

        format_size(bytes_per_sec, ftroughput);
        nprintf(" %s/s", ftroughput);
        if (bytes_per_sec && fdinfo.size - fdinfo.pos > 0) {
            print_eta((fdinfo.size - fdinfo.pos) / bytes_per_sec);
        }
    }


    nprintf("\n");

    // Need to work on window width when using screen/watch/...
    //~ printf("    [");
    //~ print_bar(perc, ws.ws_col-6);
    //~ printf("]\n");
}
copy_and_clean_results(results, result_count, 0);
return 0;
}