osutil: use fdopendir instead of dirfd
authorBryan O'Sullivan <bos@serpentine.com>
Mon, 15 Oct 2007 12:57:01 -0700
changeset 5463 3b204881f959
parent 5462 91a522a69c13
child 5464 7dafd9ab3979
osutil: use fdopendir instead of dirfd
mercurial/osutil.c
--- a/mercurial/osutil.c	Sat Oct 13 15:25:11 2007 +0400
+++ b/mercurial/osutil.c	Mon Oct 15 12:57:01 2007 -0700
@@ -7,6 +7,7 @@
  the GNU General Public License, incorporated herein by reference.
 */
 
+#define _ATFILE_SOURCE
 #include <Python.h>
 #include <dirent.h>
 #include <fcntl.h>
@@ -15,10 +16,6 @@
 #include <sys/types.h>
 #include <unistd.h>
 
-#if defined(__sun)
-#define dirfd(dir) ((dir)->dd_fd)
-#endif
-
 struct listdir_stat {
 	PyObject_HEAD
 	struct stat st;
@@ -165,7 +162,7 @@
 }
 
 static PyObject *statfiles(PyObject *list, PyObject *ctor_args, int keep,
-			   char *path, int len, DIR *dir)
+			   char *path, int len, int dfd)
 {
 	struct stat buf;
 	struct stat *stp = &buf;
@@ -196,7 +193,11 @@
 			PyTuple_SET_ITEM(elt, 2, py_st);
 		}
 
+#ifdef AT_SYMLINK_NOFOLLOW
+		ret = fstatat(dfd, name, stp, AT_SYMLINK_NOFOLLOW);
+#else
 		ret = lstat(path, stp);
+#endif
 		if (ret == -1)
 			return PyErr_SetFromErrnoWithFilename(PyExc_OSError,
 							      path);
@@ -244,6 +245,7 @@
 	char full_path[PATH_MAX + 10];
 	int path_len;
 	int need_stat, keep_stat;
+	int dfd;
 
 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist,
 					 &path, &path_len, &statobj))
@@ -251,7 +253,13 @@
 
 	keep_stat = statobj && PyObject_IsTrue(statobj);
 
+#ifdef AT_SYMLINK_NOFOLLOW
+	dfd = open(path, O_RDONLY);
+	dir = fdopendir(dfd);
+#else
 	dir = opendir(path);
+	dfd = -1;
+#endif
 	if (!dir) {
 		err = PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
 		goto bail;
@@ -274,7 +282,7 @@
 	if (!keep_stat && !need_stat)
 		goto done;
 
-	err = statfiles(list, ctor_args, keep_stat, full_path, path_len, dir);
+	err = statfiles(list, ctor_args, keep_stat, full_path, path_len, dfd);
 	if (!err)
 		goto done;