213 size = PyList_Size(list); |
213 size = PyList_Size(list); |
214 #ifdef AT_SYMLINK_NOFOLLOW |
214 #ifdef AT_SYMLINK_NOFOLLOW |
215 dfd = dirfd(dir); |
215 dfd = dirfd(dir); |
216 #endif |
216 #endif |
217 |
217 |
218 if (do_stat || !all_kinds) { |
218 if (!(do_stat || !all_kinds)) |
219 for (i = 0; i < size; i++) { |
219 goto done; |
220 PyObject *elt = PyList_GetItem(list, i); |
220 |
221 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); |
221 for (i = 0; i < size; i++) { |
222 PyObject *py_st = NULL; |
222 PyObject *elt = PyList_GetItem(list, i); |
223 PyObject *py_kind = PyTuple_GET_ITEM(elt, 1); |
223 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); |
224 int kind; |
224 PyObject *py_st = NULL; |
225 |
225 PyObject *py_kind = PyTuple_GET_ITEM(elt, 1); |
226 kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind); |
226 int kind; |
227 |
227 |
228 if (kind != -1 && !do_stat) |
228 kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind); |
229 continue; |
229 |
230 |
230 if (kind != -1 && !do_stat) |
231 strncat(full_path + path_len + 1, name, |
231 continue; |
232 PATH_MAX - path_len); |
232 |
233 full_path[PATH_MAX] = 0; |
233 strncat(full_path + path_len + 1, name, PATH_MAX - path_len); |
234 |
234 full_path[PATH_MAX] = 0; |
235 if (do_stat) { |
235 |
236 struct listdir_stat *st; |
236 if (do_stat) { |
237 |
237 struct listdir_stat *st; |
238 if (!ctor_args) { |
238 |
239 ctor_args = PyTuple_New(0); |
239 if (!ctor_args) { |
240 if (!ctor_args) |
240 ctor_args = PyTuple_New(0); |
241 goto bail; |
241 if (!ctor_args) |
242 } |
|
243 |
|
244 st = (struct listdir_stat *) |
|
245 PyObject_CallObject((PyObject *)&listdir_stat_type, |
|
246 ctor_args); |
|
247 |
|
248 if (!st) |
|
249 goto bail; |
242 goto bail; |
|
243 } |
|
244 |
|
245 st = (struct listdir_stat *) |
|
246 PyObject_CallObject((PyObject *)&listdir_stat_type, |
|
247 ctor_args); |
|
248 |
|
249 if (!st) |
|
250 goto bail; |
250 #ifdef AT_SYMLINK_NOFOLLOW |
251 #ifdef AT_SYMLINK_NOFOLLOW |
251 ret = fstatat(dfd, name, &st->st, AT_SYMLINK_NOFOLLOW); |
252 ret = fstatat(dfd, name, &st->st, AT_SYMLINK_NOFOLLOW); |
252 #else |
253 #else |
253 ret = lstat(full_path, &st->st); |
254 ret = lstat(full_path, &st->st); |
254 #endif |
255 #endif |
255 if (ret == -1) { |
256 if (ret == -1) { |
256 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, |
257 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, |
257 full_path); |
258 full_path); |
258 goto bail; |
259 goto bail; |
259 } |
260 } |
260 if (kind == -1) |
261 if (kind == -1) |
261 kind = mode_to_kind(st->st.st_mode); |
262 kind = mode_to_kind(st->st.st_mode); |
262 py_st = (PyObject *)st; |
263 py_st = (PyObject *)st; |
263 } else { |
264 } else { |
264 struct stat buf; |
265 struct stat buf; |
265 #ifdef AT_SYMLINK_NOFOLLOW |
266 #ifdef AT_SYMLINK_NOFOLLOW |
266 ret = fstatat(dfd, ent->d_name, &buf, AT_SYMLINK_NOFOLLOW); |
267 ret = fstatat(dfd, ent->d_name, &buf, AT_SYMLINK_NOFOLLOW); |
267 #else |
268 #else |
268 ret = lstat(full_path, &buf); |
269 ret = lstat(full_path, &buf); |
269 #endif |
270 #endif |
270 if (ret == -1) { |
271 if (ret == -1) { |
271 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, |
272 list = PyErr_SetFromErrnoWithFilename(PyExc_OSError, |
272 full_path); |
273 full_path); |
273 goto bail; |
274 goto bail; |
274 } |
|
275 if (kind == -1) |
|
276 kind = mode_to_kind(buf.st_mode); |
|
277 } |
275 } |
278 |
276 if (kind == -1) |
279 if (py_kind == Py_None && kind != -1) { |
277 kind = mode_to_kind(buf.st_mode); |
280 py_kind = PyInt_FromLong(kind); |
278 } |
281 if (!py_kind) |
279 |
282 goto bail; |
280 if (py_kind == Py_None && kind != -1) { |
283 Py_XDECREF(Py_None); |
281 py_kind = PyInt_FromLong(kind); |
284 PyTuple_SET_ITEM(elt, 1, py_kind); |
282 if (!py_kind) |
|
283 goto bail; |
|
284 Py_XDECREF(Py_None); |
|
285 PyTuple_SET_ITEM(elt, 1, py_kind); |
|
286 } |
|
287 |
|
288 if (do_stat) { |
|
289 if (!py_st) { |
|
290 py_st = Py_None; |
|
291 Py_INCREF(Py_None); |
285 } |
292 } |
286 |
293 PyTuple_SET_ITEM(elt, 2, py_st); |
287 if (do_stat) { |
|
288 if (!py_st) { |
|
289 py_st = Py_None; |
|
290 Py_INCREF(Py_None); |
|
291 } |
|
292 PyTuple_SET_ITEM(elt, 2, py_st); |
|
293 } |
|
294 } |
294 } |
295 } |
295 } |
296 |
296 |
297 goto done; |
297 goto done; |
298 |
298 |
299 bail: |
299 bail: |
300 Py_XDECREF(list); |
300 Py_XDECREF(list); |
301 |
301 |
302 done: |
302 done: |
303 Py_XDECREF(ctor_args); |
303 Py_XDECREF(ctor_args); |
304 if (dir) |
304 if (dir) |
305 closedir(dir); |
305 closedir(dir); |
306 return list; |
306 return list; |
307 } |
307 } |
308 |
308 |
309 |
309 |
310 static char osutil_doc[] = "Native operating system services."; |
310 static char osutil_doc[] = "Native operating system services."; |