79287646

Date: 2024-12-17 11:15:21
Score: 0.5
Natty:
Report link

As @TedLyngmo and @robertklep pointed in their comments, the string returned by getenv() function shouldn't be changed by the application. So, the problem was solved by just copying the returned string into a new string and tokenizing the new one, leaving the original string untouched.

Here is the new working code refactored as @xing suggested in his answer to keep parsing and searching logic separated.

bool tokenize(char *str, char tokens[][100], int max_tokens, int *count, const char *delimiter) {
  char *token;                                                                   
  int num_tokens = 0;                                                            
  token = strtok(str, delimiter);                                                
  if (!token)                                                                    
    return false;                                                                
  strcpy(tokens[0], token);                                                      
  num_tokens++;                                                                  
  for (int i = 1; token && i < max_tokens; i++) {                                        
    token = strtok(NULL, delimiter);                                             
    if(token) {                                                                  
      strcpy(tokens[i], token);                                                  
      num_tokens++;                                                              
    }                                                                            
  }                                                                              
  *count = num_tokens;                                                           
  return true;                                                                   
}          

bool str_in_path(char *target, char *result) {
  const char *path = getenv("PATH");
  char path_copy[strlen(path)];
  strcpy(path_copy, path);  // copying the path to avoid manipulating the original string returned by getenv()
  char dirs[20][100] = {};
  int num_dirs;
  tokenize(path_copy, dirs, 20, &num_dirs, ":"); // tokenizing the copied path instead of the original one.

  for (int i = 0; i < num_dirs; i++) {
    struct dirent *entry = NULL;
    DIR *dir = opendir(dirs[i]);
    if (dir == NULL) {
      fprintf(stderr, "can't open directory %s\n", dirs[i]);
      continue;
    }                                                                                                                                                              
    while ((entry = readdir(dir)) != NULL) {
      if (!strcmp(target, entry->d_name)) {
        strcpy(result, dirs[i]);
        strcat(result, "/");
        strcat(result, entry->d_name);
        closedir(dir);
        return true;
      }
    }
    closedir(dir);
  }
  return false;
}

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @TedLyngmo
  • User mentioned (0): @robertklep
  • User mentioned (0): @xing
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Mostafa Kashwaa