comparison lib/lib.c @ 1219:468444e5c7c5 draft

Move mkpathat to lib, remove redundant function used by patch.
author Rob Landley <rob@landley.net>
date Tue, 11 Mar 2014 20:44:55 -0500
parents fba5d8d3905c
children e1b09affb6db
comparison
equal deleted inserted replaced
1218:fba5d8d3905c 1219:468444e5c7c5
112 else offset -= or; 112 else offset -= or;
113 if (or < try) break; 113 if (or < try) break;
114 } 114 }
115 115
116 return offset; 116 return offset;
117 }
118
119 // flags: 1=make last dir (with mode lastmode, otherwise skips last component)
120 // 2=make path (already exists is ok)
121 // 4=verbose
122 // returns 0 = path ok, 1 = error
123 int mkpathat(int atfd, char *dir, mode_t lastmode, int flags)
124 {
125 struct stat buf;
126 char *s;
127
128 // mkdir -p one/two/three is not an error if the path already exists,
129 // but is if "three" is a file. The others we dereference and catch
130 // not-a-directory along the way, but the last one we must explicitly
131 // test for. Might as well do it up front.
132
133 if (!fstatat(atfd, dir, &buf, 0) && !S_ISDIR(buf.st_mode)) {
134 errno = EEXIST;
135 return 1;
136 }
137
138 // Skip leading / of absolute paths
139 while (*dir == '/') dir++;
140
141 for (s=dir; ;s++) {
142 char save = 0;
143 mode_t mode = (0777&~toys.old_umask)|0300;
144
145 // Skip leading / of absolute paths.
146 if (*s == '/' && (flags&2)) {
147 save = *s;
148 *s = 0;
149 } else if (*s) continue;
150
151 // Use the mode from the -m option only for the last directory.
152 if (!save) {
153 if (flags&1) mode = lastmode;
154 else break;
155 }
156
157 if (mkdirat(atfd, dir, mode)) {
158 if (!(flags&2) || errno != EEXIST) return 1;
159 } else if (flags&4)
160 fprintf(stderr, "%s: created directory '%s'\n", toys.which->name, dir);
161
162 if (!(*s = save)) break;
163 }
164
165 return 0;
117 } 166 }
118 167
119 // Split a path into linked list of components, tracking head and tail of list. 168 // Split a path into linked list of components, tracking head and tail of list.
120 // Filters out // entries with no contents. 169 // Filters out // entries with no contents.
121 struct string_list **splitpath(char *path, struct string_list **list) 170 struct string_list **splitpath(char *path, struct string_list **list)