99 0, /* tp_init */ |
97 0, /* tp_init */ |
100 0, /* tp_alloc */ |
98 0, /* tp_alloc */ |
101 listdir_stat_new, /* tp_new */ |
99 listdir_stat_new, /* tp_new */ |
102 }; |
100 }; |
103 |
101 |
104 static inline int mode_to_kind(int mode) |
|
105 { |
|
106 if (S_ISREG(mode)) return S_IFREG; |
|
107 if (S_ISDIR(mode)) return S_IFDIR; |
|
108 if (S_ISLNK(mode)) return S_IFLNK; |
|
109 if (S_ISBLK(mode)) return S_IFBLK; |
|
110 if (S_ISCHR(mode)) return S_IFCHR; |
|
111 if (S_ISFIFO(mode)) return S_IFIFO; |
|
112 if (S_ISSOCK(mode)) return S_IFSOCK; |
|
113 return mode; |
|
114 } |
|
115 |
|
116 static PyObject *listfiles(PyObject *list, DIR *dir, |
102 static PyObject *listfiles(PyObject *list, DIR *dir, |
117 int keep_stat, int *need_stat) |
103 int keep_stat, int *need_stat) |
118 { |
104 { |
119 struct dirent *ent; |
105 struct dirent *ent; |
120 PyObject *name, *py_kind, *val; |
106 PyObject *name, *py_kind, *val; |
185 struct stat *stp = &buf; |
171 struct stat *stp = &buf; |
186 int kind; |
172 int kind; |
187 int ret; |
173 int ret; |
188 ssize_t i; |
174 ssize_t i; |
189 ssize_t size = PyList_Size(list); |
175 ssize_t size = PyList_Size(list); |
190 #ifdef AT_SYMLINK_NOFOLLOW |
|
191 int dfd = dirfd(dir); |
|
192 #endif |
|
193 |
176 |
194 for (i = 0; i < size; i++) { |
177 for (i = 0; i < size; i++) { |
195 PyObject *elt = PyList_GetItem(list, i); |
178 PyObject *elt = PyList_GetItem(list, i); |
196 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); |
179 char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0)); |
197 PyObject *py_st = NULL; |
180 PyObject *py_st = NULL; |
211 return PyErr_NoMemory(); |
194 return PyErr_NoMemory(); |
212 stp = &((struct listdir_stat *)py_st)->st; |
195 stp = &((struct listdir_stat *)py_st)->st; |
213 PyTuple_SET_ITEM(elt, 2, py_st); |
196 PyTuple_SET_ITEM(elt, 2, py_st); |
214 } |
197 } |
215 |
198 |
216 #ifdef AT_SYMLINK_NOFOLLOW |
|
217 ret = fstatat(dfd, name, stp, AT_SYMLINK_NOFOLLOW); |
|
218 #else |
|
219 ret = lstat(path, stp); |
199 ret = lstat(path, stp); |
220 #endif |
|
221 if (ret == -1) |
200 if (ret == -1) |
222 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, |
201 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, |
223 path); |
202 path); |
224 |
203 |
225 if (kind == -1) |
204 if (kind == -1) { |
226 kind = mode_to_kind(stp->st_mode); |
205 if (S_ISREG(stp->st_mode)) |
|
206 kind = S_IFREG; |
|
207 else if (S_ISDIR(stp->st_mode)) |
|
208 kind = S_IFDIR; |
|
209 else if (S_ISLNK(stp->st_mode)) |
|
210 kind = S_IFLNK; |
|
211 else if (S_ISBLK(stp->st_mode)) |
|
212 kind = S_IFBLK; |
|
213 else if (S_ISCHR(stp->st_mode)) |
|
214 kind = S_IFCHR; |
|
215 else if (S_ISFIFO(stp->st_mode)) |
|
216 kind = S_IFIFO; |
|
217 else if (S_ISSOCK(stp->st_mode)) |
|
218 kind = S_IFSOCK; |
|
219 else |
|
220 kind = stp->st_mode; |
|
221 } |
227 |
222 |
228 if (py_kind == Py_None && kind != -1) { |
223 if (py_kind == Py_None && kind != -1) { |
229 py_kind = PyInt_FromLong(kind); |
224 py_kind = PyInt_FromLong(kind); |
230 if (!py_kind) |
225 if (!py_kind) |
231 return PyErr_NoMemory(); |
226 return PyErr_NoMemory(); |