You don't allocate enough space for the string.
You don't quite allocate enough for 'mydir' (off by one); You do an unorthodox length calculation which ignores the actual length of 'mydir'; you then make a good copy of the directory name (but leak the memory previously allocated); you then concatenate the name over the end of the space allocated by strdup()
, which is always bad. If you omitted the sizeof()
, then you would be allocating one byte too few for a null terminated directory string.
You also should not cache the separate return values from readdir()
because it generally returns a pointer to the same bit of memory each time. You are certainly not authorized to assume that it does otherwise.
You are also trampling over freed memory if you really release buf inside the loop; you allocate just once, and free many times.
Normally, you would not bother to allocate the buf
at all; it is not that big a structure.
You also don't self-evidently have a slash separator between the directory name and the file name component; that might not matter if you've ensured that mydir
has one on the end.
Here is a simple program that more or less does what is necessary.
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <pwd.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
static const char mydir[] = "./";
DIR *dirh;
size_t dlen = strlen(mydir) + 1;
if ((dirh = opendir(mydir)) != 0)
{
struct dirent *dirp;
while ((dirp = readdir(dirh)) != 0)
{
char *str = malloc(dlen + strlen(dirp->d_name));
if (str != 0)
{
struct stat buf;
strcpy(str, mydir);
strcat(str, dirp->d_name);
if (stat(str, &buf) == 0)
{
struct passwd *pwd = getpwuid(buf.st_uid);
if (pwd != 0)
printf("\t%s (%s)\n", str, pwd->pw_name);
}
free(str);
}
}
closedir(dirh);
}
return 0;
}