comparison mercurial/osutil.c @ 5457:7372b6bbc5e6

osutil: improve portability - manually inline mode_to_kind - remove unused alloca include - remove fstatat and associated bits It's not obvious that there's an advantage to using fstatat in terms of performance. The race-avoidance properties of fstatat aren't terribly useful to us either. So best to avoid it until we figure out how to use it portably.
author Matt Mackall <mpm@selenic.com>
date Thu, 11 Oct 2007 17:46:06 -0500
parents 0d154bce2341
children 3b204881f959
comparison
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();