mercurial/osutil.c
changeset 5457 7372b6bbc5e6
parent 5432 0d154bce2341
child 5463 3b204881f959
equal deleted inserted replaced
5456:a58d415b272e 5457:7372b6bbc5e6
     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
       
    11 #include <Python.h>
    10 #include <Python.h>
    12 #include <alloca.h>
       
    13 #include <dirent.h>
    11 #include <dirent.h>
    14 #include <fcntl.h>
    12 #include <fcntl.h>
    15 #include <string.h>
    13 #include <string.h>
    16 #include <sys/stat.h>
    14 #include <sys/stat.h>
    17 #include <sys/types.h>
    15 #include <sys/types.h>
    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();