annotate lib/dirtree.c @ 432:01473712c9fe

Document that optflags is always an int (so 32 bit and 64 bit platforms behave the same).
author Rob Landley <rob@landley.net>
date Mon, 06 Feb 2012 21:15:19 -0600
parents 7259b853cb8b
children 44abf4d901f3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
1 /* vi: set sw=4 ts=4 :*/
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
2 /* dirtree.c - Functions for dealing with directory trees.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
3 *
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
4 * Copyright 2007 Rob Landley <rob@landley.net>
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
5 */
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
6
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
7 #include "toys.h"
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
8
258
e64dec29965d Dirtree needs to use lstat(), not stat. And failure should probably be a
Rob Landley <rob@landley.net>
parents: 156
diff changeset
9 // NOTE: This uses toybuf. Possibly it shouldn't do that.
e64dec29965d Dirtree needs to use lstat(), not stat. And failure should probably be a
Rob Landley <rob@landley.net>
parents: 156
diff changeset
10
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
11 // Create a dirtree node from a path.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
12
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
13 struct dirtree *dirtree_add_node(char *path)
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
14 {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
15 struct dirtree *dt;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
16 char *name;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
17
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
18 // Find last chunk of name.
156
1e8f4b05cb65 Remove trailing whitespace (thanks to Charlie Shepherd), and a couple comment
Rob Landley <rob@landley.net>
parents: 143
diff changeset
19
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
20 for (;;) {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
21 name = strrchr(path, '/');
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
22
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
23 if (!name) name = path;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
24 else {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
25 if (*(name+1)) name++;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
26 else {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
27 *name=0;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
28 continue;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
29 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
30 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
31 break;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
32 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
33
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
34 dt = xzalloc(sizeof(struct dirtree)+strlen(name)+1);
258
e64dec29965d Dirtree needs to use lstat(), not stat. And failure should probably be a
Rob Landley <rob@landley.net>
parents: 156
diff changeset
35 if (lstat(path, &(dt->st))) {
e64dec29965d Dirtree needs to use lstat(), not stat. And failure should probably be a
Rob Landley <rob@landley.net>
parents: 156
diff changeset
36 error_msg("Skipped '%s'",name);
e64dec29965d Dirtree needs to use lstat(), not stat. And failure should probably be a
Rob Landley <rob@landley.net>
parents: 156
diff changeset
37 free(dt);
e64dec29965d Dirtree needs to use lstat(), not stat. And failure should probably be a
Rob Landley <rob@landley.net>
parents: 156
diff changeset
38 return 0;
e64dec29965d Dirtree needs to use lstat(), not stat. And failure should probably be a
Rob Landley <rob@landley.net>
parents: 156
diff changeset
39 }
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
40 strcpy(dt->name, name);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
41
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
42 return dt;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
43 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
44
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
45 // Given a directory (in a writeable PATH_MAX buffer), recursively read in a
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
46 // directory tree.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
47 //
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
48 // If callback==NULL, allocate tree of struct dirtree and
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
49 // return root of tree. Otherwise call callback(node) on each hit, free
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
50 // structures after use, and return NULL.
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
51
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
52 struct dirtree *dirtree_read(char *path, struct dirtree *parent,
263
7c53152a483b Make cp pass most of its test suite. Still need to add symlink support.
Rob Landley <rob@landley.net>
parents: 262
diff changeset
53 int (*callback)(char *path, struct dirtree *node))
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
54 {
320
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
55 struct dirtree *dtroot = NULL, *this, **ddt = &dtroot;
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
56 DIR *dir;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
57 int len = strlen(path);
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
58
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
59 if (!(dir = opendir(path))) perror_msg("No %s", path);
270
e9f75ffd3200 If we don't remember to closedir(), the leaked filehandles add up.
Rob Landley <rob@landley.net>
parents: 263
diff changeset
60 else for (;;) {
292
b4077be6c746 Update mdev to work around the newest sysfs api breakage in the 2.6.25 kernel.
Rob Landley <rob@landley.net>
parents: 270
diff changeset
61 int norecurse = 0;
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
62 struct dirent *entry = readdir(dir);
270
e9f75ffd3200 If we don't remember to closedir(), the leaked filehandles add up.
Rob Landley <rob@landley.net>
parents: 263
diff changeset
63 if (!entry) {
e9f75ffd3200 If we don't remember to closedir(), the leaked filehandles add up.
Rob Landley <rob@landley.net>
parents: 263
diff changeset
64 closedir(dir);
e9f75ffd3200 If we don't remember to closedir(), the leaked filehandles add up.
Rob Landley <rob@landley.net>
parents: 263
diff changeset
65 break;
e9f75ffd3200 If we don't remember to closedir(), the leaked filehandles add up.
Rob Landley <rob@landley.net>
parents: 263
diff changeset
66 }
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
67
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
68 // Skip "." and ".."
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
69 if (entry->d_name[0]=='.') {
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
70 if (!entry->d_name[1]) continue;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
71 if (entry->d_name[1]=='.' && !entry->d_name[2]) continue;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
72 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
73
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
74 snprintf(path+len, sizeof(toybuf)-len, "/%s", entry->d_name);
320
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
75 *ddt = this = dirtree_add_node(path);
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
76 if (!this) continue;
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
77 this->parent = parent;
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
78 this->depth = parent ? parent->depth + 1 : 1;
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
79 if (callback) norecurse = callback(path, this);
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
80 if (!norecurse && S_ISDIR(this->st.st_mode))
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
81 this->child = dirtree_read(path, this, callback);
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
82 if (callback) free(this);
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
83 else ddt = &(this->next);
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
84 path[len]=0;
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
85 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
86
320
7259b853cb8b Work around a reiserfs bug. (One line change, switch from looking at broken struct dirent->dt_type to looking at stat() output. The rest are unrelated variable renames.)
Rob Landley <rob@landley.net>
parents: 292
diff changeset
87 return dtroot;
143
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
88 }
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
89
9cbb323f297f Break out dirtree.c and let it call a function instead of returning the data.
Rob Landley <rob@landley.net>
parents:
diff changeset
90