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 |