This one has got me stumped. I cannot make heads or tails of it with a debugger, or by looking at it.. I have been looking for a long time..
The code is altered from the original (first example) found here.
Here is the changed code that I am playing with:
Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#define BUFSZ 1024
int main(void)
{
DIR *dp;
struct dirent *dirp;
struct stat st;
struct passwd *pw;
struct group *grp;
char buf[BUFSZ], *bp, *ftime;
memset(buf, '\0', BUFSZ);
if ((dp = opendir(".")) == NULL) {
printf("Cannot open this directory\n");
perror("");
exit(EXIT_FAILURE);
}
while ((dirp = readdir(dp)) != NULL) {
bp = buf;
do {
if (dirp->d_reclen != 0) {
if (strcmp(dirp->d_name, ".") == 0 ||
strcmp(dirp->d_name, "..") == 0) {
break; /* Don't want to list dot and dot-dot */
}
stat(dirp->d_name, &st);
ftime = ctime(&st.st_mtime);
ftime[16] = '\0';
ftime += 4;
pw = getpwuid(st.st_uid);
grp = getgrgid(st.st_gid);
printf("%3zu %-8s %-7s %9zu %s %s\n",
st.st_nlink, pw->pw_name, grp->gr_name,
st.st_size, ftime, dirp->d_name);
}
bp += dirp->d_reclen;
dirp = (struct dirent *) (bp);
} while (dirp->d_ino != 0);
memset(buf, '\0', BUFSZ);
}
closedir(dp);
return 0;
}
The particular bits I don't get are in red. Why make a buffer, set it to zero, make bp point to it, then add the size of d_reclen to it, then turn around cast it as a struct dirent* and assign that to dirp? I am obviously missing something here. I tried doing things like
Code:
// bp += dirp->d_reclen;
// dirp = (struct dirent *) (bp);
dirp += dirp->d_reclen;
or
Code:
// bp += dirp->d_reclen;
// dirp = (struct dirent *) (bp);
dirp += dirp->d_off;
But they both segfault on me. Why the empty buffer? This thing has got me completely flummoxed.