Home > Back-end >  Trying to remake linux find command in C
Trying to remake linux find command in C

Time:04-29

I've been tasked with remaking a portion of the functionality of the find command. The first part I'm trying to do is just the normal "find " where it lists all files and sub-directories within that directory. I'm using the actual find command to test my results.

Anything apparent that I'm missing that's causing me to print improper file paths?

Image Order:

  1. C Code

  2. Expected Output

  3. Actual Output

  4. Tree for the directory I'm using to test

    void readSub (char* subDir)
    {
     DIR *sub_dp = opendir(subDir); //Opens directory stream
    
     struct dirent *subDirp; //define sub directory pointer
     struct stat buf; //define file status struct
    
     char t1[] = ".";
     char t2[] = "..";
     char t3[] = "/";
    
     if(sub_dp != NULL) // Was directory successfully opened
     {
             //read each entry one time only
             while((subDirp = readdir(sub_dp)) != NULL)
             {
                     char *temp = subDirp -> d_name; //check if first entry was a sub directory
    
                     //avoid searching for . and ..
                     if(strcmp(temp, t1) != 0 && strcmp(temp, t2) != 0)
                     {
                             char *tempSub = t3;
                             tempSub = strcat(tempSub, temp); //add / to entry name
                             char *temp_full_path = malloc(sizeof(char) * 2000);
                             temp_full_path = strcpy(temp_full_path, subDir);
                             strcat(temp_full_path, tempSub); //gives full path
    
                             printf("%s\n", temp_full_path);
                             DIR *subsubDP = opendir(temp_full_path); //try to open
    
                             if(subsubDP != NULL) //if not NULL then subsubDP is sub directory
                             {
                                     closedir(subsubDP); //will get opened in recursive call
                                     readSub(temp_full_path); //recursive call
                             }
                     }
             } //end of while loop
             closedir(sub_dp); //close directory stream
     }
    
     else
     {
             printf("Can't open directory\n");
             exit(2);
     }
    }
    
    int main(int argc, char **argv)
    {
            char *dir;
    
     if(argc < 2)
     {
             dir = ".";
     }
    
     else
     {
             dir = argv[1];
     }
    
     readSub(dir);
    
     exit(0);
    }
    

enter image description here

enter image description here

enter image description here

CodePudding user response:

The problem is

tempSub = strcat(tempSub, temp); //add / to entry name

tempSub points to the t3 array, which only has 2 bytes. Concatenating temp to it writes outside the array bounds, which causes undefined behavior.

You should calculate the total length of temp_full_path by adding the lengths of subDir, t3, temp, plus 1 for the null terminator, and allocate that. Since you only need this within the current loop iteration, you can use a variable-length array rather than malloc() (your code never calls free(temp_full_path)).

Replace

 char *tempSub = t3;
 tempSub = strcat(tempSub, temp); //add / to entry name
 char *temp_full_path = malloc(sizeof(char) * 2000);
 temp_full_path = strcpy(temp_full_path, subDir);
 strcat(temp_full_path, tempSub); //gives full path

with

char temp_full_path[strlen(subDir)   strlen(t3)   strlen(temp)   1];
sprintf(temp_full_path, "%s%s%s", subDir, t3, temp);
  • Related