Mercurial > hg > mercurial-crew-with-dirclash
comparison mercurial/osutil.c @ 5425:830f6e280c90
osutils: pull file stat loop into its own function
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Mon, 08 Oct 2007 18:47:16 -0500 |
parents | 005638db9d0c |
children | e760cb72c02e |
comparison
equal
deleted
inserted
replaced
5424:005638db9d0c | 5425:830f6e280c90 |
---|---|
107 if (S_ISFIFO(mode)) return S_IFIFO; | 107 if (S_ISFIFO(mode)) return S_IFIFO; |
108 if (S_ISSOCK(mode)) return S_IFSOCK; | 108 if (S_ISSOCK(mode)) return S_IFSOCK; |
109 return mode; | 109 return mode; |
110 } | 110 } |
111 | 111 |
112 static PyObject *statfiles(PyObject *list, PyObject *ctor_args, int keep, | |
113 char *path, int len, DIR *dir) | |
114 { | |
115 struct stat buf; | |
116 struct stat *stp = &buf; | |
117 int kind; | |
118 int ret; | |
119 ssize_t i; | |
120 ssize_t size = PyList_Size(list); | |
121 #ifdef AT_SYMLINK_NOFOLLOW | |
122 int dfd = dirfd(dir); | |
123 #endif | |
124 | |
125 for (i = 0; i < size; i++) { | |
126 PyObject *elt = PyList_GetItem(list, i); | |
127 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); | |
128 PyObject *py_st = NULL; | |
129 PyObject *py_kind = PyTuple_GET_ITEM(elt, 1); | |
130 | |
131 kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind); | |
132 if (kind != -1 && !keep) | |
133 continue; | |
134 | |
135 strncat(path + len + 1, name, PATH_MAX - len); | |
136 path[PATH_MAX] = 0; | |
137 | |
138 if (keep) { | |
139 py_st = PyObject_CallObject( | |
140 (PyObject *)&listdir_stat_type, ctor_args); | |
141 if (!py_st) | |
142 return PyErr_NoMemory(); | |
143 stp = &((struct listdir_stat *)py_st)->st; | |
144 PyTuple_SET_ITEM(elt, 2, py_st); | |
145 } | |
146 | |
147 #ifdef AT_SYMLINK_NOFOLLOW | |
148 ret = fstatat(dfd, name, stp, AT_SYMLINK_NOFOLLOW); | |
149 #else | |
150 ret = lstat(path, stp); | |
151 #endif | |
152 if (ret == -1) | |
153 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, | |
154 path); | |
155 | |
156 if (kind == -1) | |
157 kind = mode_to_kind(stp->st_mode); | |
158 | |
159 if (py_kind == Py_None && kind != -1) { | |
160 py_kind = PyInt_FromLong(kind); | |
161 if (!py_kind) | |
162 return PyErr_NoMemory(); | |
163 Py_XDECREF(Py_None); | |
164 PyTuple_SET_ITEM(elt, 1, py_kind); | |
165 } | |
166 } | |
167 | |
168 return 0; | |
169 } | |
170 | |
112 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs) | 171 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs) |
113 { | 172 { |
114 static char *kwlist[] = { "path", "stat", NULL }; | 173 static char *kwlist[] = { "path", "stat", NULL }; |
115 PyObject *statobj = NULL; | 174 PyObject *statobj = NULL; |
116 DIR *dir = NULL; | 175 DIR *dir = NULL; |
117 struct dirent *ent; | 176 struct dirent *ent; |
118 PyObject *list = NULL; | 177 PyObject *list = NULL; |
178 PyObject *err = NULL; | |
119 PyObject *ctor_args = NULL; | 179 PyObject *ctor_args = NULL; |
120 int all_kinds = 1; | 180 int all_kinds = 1; |
121 char full_path[PATH_MAX + 10]; | 181 char full_path[PATH_MAX + 10]; |
122 int path_len; | 182 int path_len; |
123 int do_stat; | 183 int do_stat; |
124 char *path; | 184 char *path; |
125 int ret; | |
126 ssize_t size; | |
127 ssize_t i; | |
128 int dfd; | |
129 | 185 |
130 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist, | 186 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist, |
131 &path, &path_len, &statobj)) | 187 &path, &path_len, &statobj)) |
132 goto bail; | 188 goto bail; |
133 | 189 |
208 PyList_Append(list, val); | 264 PyList_Append(list, val); |
209 Py_DECREF(val); | 265 Py_DECREF(val); |
210 } | 266 } |
211 | 267 |
212 PyList_Sort(list); | 268 PyList_Sort(list); |
213 size = PyList_Size(list); | 269 |
214 #ifdef AT_SYMLINK_NOFOLLOW | 270 if (do_stat) { |
215 dfd = dirfd(dir); | 271 ctor_args = PyTuple_New(0); |
216 #endif | 272 if (!ctor_args) |
217 | |
218 if (!(do_stat || !all_kinds)) | |
219 goto done; | |
220 | |
221 for (i = 0; i < size; i++) { | |
222 PyObject *elt = PyList_GetItem(list, i); | |
223 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); | |
224 PyObject *py_st = NULL; | |
225 PyObject *py_kind = PyTuple_GET_ITEM(elt, 1); | |
226 struct listdir_stat *st; | |
227 struct stat buf; | |
228 struct stat *stp = &buf; | |
229 int kind; | |
230 | |
231 kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind); | |
232 | |
233 if (kind != -1 && !do_stat) | |
234 continue; | |
235 | |
236 strncat(full_path + path_len + 1, name, PATH_MAX - path_len); | |
237 full_path[PATH_MAX] = 0; | |
238 | |
239 if (do_stat) { | |
240 if (!ctor_args) { | |
241 ctor_args = PyTuple_New(0); | |
242 if (!ctor_args) | |
243 goto bail; | |
244 } | |
245 | |
246 py_st = PyObject_CallObject((PyObject *)&listdir_stat_type, | |
247 ctor_args); | |
248 st = (struct listdir_stat *)py_st; | |
249 if (!st) | |
250 goto bail; | |
251 stp = &st->st; | |
252 PyTuple_SET_ITEM(elt, 2, py_st); | |
253 } | |
254 | |
255 #ifdef AT_SYMLINK_NOFOLLOW | |
256 ret = fstatat(dfd, name, stp, AT_SYMLINK_NOFOLLOW); | |
257 #else | |
258 ret = lstat(full_path, stp); | |
259 #endif | |
260 if (ret == -1) { | |
261 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, | |
262 full_path); | |
263 goto bail; | 273 goto bail; |
264 } | |
265 if (kind == -1) | |
266 kind = mode_to_kind(stp->st_mode); | |
267 | |
268 if (py_kind == Py_None && kind != -1) { | |
269 py_kind = PyInt_FromLong(kind); | |
270 if (!py_kind) | |
271 goto bail; | |
272 Py_XDECREF(Py_None); | |
273 PyTuple_SET_ITEM(elt, 1, py_kind); | |
274 } | |
275 } | 274 } |
276 | 275 |
276 if (do_stat || !all_kinds) | |
277 if (statfiles(list, ctor_args, do_stat, full_path, path_len, | |
278 dir)) | |
279 goto bail; | |
277 goto done; | 280 goto done; |
278 | 281 |
279 bail: | 282 bail: |
280 Py_XDECREF(list); | 283 Py_XDECREF(list); |
281 | 284 |
282 done: | 285 done: |
283 Py_XDECREF(ctor_args); | 286 Py_XDECREF(ctor_args); |
284 if (dir) | 287 if (dir) |
285 closedir(dir); | 288 closedir(dir); |
286 return list; | 289 return err ? err : list; |
287 } | 290 } |
288 | 291 |
289 | 292 |
290 static char osutil_doc[] = "Native operating system services."; | 293 static char osutil_doc[] = "Native operating system services."; |
291 | 294 |