1 /* Recursively descend the filesystem and visit each file. */
20 void scandir(const string& path);
30 if ((stat_buf.st_mode & S_IFMT) != S_IFREG) {
31 printf("file is no longer a regular file!\n");
36 ssize_t res = read(fd, buf, sizeof(buf));
40 printf("Error while reading: %m\n");
42 } else if (res == 0) {
49 printf("Bytes read: %Ld\n", size);
52 void scanfile(const string& path)
57 lstat(path.c_str(), &stat_buf);
59 printf("%s:\n", path.c_str());
60 printf(" ino=%Ld, perm=%04o, uid=%d, gid=%d, nlink=%d, blksize=%d, size=%Ld\n",
61 (int64_t)stat_buf.st_ino, stat_buf.st_mode & 07777,
62 stat_buf.st_uid, stat_buf.st_gid, stat_buf.st_nlink,
63 (int)stat_buf.st_blksize, (int64_t)stat_buf.st_size);
65 switch (stat_buf.st_mode & S_IFMT) {
71 printf(" special file\n");
74 printf(" regular file\n");
75 /* Be paranoid when opening the file. We have no guarantee that the
76 * file was not replaced between the stat() call above and the open()
77 * call below, so we might not even be opening a regular file. That
78 * the file descriptor refers to a regular file is checked in
79 * dumpfile(). But we also supply flags to open to to guard against
80 * various conditions before we can perform that verification:
81 * - O_NOFOLLOW: in the event the file was replaced by a symlink
82 * - O_NONBLOCK: prevents open() from blocking if the file was
84 * We also add in O_NOATIME, since this may reduce disk writes (for
86 fd = open(path.c_str(), O_RDONLY|O_NOATIME|O_NOFOLLOW|O_NONBLOCK);
88 /* Drop the use of the O_NONBLOCK flag; we only wanted that for file
90 flags = fcntl(fd, F_GETFL);
91 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
98 printf(" directory\n");
104 void scandir(const string& path)
106 printf("Scan directory: %s\n", path.c_str());
108 DIR *dir = opendir(path.c_str());
111 printf("Error: %m\n");
116 vector<string> contents;
117 while ((ent = readdir(dir)) != NULL) {
118 string filename(ent->d_name);
119 if (filename == "." || filename == "..")
121 contents.push_back(filename);
124 sort(contents.begin(), contents.end());
126 for (vector<string>::iterator i = contents.begin();
127 i != contents.end(); ++i) {
128 const string& filename = *i;
129 printf(" d_name = '%s'\n", filename.c_str());
130 scanfile(path + "/" + filename);
136 int main(int argc, char *argv[])