Skip to content

Commit b3b1909

Browse files
committed
chapter 8 sample code 8.6
1 parent 6144cfd commit b3b1909

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
typedef struct {
2+
long ino;
3+
char name[NAME_MAX+1];
4+
} Dirent;
5+
6+
typedef struct {
7+
int fd;
8+
Dirent d;
9+
} DIR;
10+
11+
DIR *opendir(char *dirname);
12+
Dirent *readdir(DIR *dfd);
13+
void closedir(DIR *dfd);
14+
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#include <stdio.h>
2+
#include <string.h>
3+
#include <unistd.h>
4+
#include <fcntl.h>
5+
#include <sys/types.h>
6+
#include <sys/stat.h>
7+
#include "dirent.h"
8+
9+
void fsize(char *);
10+
11+
main (int argc, char **argv)
12+
{
13+
if (argc == 1)
14+
fsize(".");
15+
else
16+
while (--argc > 0)
17+
fsize(*++argv);
18+
return 0;
19+
}
20+
21+
int stat(char *, struct stat *);
22+
void dirwalk(char *, void (*fcn)(char *));
23+
24+
void fsize(char *name)
25+
{
26+
struct stat stbuf;
27+
28+
if (stat(name, &stbuf) == -1) {
29+
fprintf(stderr, "fsize: can't access %s\n", name);
30+
return;
31+
}
32+
if ((stbuf.st_mode & S_IFMT) == S_IFDIR)
33+
dirwalk(name, fsize);
34+
printf("%8ld %s\n", stbuf.st_size, name);
35+
}
36+
37+
#define MAX_PATH 1024
38+
39+
void dirwalk(char *dir, void (*fcn)(char *))
40+
{
41+
char name[MAX_PATH];
42+
Dirent *dp;
43+
DIR *dfd;
44+
45+
if ((dfd = opendir(dir)) == NULL) {
46+
fprintf(stderr, "dirwalk: can't open %s\n", dir);
47+
return;
48+
}
49+
while ((dp = readdir(dfd)) != NULL) {
50+
if (strcmp(dp->name, ".") == 0
51+
|| strcmp(dp->name, "..") == 0)
52+
continue;
53+
if (strlen(dir) + strlen(dp->name) + 2 > sizeof(name))
54+
fprintf(stderr, "dirwalk: name %s/%s too long\n",
55+
dir, dp->name);
56+
else {
57+
sprintf(name, "%s/%s", dir, dp->name);
58+
(*fcn)(name);
59+
}
60+
}
61+
closedir(dfd);
62+
}
63+
64+
int fstat(int fd, struct stat *);
65+
66+
DIR *opendir(char *dirname)
67+
{
68+
int fd;
69+
struct stat stbuf;
70+
DIR *dp;
71+
72+
if ((fd = open(dirname, O_RDONLY, 0)) == -1
73+
|| fstat(fd, &stbuf) == -1
74+
|| (stbuf.st_mode & S_IFMT) != S_IFDIR
75+
|| (dp = (DIR *) malloc(sizeof(DIR))) == NULL)
76+
return NULL;
77+
dp->fd = fd;
78+
return dp;
79+
}
80+
81+
void closedir(DIR *dp)
82+
{
83+
if (dp) {
84+
close(dp->fd);
85+
free(dp);
86+
}
87+
}
88+
89+
#include <sys/dir.h>
90+
91+
Dirent *readdir(DIR *dp)
92+
{
93+
struct direct dirbuf;
94+
static Dirent d;
95+
96+
while (read(dp->fd, (char *) &dirbuf, sizeof(dirbuf))
97+
== sizeof(dirbuf)) {
98+
if (dirbuf.d_ino == 0)
99+
continue;
100+
d.ino = dirbuf.d_ino;
101+
strncpy(d.name, dirbuf.d_name, DIRSIZ);
102+
d.name[DIRSIZ] = '\0';
103+
return &d;
104+
}
105+
return NULL;
106+
}
107+

0 commit comments

Comments
 (0)