I am reading this book, UNIX Filesystems -- Evolution, Design, and Implementation, by Steve D. Pate. I am not convinced it is a great book, as some of his first example code does not even build 'out of the box.' The following is what I am referring to:
Code:
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dirent.h>
#include <sys/unistd.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <pwd.h>
#include <grp.h>
#define BUFSZ 1024
main()
{
struct dirent *dir;
struct stat st;
struct passwd *pw;
struct group *grp;
char buf[BUFSZ], *bp, *ftime;
int dfd, fd, nread;
dfd = open(".", O_RDONLY);
bzero(buf, BUFSZ);
while (nread = getdents(dfd, (struct dirent *) &buf, BUFSZ) != 0) {
bp = buf;
dir = (struct dirent *) buf;
do {
if (dir->d_reclen != 0) {
stat(dir->d_name, &st);
ftime = ctime(&st.st_mtime);
ftime[16] = '\0';
ftime += 4;
pw = getpwuid(st.st_uid);
grp = getgrgid(st.st_gid);
printf("%3d %-8s %-7s %9d %s %s\n",
st.st_nlink, pw->pw_name, grp->gr_name,
st.st_size, ftime, dir->d_name);
}
bp = bp + dir->d_reclen;
dir = (struct dirent *) (bp);
} while (dir->d_ino != 0);
bzero(buf, BUFSZ);
}
}
This is supposed to be a general version of the ls command. Aside from things like missing headers, he makes calls to getdents, which seems to be deprecated (from reading the man page), or perhaps it was never really implemented on Linux to be used by general system programmers in the first place; I don't know, but let's assume that things have changed between now and 2003 when the book was first published -- it does not matter as much to me, as I learn a bit when I am trying to track these problems down.
Anyway, I started changing the code, to look more like this:
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 <strings.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;
//int dfd;
// dfd = open(".", O_RDONLY);
bzero(buf, BUFSZ);
if ((dp = opendir(".")) == NULL) {
printf("Cannot open this directory\n");
perror("");
exit(EXIT_FAILURE);
}
while ((dirp = readdir(dp)) != NULL) {
bp = buf;
dirp = (struct dirent *) buf;
do {
if (dirp->d_reclen != 0) {
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 = bp + dirp->d_reclen;
dirp = (struct dirent *) (bp);
} while (dirp->d_ino != 0);
bzero(buf, BUFSZ);
}
return 0;
}
It is not complete, nor correct - I am still working through understanding some of the code. The one part that gets me is this:
Code:
if (dirp->d_reclen != 0) {
The trouble is, when I run the program through the debugger, dirp->d_reclen is always 0. Why?