merge with crew
authorBenoit Boissinot <benoit.boissinot@ens-lyon.org>
Wed, 15 Oct 2008 16:27:36 +0200
changeset 7100 baf12d52add4
parent 7099 6f750e76fb46 (diff)
parent 7097 d4218edd55bd (current diff)
child 7101 e786192d995d
child 7102 14f3ea2ea54f
merge with crew
--- a/mercurial/dirstate.py	Mon Oct 13 17:31:03 2008 +0100
+++ b/mercurial/dirstate.py	Wed Oct 15 16:27:36 2008 +0200
@@ -492,11 +492,18 @@
             nd = work.pop()
             if hasattr(match, 'dir'):
                 match.dir(nd)
+            skip = None
             if nd == '.':
                 nd = ''
-                entries = listdir(join(nd), stat=True)
             else:
-                entries = listdir(join(nd), stat=True, skip ='.hg')
+                skip = '.hg'
+            try:
+                entries = listdir(join(nd), stat=True, skip=skip)
+            except OSError, inst:
+                if inst.errno == errno.EACCES:
+                    fwarn(nd, inst.strerror)
+                    continue
+                raise
             for f, kind, st in entries:
                 nf = normalize(nd and (nd + "/" + f) or f, True)
                 if nf not in results:
--- a/mercurial/osutil.c	Mon Oct 13 17:31:03 2008 +0100
+++ b/mercurial/osutil.c	Wed Oct 15 16:27:36 2008 +0200
@@ -172,29 +172,19 @@
 		kind, py_st);
 }
 
-static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
+static PyObject *_listdir(char *path, int plen, int wantstat, char *skip)
 {
 	PyObject *rval = NULL; /* initialize - return value */
-	PyObject *statobj = NULL; /* initialize - optional arg */
 	PyObject *list;
 	HANDLE fh;
 	WIN32_FIND_DATAA fd;
-	char *path, *pattern, *skip = NULL;
-	int plen, wantstat;
-
-	static char *kwlist[] = {"path", "stat", "skip", NULL};
-
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|Os:listdir",
-			kwlist, &path, &plen, &statobj, &skip))
-		goto error_parse;
-
-	wantstat = statobj && PyObject_IsTrue(statobj);
+	char *pattern;
 
 	/* build the path + \* pattern string */
 	pattern = malloc(plen+3); /* path + \* + \0 */
 	if (!pattern) {
 		PyErr_NoMemory();
-		goto error_parse;
+		goto error_nomem;
 	}
 	strcpy(pattern, path);
 
@@ -254,7 +244,7 @@
 	FindClose(fh);
 error_file:
 	free(pattern);
-error_parse:
+error_nomem:
 	return rval;
 }
 
@@ -276,33 +266,27 @@
 	return -1;
 }
 
-static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
+static PyObject *_listdir(char *path, int pathlen, int keepstat, char *skip)
 {
-	static char *kwlist[] = { "path", "stat", "skip", NULL };
-	PyObject *statflag = NULL, *list, *elem, *stat, *ret = NULL;
-	char fullpath[PATH_MAX + 10], *path, *skip = NULL;
-	int pathlen, keepstat, kind, dfd = -1, err;
+	PyObject *list, *elem, *stat, *ret = NULL;
+	char fullpath[PATH_MAX + 10];
+	int kind, dfd = -1, err;
 	struct stat st;
 	struct dirent *ent;
 	DIR *dir;
 
-	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|Os:listdir", kwlist,
-					 &path, &pathlen, &statflag, &skip))
-		goto error_parse;
-
 	if (pathlen >= PATH_MAX) {
 		PyErr_SetString(PyExc_ValueError, "path too long");
-		goto error_parse;
+		goto error_value;
 	}
 	strncpy(fullpath, path, PATH_MAX);
 	fullpath[pathlen] = '/';
-	keepstat = statflag && PyObject_IsTrue(statflag);
 
 #ifdef AT_SYMLINK_NOFOLLOW
 	dfd = open(path, O_RDONLY);
 	if (dfd == -1) {
 		PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
-		goto error_parse;
+		goto error_value;
 	}
 	dir = fdopendir(dfd);
 #else
@@ -375,12 +359,36 @@
 #ifdef AT_SYMLINK_NOFOLLOW
 	close(dfd);
 #endif
-error_parse:
+error_value:
 	return ret;
 }
 
 #endif /* ndef _WIN32 */
 
+static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+	PyObject *statobj = NULL; /* initialize - optional arg */
+	PyObject *skipobj = NULL; /* initialize - optional arg */
+	char *path, *skip = NULL;
+	int wantstat, plen;
+
+	static char *kwlist[] = {"path", "stat", "skip", NULL};
+
+	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|OO:listdir",
+			kwlist, &path, &plen, &statobj, &skipobj))
+		return NULL;
+
+	wantstat = statobj && PyObject_IsTrue(statobj);
+
+	if (skipobj && skipobj != Py_None) {
+		skip = PyString_AsString(skipobj);
+		if (!skip)
+			return NULL;
+	}
+
+	return _listdir(path, plen, wantstat, skip);
+}
+
 static char osutil_doc[] = "Native operating system services.";
 
 static PyMethodDef methods[] = {
--- a/tests/test-permissions	Mon Oct 13 17:31:03 2008 +0100
+++ b/tests/test-permissions	Wed Oct 15 16:27:36 2008 +0200
@@ -16,3 +16,10 @@
 chmod -w .
 hg diff --nodates
 chmod +w .
+
+chmod +w .hg/store/data/a.i
+mkdir dir
+touch dir/a
+hg status
+chmod -rx dir
+hg status
--- a/tests/test-permissions.out	Mon Oct 13 17:31:03 2008 +0100
+++ b/tests/test-permissions.out	Wed Oct 15 16:27:36 2008 +0200
@@ -20,3 +20,7 @@
 @@ -1,1 +1,1 @@
 -foo
 +barber
+M a
+? dir/a
+dir: Permission denied
+M a