- struct dirent *de;
- pid_t pid;
- char *dname;
-
- if(!(d = opendir(FUSER_PROC_DIR))) return 0;
- while((de = readdir(d)) != NULL) {
- pid = (pid_t)atoi(de->d_name);
- if(!pid) continue;
- dname = concat_subpath_file(FUSER_PROC_DIR, de->d_name);
- if(chdir(dname) < 0) {
- free(dname);
- continue;
+ struct dirent *d_ent;
+ smallint stop_scan;
+ smallint retval;
+
+ d = opendir(path);
+ if (d == NULL)
+ return 0;
+
+ G.recursion_depth++;
+ retval = 0;
+ stop_scan = 0;
+ while (!stop_scan && (d_ent = readdir(d)) != NULL) {
+ struct stat statbuf;
+ pid_t pid;
+ char *subpath;
+
+ subpath = concat_subpath_file(path, d_ent->d_name);
+ if (subpath == NULL)
+ continue; /* . or .. */
+
+ switch (G.recursion_depth) {
+ case PROC_DIR:
+ pid = (pid_t)bb_strtou(d_ent->d_name, NULL, 10);
+ if (errno != 0
+ || pid == G.mypid
+ /* "this PID doesn't use specified FILEs or PORT/PROTO": */
+ || scan_recursive(subpath) == 0
+ ) {
+ break;
+ }
+ if (option_mask32 & OPT_KILL) {
+ if (kill(pid, G.killsig) != 0) {
+ bb_perror_msg("kill pid %s", d_ent->d_name);
+ G.kill_failed = 1;
+ }
+ }
+ if (!(option_mask32 & OPT_SILENT))
+ printf("%s ", d_ent->d_name);
+ retval = 1;
+ break;
+
+ case PROC_DIR_LINKS:
+ switch (
+ index_in_substrings(
+ "cwd" "\0" "exe" "\0"
+ "root" "\0" "fd" "\0"
+ "lib" "\0" "mmap" "\0"
+ "maps" "\0",
+ d_ent->d_name
+ )
+ ) {
+ enum {
+ CWD_LINK,
+ EXE_LINK,
+ ROOT_LINK,
+ FD_DIR_LINKS,
+ LIB_DIR_LINKS,
+ MMAP_DIR_LINKS,
+ MAPS,
+ };
+ case CWD_LINK:
+ case EXE_LINK:
+ case ROOT_LINK:
+ goto scan_link;
+ case FD_DIR_LINKS:
+ case LIB_DIR_LINKS:
+ case MMAP_DIR_LINKS:
+ stop_scan = scan_recursive(subpath);
+ if (stop_scan)
+ retval = stop_scan;
+ break;
+ case MAPS:
+ stop_scan = scan_proc_net_or_maps(subpath, 0);
+ if (stop_scan)
+ retval = stop_scan;
+ default:
+ break;
+ }
+ break;
+ case PROC_SUBDIR_LINKS:
+ scan_link:
+ if (stat(subpath, &statbuf) < 0)
+ break;
+ stop_scan = search_dev_inode(&statbuf);
+ if (stop_scan)
+ retval = stop_scan;
+ default:
+ break;