280
288
cdef int stat_result
281
289
cdef _Stat statvalue
285
cwd = getcwd(NULL, 0)
286
if -1 == chdir(path):
287
raise OSError(errno, strerror(errno))
288
the_dir = opendir(".")
290
raise OSError(errno, strerror(errno))
293
# Avoid chdir('') because it causes problems on Sun OS, and avoid this if
295
if path != "" and path != '.':
296
# we change into the requested directory before reading, and back at the
297
# end, because that turns out to make the stat calls measurably faster than
298
# passing full paths every time.
299
orig_dir_fd = open(".", O_RDONLY, 0)
300
if orig_dir_fd == -1:
301
raise OSError(errno, strerror(errno))
302
if -1 == chdir(path):
303
raise OSError(errno, strerror(errno))
295
# Unlike most libc functions, readdir needs errno set to 0
296
# beforehand so that eof can be distinguished from errors. See
297
# <https://bugs.launchpad.net/bzr/+bug/279381>
300
entry = readdir(the_dir)
301
if entry == NULL and (errno == EAGAIN or errno == EINTR):
307
if errno == ENOTDIR or errno == 0:
308
# We see ENOTDIR at the end of a normal directory.
309
# As ENOTDIR for read_dir(file) is triggered on opendir,
310
# we consider ENOTDIR to be 'no error'.
313
raise OSError(errno, strerror(errno))
315
if not (name[0] == c"." and (
317
(name[1] == c"." and name[2] == 0))
320
stat_result = lstat(entry.d_name, &statvalue._st)
308
the_dir = opendir(".")
310
raise OSError(errno, strerror(errno))
315
# Unlike most libc functions, readdir needs errno set to 0
316
# beforehand so that eof can be distinguished from errors. See
317
# <https://bugs.launchpad.net/bzr/+bug/279381>
320
entry = readdir(the_dir)
321
if entry == NULL and (errno == EAGAIN or errno == EINTR):
327
if errno == ENOTDIR or errno == 0:
328
# We see ENOTDIR at the end of a normal directory.
329
# As ENOTDIR for read_dir(file) is triggered on opendir,
330
# we consider ENOTDIR to be 'no error'.
323
333
raise OSError(errno, strerror(errno))
327
# We append a 5-tuple that can be modified in-place by the C
329
# inode to sort on (to replace with top_path)
331
# kind (None, to set)
332
# statvalue (to keep)
333
# abspath (None, to set)
334
PyList_Append(result, (entry.d_ino, entry.d_name, None,
335
if not (name[0] == c"." and (
337
(name[1] == c"." and name[2] == 0))
340
stat_result = lstat(entry.d_name, &statvalue._st)
343
raise OSError(errno, strerror(errno))
347
# We append a 5-tuple that can be modified in-place by the C
349
# inode to sort on (to replace with top_path)
351
# kind (None, to set)
352
# statvalue (to keep)
353
# abspath (None, to set)
354
PyList_Append(result, (entry.d_ino, entry.d_name, None,
357
if -1 == closedir(the_dir):
358
raise OSError(errno, strerror(errno))
339
raise OSError(errno, strerror(errno))
341
if -1 == closedir(the_dir):
342
raise OSError(errno, strerror(errno))
360
if -1 != orig_dir_fd:
362
if -1 == fchdir(orig_dir_fd):
363
# try to close the original directory anyhow
365
if -1 == close(orig_dir_fd) or failed:
366
raise OSError(errno, strerror(errno))