Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenating file with path to get full path in C

Tags:

c

file

linux

unix

Using C, I'm trying to concatenate the filenames in a directory with their paths so that I can call stat() for each, but when I try to do using strcat inside the loop it concatenates the previous filename with the next. It's modifying argv[1] during the loop, but I haven't worked with C in a long time, so I'm very confused...

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>

int main(int argc, char *argv[]) {
 struct stat buff;

 int status;

 if (argc > 1) {
  status = stat(argv[1], &buff);
  if (status != -1) {
   if (S_ISDIR(buff.st_mode)) { 
     DIR *dp = opendir(argv[1]);
     struct dirent *ep;
     char* path = argv[1];
     printf("Path = %s\n", path);

     if (dp != NULL) {
       while (ep = readdir(dp)) {
       char* fullpath = strcat(path, ep->d_name);
       printf("Full Path = %s\n", fullpath);
     }
     (void) closedir(dp);
   } else {
      perror("Couldn't open the directory");
   }
 }

  } else {
   perror(argv[1]);
   exit(1);
  }
 } else {
   perror(argv[0]]);
                exit(1);
 }

 return 0;
}
like image 566
Derek Avatar asked Dec 14 '22 00:12

Derek


2 Answers

You shouldn't modify argv[i]. Even if you do, you only have one argv[1], so doing strcat() on it is going to keep appending to whatever you had in it earlier.

You have another subtle bug. A directory name and file names in it should be separated by the path separator, / on most systems. You don't add that in your code.

To fix this, outside of your while loop:

size_t arglen = strlen(argv[1]);

You should do this in your while loop:

/* + 2 because of the '/' and the terminating 0 */
char *fullpath = malloc(arglen + strlen(ep->d_name) + 2);
if (fullpath == NULL) { /* deal with error and exit */ }
sprintf(fullpath, "%s/%s", path, ep->d_name);
/* use fullpath */
free(fullpath);
like image 112
Alok Singhal Avatar answered Dec 17 '22 22:12

Alok Singhal


Where is the memory that you are copying to? path is allocated on the stack to contain the arguments you need yo allocate the memory yourself e.g.

char path[1024] ;   // or some other number
strcpy( path, argv[1] );
// then separator
strcat( path, "/" ) ; // or "\\" in Windows
strcat( path, ep->d_name);

In production code se strncat etc to stop overflows

like image 43
mmmmmm Avatar answered Dec 17 '22 22:12

mmmmmm