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; }
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; }
signed char get_fdinfo(pid_t pid, int fdnum, fdinfo_t *fd_info) { struct stat stat_buf; char fdpath[MAXPATHLEN + 1]; char line[LINE_LEN]; ssize_t len; FILE *fp; struct timezone tz; fd_info->num = fdnum; snprintf(fdpath, MAXPATHLEN, "%s/%d/fd/%d", PROC_PATH, pid, fdnum); len=readlink(fdpath, fd_info->name, MAXPATHLEN); if (len != -1) fd_info->name[len] = 0; else { //~ nperror("readlink"); return 0; } if (stat(fd_info->name, &stat_buf) == -1) { //~ printf("[debug] %i - %s\n",pid,fd_info->name); if (flag_debug) nperror("stat (get_fdinfo)"); return 0; } if (S_ISBLK(stat_buf.st_mode)) { int fd; fd = open(fd_info->name, O_RDONLY); if (fd < 0) { if (flag_debug) nperror("open (get_fdinfo)"); return 0; } if (ioctl(fd, BLKGETSIZE64, &fd_info->size) < 0) { if (flag_debug) nperror("ioctl (get_fdinfo)"); close(fd); return 0; } close(fd); } else { fd_info->size = stat_buf.st_size; } fd_info->pos = 0; snprintf(fdpath, MAXPATHLEN, "%s/%d/fdinfo/%d", PROC_PATH, pid, fdnum); fp = fopen(fdpath, "rt"); gettimeofday(&fd_info->tv, &tz); if (!fp) { if (flag_debug) nperror("fopen (get_fdinfo)"); return 0; } while (fgets(line, LINE_LEN - 1, fp) != NULL) { line[4]=0; if (!strcmp(line, "pos:")) { fd_info->pos = atoll(line + 5); break; } } fclose(fp); return 1; }
signed char get_fdinfo(pid_t pid, int fdnum, fdinfo_t *fd_info) { struct stat stat_buf; #ifndef __APPLE__ char fdpath[MAXPATHLEN + 1]; char line[LINE_LEN]; FILE *fp; int flags; #endif struct timezone tz; fd_info->num = fdnum; fd_info->mode = PM_NONE; #ifdef __APPLE__ struct vnode_fdinfowithpath vnodeInfo; if (proc_pidfdinfo(pid, fdnum, PROC_PIDFDVNODEPATHINFO, &vnodeInfo, PROC_PIDFDVNODEPATHINFO_SIZE) <= 0) return 0; strncpy(fd_info->name, vnodeInfo.pvip.vip_path, MAXPATHLEN); #else ssize_t len; snprintf(fdpath, MAXPATHLEN, "%s/%d/fd/%d", PROC_PATH, pid, fdnum); len=readlink(fdpath, fd_info->name, MAXPATHLEN); if (len != -1) fd_info->name[len] = 0; else { //~ nperror("readlink"); return 0; } #endif if (stat(fd_info->name, &stat_buf) == -1) { //~ printf("[debug] %i - %s\n",pid,fd_info->name); if (flag_debug) nperror("stat (get_fdinfo)"); return 0; } if (S_ISBLK(stat_buf.st_mode)) { int fd; fd = open(fd_info->name, O_RDONLY); if (fd < 0) { if (flag_debug) nperror("open (get_fdinfo)"); return 0; } #ifdef __APPLE__ uint64_t bc; uint32_t bs; bs = 0; bc = 0; if (ioctl(fd, DKIOCGETBLOCKSIZE, &bs) < 0 || ioctl(fd, DKIOCGETBLOCKCOUNT, &bc) < 0) { if (flag_debug) perror("ioctl (get_fdinfo)"); return 0; } fd_info->size = bc*bs; printf("Size: %lld\n", fd_info->size); #else if (ioctl(fd, BLKGETSIZE64, &fd_info->size) < 0) { if (flag_debug) nperror("ioctl (get_fdinfo)"); close(fd); return 0; } #endif close(fd); } else { fd_info->size = stat_buf.st_size; } #ifdef __APPLE__ fd_info->pos = vnodeInfo.pfi.fi_offset; gettimeofday(&fd_info->tv, &tz); if (vnodeInfo.pfi.fi_openflags & FREAD) fd_info->mode = PM_READ; if (vnodeInfo.pfi.fi_openflags & FWRITE) fd_info->mode = PM_WRITE; if (vnodeInfo.pfi.fi_openflags & FREAD && vnodeInfo.pfi.fi_openflags & FWRITE) fd_info->mode = PM_READWRITE; #else flags = 0; fd_info->pos = 0; snprintf(fdpath, MAXPATHLEN, "%s/%d/fdinfo/%d", PROC_PATH, pid, fdnum); fp = fopen(fdpath, "rt"); gettimeofday(&fd_info->tv, &tz); if (!fp) { if (flag_debug) nperror("fopen (get_fdinfo)"); return 0; } while (fgets(line, LINE_LEN - 1, fp) != NULL) { if (!strncmp(line, "pos:", 4)) fd_info->pos = atoll(line + 5); if (!strncmp(line, "flags:", 6)) flags = atoll(line + 7); } if ((flags & O_ACCMODE) == O_RDONLY) fd_info->mode = PM_READ; if ((flags & O_ACCMODE) == O_WRONLY) fd_info->mode = PM_WRITE; if ((flags & O_ACCMODE) == O_RDWR) fd_info->mode = PM_READWRITE; fclose(fp); #endif return 1; }