mercurial/osutil.c
changeset 5425 830f6e280c90
parent 5424 005638db9d0c
child 5426 e760cb72c02e
equal deleted inserted replaced
5424:005638db9d0c 5425:830f6e280c90
   107 	if (S_ISFIFO(mode)) return S_IFIFO;
   107 	if (S_ISFIFO(mode)) return S_IFIFO;
   108 	if (S_ISSOCK(mode)) return S_IFSOCK;
   108 	if (S_ISSOCK(mode)) return S_IFSOCK;
   109 	return mode;
   109 	return mode;
   110 }
   110 }
   111 
   111 
       
   112 static PyObject *statfiles(PyObject *list, PyObject *ctor_args, int keep,
       
   113 			   char *path, int len, DIR *dir)
       
   114 {
       
   115 	struct stat buf;
       
   116 	struct stat *stp = &buf;
       
   117 	int kind;
       
   118 	int ret;
       
   119 	ssize_t i;
       
   120 	ssize_t size = PyList_Size(list);
       
   121 #ifdef AT_SYMLINK_NOFOLLOW
       
   122 	int dfd = dirfd(dir);
       
   123 #endif
       
   124 
       
   125 	for (i = 0; i < size; i++) {
       
   126 		PyObject *elt = PyList_GetItem(list, i);
       
   127 		char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0));
       
   128 		PyObject *py_st = NULL;
       
   129 		PyObject *py_kind = PyTuple_GET_ITEM(elt, 1);
       
   130 
       
   131 		kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind);
       
   132 		if (kind != -1 && !keep)
       
   133 			continue;
       
   134 
       
   135 		strncat(path + len + 1, name, PATH_MAX - len);
       
   136 		path[PATH_MAX] = 0;
       
   137 
       
   138 		if (keep) {
       
   139 			py_st = PyObject_CallObject(
       
   140 				(PyObject *)&listdir_stat_type, ctor_args);
       
   141 			if (!py_st)
       
   142 				return PyErr_NoMemory();
       
   143 			stp = &((struct listdir_stat *)py_st)->st;
       
   144 			PyTuple_SET_ITEM(elt, 2, py_st);
       
   145 		}
       
   146 
       
   147 #ifdef AT_SYMLINK_NOFOLLOW
       
   148 		ret = fstatat(dfd, name, stp, AT_SYMLINK_NOFOLLOW);
       
   149 #else
       
   150 		ret = lstat(path, stp);
       
   151 #endif
       
   152 		if (ret == -1)
       
   153 			return PyErr_SetFromErrnoWithFilename(PyExc_OSError,
       
   154 							      path);
       
   155 
       
   156 		if (kind == -1)
       
   157 			kind = mode_to_kind(stp->st_mode);
       
   158 
       
   159 		if (py_kind == Py_None && kind != -1) {
       
   160 			py_kind = PyInt_FromLong(kind);
       
   161 			if (!py_kind)
       
   162 				return PyErr_NoMemory();
       
   163 			Py_XDECREF(Py_None);
       
   164 			PyTuple_SET_ITEM(elt, 1, py_kind);
       
   165 		}
       
   166 	}
       
   167 
       
   168 	return 0;
       
   169 }
       
   170 
   112 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
   171 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
   113 {
   172 {
   114 	static char *kwlist[] = { "path", "stat", NULL };
   173 	static char *kwlist[] = { "path", "stat", NULL };
   115 	PyObject *statobj = NULL;
   174 	PyObject *statobj = NULL;
   116 	DIR *dir = NULL;
   175 	DIR *dir = NULL;
   117 	struct dirent *ent;
   176 	struct dirent *ent;
   118 	PyObject *list = NULL;
   177 	PyObject *list = NULL;
       
   178 	PyObject *err = NULL;
   119 	PyObject *ctor_args = NULL;
   179 	PyObject *ctor_args = NULL;
   120 	int all_kinds = 1;
   180 	int all_kinds = 1;
   121 	char full_path[PATH_MAX + 10];
   181 	char full_path[PATH_MAX + 10];
   122 	int path_len;
   182 	int path_len;
   123 	int do_stat;
   183 	int do_stat;
   124 	char *path;
   184 	char *path;
   125 	int ret;
       
   126 	ssize_t size;
       
   127 	ssize_t i;
       
   128 	int dfd;
       
   129 
   185 
   130 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist,
   186 	if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|O:listdir", kwlist,
   131 					 &path, &path_len, &statobj))
   187 					 &path, &path_len, &statobj))
   132 		goto bail;
   188 		goto bail;
   133 
   189 
   208 		PyList_Append(list, val);
   264 		PyList_Append(list, val);
   209 		Py_DECREF(val);
   265 		Py_DECREF(val);
   210 	}
   266 	}
   211 
   267 
   212 	PyList_Sort(list);
   268 	PyList_Sort(list);
   213 	size = PyList_Size(list);
   269 
   214 #ifdef AT_SYMLINK_NOFOLLOW
   270 	if (do_stat) {
   215 	dfd = dirfd(dir);
   271 		ctor_args = PyTuple_New(0);
   216 #endif
   272 		if (!ctor_args)
   217 
       
   218 	if (!(do_stat || !all_kinds))
       
   219 		goto done;
       
   220 
       
   221 	for (i = 0; i < size; i++) {
       
   222 		PyObject *elt = PyList_GetItem(list, i);
       
   223 		char *name = PyString_AsString(PyTuple_GET_ITEM(elt, 0));
       
   224 		PyObject *py_st = NULL;
       
   225 		PyObject *py_kind = PyTuple_GET_ITEM(elt, 1);
       
   226 		struct listdir_stat *st;
       
   227 		struct stat buf;
       
   228 		struct stat *stp = &buf;
       
   229 		int kind;
       
   230 
       
   231 		kind = py_kind == Py_None ? -1 : PyInt_AsLong(py_kind);
       
   232 
       
   233 		if (kind != -1 && !do_stat)
       
   234 			continue;
       
   235 
       
   236 		strncat(full_path + path_len + 1, name, PATH_MAX - path_len);
       
   237 		full_path[PATH_MAX] = 0;
       
   238 
       
   239 		if (do_stat) {
       
   240 			if (!ctor_args) {
       
   241 				ctor_args = PyTuple_New(0);
       
   242 				if (!ctor_args)
       
   243 					goto bail;
       
   244 			}
       
   245 
       
   246 			py_st = PyObject_CallObject((PyObject *)&listdir_stat_type,
       
   247 						    ctor_args);
       
   248 			st = (struct listdir_stat *)py_st;
       
   249 			if (!st)
       
   250 				goto bail;
       
   251 			stp = &st->st;
       
   252 			PyTuple_SET_ITEM(elt, 2, py_st);
       
   253 		}
       
   254 
       
   255 #ifdef AT_SYMLINK_NOFOLLOW
       
   256 		ret = fstatat(dfd, name, stp, AT_SYMLINK_NOFOLLOW);
       
   257 #else
       
   258 		ret = lstat(full_path, stp);
       
   259 #endif
       
   260 		if (ret == -1) {
       
   261 			list = PyErr_SetFromErrnoWithFilename(PyExc_OSError,
       
   262 							      full_path);
       
   263 			goto bail;
   273 			goto bail;
   264 		}
       
   265 		if (kind == -1)
       
   266 			kind = mode_to_kind(stp->st_mode);
       
   267 
       
   268 		if (py_kind == Py_None && kind != -1) {
       
   269 			py_kind = PyInt_FromLong(kind);
       
   270 			if (!py_kind)
       
   271 				goto bail;
       
   272 			Py_XDECREF(Py_None);
       
   273 			PyTuple_SET_ITEM(elt, 1, py_kind);
       
   274 		}
       
   275 	}
   274 	}
   276 
   275 
       
   276 	if (do_stat || !all_kinds)
       
   277 		if (statfiles(list, ctor_args, do_stat, full_path, path_len,
       
   278 			      dir))
       
   279 			goto bail;
   277 	goto done;
   280 	goto done;
   278 
   281 
   279  bail:
   282  bail:
   280 	Py_XDECREF(list);
   283 	Py_XDECREF(list);
   281 
   284 
   282  done:
   285  done:
   283 	Py_XDECREF(ctor_args);
   286 	Py_XDECREF(ctor_args);
   284 	if (dir)
   287 	if (dir)
   285 		closedir(dir);
   288 		closedir(dir);
   286 	return list;
   289 	return err ? err : list;
   287 }
   290 }
   288 
   291 
   289 
   292 
   290 static char osutil_doc[] = "Native operating system services.";
   293 static char osutil_doc[] = "Native operating system services.";
   291 
   294