#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <fcntl.h>
#define PATH_LINE 128
void get_pid(){
char full_path[PATH_LINE]="";
int fd;
char pid[6];
for(int i=0 ;i <99999; i ){
fd =0;
memset(full_path,0,PATH_LINE);
strcat(full_path,PROC_PATH);
sprintf(pid, "%d", i);
strcat(full_path,pid);
fd = open(full_path, O_RDONLY);
if(fd != -1){
printf("%s - fd [%d]\n", full_path, fd);
}
}
}
int main(void){
get_pid();
return 0;
}
I expected this code to print all the PIDs I have on my computer.
That is, it will try to open the folder /proc/PID and if it does not return an error, then it will print the PID.
But, he prints me a lot of PIDs that don't really run on my computer...
Is there an error in my code? I'm trying to do this without built-in structs.
terminal output:
CodePudding user response:
I saw one serious problem here. First of all, it is easier for us to view all processes with "find /proc/ -maxdepth 1 -type d 2>/dev/null" this command will show you all the processes in /proc/. I ran your code and saw that you are opening files and never close them. I added one line "close(fd);" inside the if statement and I got all the processes that run on my machine. In my opinion, this will fix your problem.
P.S. There is a limit to opened files from your program. Not closing opened files in for loop is what you missed here. You can check what is it with: "ulimit -n".
CodePudding user response:
I would not loop from 0
to 99998
and try to open all those. It takes time and it misses processes with greater pids than 99998
.
I suggest that you use opendir
, readdir
and closedir
in order to read all directory entries in /proc
and to filter out those you are interested in.
Example:
#include <dirent.h> // opendir, readdir, closedir
#include <sys/types.h>
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
// a function to check if a string consists of all digits
bool all_digits(const char *str) {
for(; *str != '\0'; str) {
if(!isdigit((unsigned char)*str)) {
return false;
}
}
return true;
}
int main(void) {
DIR* dp = opendir("/proc"); // open /proc
if(dp) {
struct dirent *curr; // see: man 3 readdir
while((curr = readdir(dp))) { // read next directory entry
if(all_digits(curr->d_name)) { // d_name holds the leaf name
puts(curr->d_name); // only print if it only has digits
}
}
closedir(dp); // finally close the directory
}
}