mercurial/osutil.c
changeset 5463 3b204881f959
parent 5457 7372b6bbc5e6
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);