comparison mercurial/osutil.c @ 5463:3b204881f959

osutil: use fdopendir instead of dirfd
author Bryan O'Sullivan <bos@serpentine.com>
date Mon, 15 Oct 2007 12:57:01 -0700
parents 7372b6bbc5e6
children
comparison
equal deleted inserted replaced
5462:91a522a69c13 5463:3b204881f959
5 5
6 This software may be used and distributed according to the terms of 6 This software may be used and distributed according to the terms of
7 the GNU General Public License, incorporated herein by reference. 7 the GNU General Public License, incorporated herein by reference.
8 */ 8 */
9 9
10 #define _ATFILE_SOURCE
10 #include <Python.h> 11 #include <Python.h>
11 #include <dirent.h> 12 #include <dirent.h>
12 #include <fcntl.h> 13 #include <fcntl.h>
13 #include <string.h> 14 #include <string.h>
14 #include <sys/stat.h> 15 #include <sys/stat.h>
15 #include <sys/types.h> 16 #include <sys/types.h>
16 #include <unistd.h> 17 #include <unistd.h>
17
18 #if defined(__sun)
19 #define dirfd(dir) ((dir)->dd_fd)
20 #endif
21 18
22 struct listdir_stat { 19 struct listdir_stat {
23 PyObject_HEAD 20 PyObject_HEAD
24 struct stat st; 21 struct stat st;
25 }; 22 };
163 160
164 return 0; 161 return 0;
165 } 162 }
166 163
167 static PyObject *statfiles(PyObject *list, PyObject *ctor_args, int keep, 164 static PyObject *statfiles(PyObject *list, PyObject *ctor_args, int keep,
168 char *path, int len, DIR *dir) 165 char *path, int len, int dfd)
169 { 166 {
170 struct stat buf; 167 struct stat buf;
171 struct stat *stp = &buf; 168 struct stat *stp = &buf;
172 int kind; 169 int kind;
173 int ret; 170 int ret;
194 return PyErr_NoMemory(); 191 return PyErr_NoMemory();
195 stp = &((struct listdir_stat *)py_st)->st; 192 stp = &((struct listdir_stat *)py_st)->st;
196 PyTuple_SET_ITEM(elt, 2, py_st); 193 PyTuple_SET_ITEM(elt, 2, py_st);
197 } 194 }
198 195
196 #ifdef AT_SYMLINK_NOFOLLOW
197 ret = fstatat(dfd, name, stp, AT_SYMLINK_NOFOLLOW);
198 #else
199 ret = lstat(path, stp); 199 ret = lstat(path, stp);
200 #endif
200 if (ret == -1) 201 if (ret == -1)
201 return PyErr_SetFromErrnoWithFilename(PyExc_OSError, 202 return PyErr_SetFromErrnoWithFilename(PyExc_OSError,
202 path); 203 path);
203 204
204 if (kind == -1) { 205 if (kind == -1) {
242 PyObject *ctor_args = NULL; 243 PyObject *ctor_args = NULL;
243 char *path; 244 char *path;
244 char full_path[PATH_MAX + 10]; 245 char full_path[PATH_MAX + 10];
245 int path_len; 246 int path_len;
246 int need_stat, keep_stat; 247 int need_stat, keep_stat;
248 int dfd;
247 249
248 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist, 250 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist,
249 &path, &path_len, &statobj)) 251 &path, &path_len, &statobj))
250 goto bail; 252 goto bail;
251 253
252 keep_stat = statobj && PyObject_IsTrue(statobj); 254 keep_stat = statobj && PyObject_IsTrue(statobj);
253 255
256 #ifdef AT_SYMLINK_NOFOLLOW
257 dfd = open(path, O_RDONLY);
258 dir = fdopendir(dfd);
259 #else
254 dir = opendir(path); 260 dir = opendir(path);
261 dfd = -1;
262 #endif
255 if (!dir) { 263 if (!dir) {
256 err = PyErr_SetFromErrnoWithFilename(PyExc_OSError, path); 264 err = PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
257 goto bail; 265 goto bail;
258 } 266 }
259 267
272 PyList_Sort(list); 280 PyList_Sort(list);
273 281
274 if (!keep_stat && !need_stat) 282 if (!keep_stat && !need_stat)
275 goto done; 283 goto done;
276 284
277 err = statfiles(list, ctor_args, keep_stat, full_path, path_len, dir); 285 err = statfiles(list, ctor_args, keep_stat, full_path, path_len, dfd);
278 if (!err) 286 if (!err)
279 goto done; 287 goto done;
280 288
281 bail: 289 bail:
282 Py_XDECREF(list); 290 Py_XDECREF(list);