annotate mercurial/osutil.c @ 8564:6b9ec23b09fc

named branches: improve pre-push logic (issue736) Each named branch is considered separately, and the push is allowed if no new branch heads are created for any named branch to be pushed. Due to some tests's use of --debug, their output will change after this addition. This has been fixed as well. Co-contributor: Henrik Stuart <henrik.stuart@edlund.dk>
author Sune Foldager <cryo@cyanite.org>
date Sat, 23 May 2009 17:04:31 +0200
parents 7de68012f86e
children dc1b9e22f288
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
1 /*
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
2 osutil.c - native operating system services
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
3
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
4 Copyright 2007 Matt Mackall and others
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
5
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
6 This software may be used and distributed according to the terms of
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
7 the GNU General Public License, incorporated herein by reference.
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
8 */
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
9
5463
3b204881f959 osutil: use fdopendir instead of dirfd
Bryan O'Sullivan <bos@serpentine.com>
parents: 5457
diff changeset
10 #define _ATFILE_SOURCE
5397
11caa374f497 osutil.c: include Python.h before the other headers
Alexis S. L. Carvalho <alexis@cecm.usp.br>
parents: 5396
diff changeset
11 #include <Python.h>
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
12 #include <fcntl.h>
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
13 #include <stdio.h>
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
14 #include <string.h>
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
15
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
16 #ifdef _WIN32
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
17 # include <windows.h>
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
18 # include <io.h>
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
19 #else
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
20 # include <dirent.h>
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
21 # include <sys/stat.h>
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
22 # include <sys/types.h>
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
23 # include <unistd.h>
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
24 #endif
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
25
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
26 #ifdef _WIN32
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
27 /*
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
28 stat struct compatible with hg expectations
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
29 Mercurial only uses st_mode, st_size and st_mtime
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
30 the rest is kept to minimize changes between implementations
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
31 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
32 struct hg_stat {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
33 int st_dev;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
34 int st_mode;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
35 int st_nlink;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
36 __int64 st_size;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
37 int st_mtime;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
38 int st_ctime;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
39 };
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
40 struct listdir_stat {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
41 PyObject_HEAD
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
42 struct hg_stat st;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
43 };
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
44 #else
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
45 struct listdir_stat {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
46 PyObject_HEAD
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
47 struct stat st;
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
48 };
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
49 #endif
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
50
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
51 #define listdir_slot(name) \
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7136
diff changeset
52 static PyObject *listdir_stat_##name(PyObject *self, void *x) \
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7136
diff changeset
53 { \
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7136
diff changeset
54 return PyInt_FromLong(((struct listdir_stat *)self)->st.name); \
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7136
diff changeset
55 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
56
5431
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
57 listdir_slot(st_dev)
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
58 listdir_slot(st_mode)
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
59 listdir_slot(st_nlink)
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
60 #ifdef _WIN32
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
61 static PyObject *listdir_stat_st_size(PyObject *self, void *x)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
62 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
63 return PyLong_FromLongLong(
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
64 (PY_LONG_LONG)((struct listdir_stat *)self)->st.st_size);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
65 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
66 #else
5431
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
67 listdir_slot(st_size)
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
68 #endif
5431
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
69 listdir_slot(st_mtime)
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
70 listdir_slot(st_ctime)
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
71
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
72 static struct PyGetSetDef listdir_stat_getsets[] = {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
73 {"st_dev", listdir_stat_st_dev, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
74 {"st_mode", listdir_stat_st_mode, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
75 {"st_nlink", listdir_stat_st_nlink, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
76 {"st_size", listdir_stat_st_size, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
77 {"st_mtime", listdir_stat_st_mtime, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
78 {"st_ctime", listdir_stat_st_ctime, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
79 {0, 0, 0, 0, 0}
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
80 };
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
81
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
82 static PyObject *listdir_stat_new(PyTypeObject *t, PyObject *a, PyObject *k)
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
83 {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
84 return t->tp_alloc(t, 0);
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
85 }
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
86
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87 static void listdir_stat_dealloc(PyObject *o)
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88 {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
89 o->ob_type->tp_free(o);
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
90 }
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
91
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
92 static PyTypeObject listdir_stat_type = {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
93 PyObject_HEAD_INIT(NULL)
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
94 0, /*ob_size*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
95 "osutil.stat", /*tp_name*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
96 sizeof(struct listdir_stat), /*tp_basicsize*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
97 0, /*tp_itemsize*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
98 (destructor)listdir_stat_dealloc, /*tp_dealloc*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
99 0, /*tp_print*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
100 0, /*tp_getattr*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
101 0, /*tp_setattr*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
102 0, /*tp_compare*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
103 0, /*tp_repr*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
104 0, /*tp_as_number*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
105 0, /*tp_as_sequence*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
106 0, /*tp_as_mapping*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
107 0, /*tp_hash */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
108 0, /*tp_call*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
109 0, /*tp_str*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
110 0, /*tp_getattro*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
111 0, /*tp_setattro*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
112 0, /*tp_as_buffer*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
113 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
114 "stat objects", /* tp_doc */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
115 0, /* tp_traverse */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
116 0, /* tp_clear */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
117 0, /* tp_richcompare */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
118 0, /* tp_weaklistoffset */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
119 0, /* tp_iter */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
120 0, /* tp_iternext */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
121 0, /* tp_methods */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
122 0, /* tp_members */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
123 listdir_stat_getsets, /* tp_getset */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
124 0, /* tp_base */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
125 0, /* tp_dict */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
126 0, /* tp_descr_get */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
127 0, /* tp_descr_set */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
128 0, /* tp_dictoffset */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
129 0, /* tp_init */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
130 0, /* tp_alloc */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
131 listdir_stat_new, /* tp_new */
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
132 };
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
133
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
134 #ifdef _WIN32
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
135
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
136 static int to_python_time(const FILETIME *tm)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
137 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
138 /* number of seconds between epoch and January 1 1601 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
139 const __int64 a0 = (__int64)134774L * (__int64)24L * (__int64)3600L;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
140 /* conversion factor from 100ns to 1s */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
141 const __int64 a1 = 10000000;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
142 /* explicit (int) cast to suspend compiler warnings */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
143 return (int)((((__int64)tm->dwHighDateTime << 32)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
144 + tm->dwLowDateTime) / a1 - a0);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
145 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
146
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
147 static PyObject *make_item(const WIN32_FIND_DATAA *fd, int wantstat)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
148 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
149 PyObject *py_st;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
150 struct hg_stat *stp;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
151
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
152 int kind = (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
153 ? _S_IFDIR : _S_IFREG;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
154
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
155 if (!wantstat)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
156 return Py_BuildValue("si", fd->cFileName, kind);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
157
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
158 py_st = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
159 if (!py_st)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
160 return NULL;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
161
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
162 stp = &((struct listdir_stat *)py_st)->st;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
163 /*
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
164 use kind as st_mode
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
165 rwx bits on Win32 are meaningless
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
166 and Hg does not use them anyway
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
167 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
168 stp->st_mode = kind;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
169 stp->st_mtime = to_python_time(&fd->ftLastWriteTime);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
170 stp->st_ctime = to_python_time(&fd->ftCreationTime);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
171 if (kind == _S_IFREG)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
172 stp->st_size = ((__int64)fd->nFileSizeHigh << 32)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
173 + fd->nFileSizeLow;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
174 return Py_BuildValue("siN", fd->cFileName,
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
175 kind, py_st);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
176 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
177
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
178 static PyObject *_listdir(char *path, int plen, int wantstat, char *skip)
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
179 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
180 PyObject *rval = NULL; /* initialize - return value */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
181 PyObject *list;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
182 HANDLE fh;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
183 WIN32_FIND_DATAA fd;
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
184 char *pattern;
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
185
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
186 /* build the path + \* pattern string */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
187 pattern = malloc(plen+3); /* path + \* + \0 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
188 if (!pattern) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
189 PyErr_NoMemory();
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
190 goto error_nomem;
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
191 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
192 strcpy(pattern, path);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
193
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
194 if (plen > 0) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
195 char c = path[plen-1];
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
196 if (c != ':' && c != '/' && c != '\\')
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
197 pattern[plen++] = '\\';
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
198 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
199 strcpy(pattern + plen, "*");
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
200
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
201 fh = FindFirstFileA(pattern, &fd);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
202 if (fh == INVALID_HANDLE_VALUE) {
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
203 PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
204 goto error_file;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
205 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
206
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
207 list = PyList_New(0);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
208 if (!list)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
209 goto error_list;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
210
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
211 do {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
212 PyObject *item;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
213
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
214 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
215 if (!strcmp(fd.cFileName, ".")
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
216 || !strcmp(fd.cFileName, ".."))
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
217 continue;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
218
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
219 if (skip && !strcmp(fd.cFileName, skip)) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
220 rval = PyList_New(0);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
221 goto error;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
222 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
223 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
224
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
225 item = make_item(&fd, wantstat);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
226 if (!item)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
227 goto error;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
228
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
229 if (PyList_Append(list, item)) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
230 Py_XDECREF(item);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
231 goto error;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
232 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
233
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
234 Py_XDECREF(item);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
235 } while (FindNextFileA(fh, &fd));
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
236
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
237 if (GetLastError() != ERROR_NO_MORE_FILES) {
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
238 PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
239 goto error;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
240 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
241
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
242 rval = list;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
243 Py_XINCREF(rval);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
244 error:
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
245 Py_XDECREF(list);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
246 error_list:
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
247 FindClose(fh);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
248 error_file:
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
249 free(pattern);
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
250 error_nomem:
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
251 return rval;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
252 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
253
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
254 #else
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
255
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
256 int entkind(struct dirent *ent)
5425
830f6e280c90 osutils: pull file stat loop into its own function
Matt Mackall <mpm@selenic.com>
parents: 5424
diff changeset
257 {
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
258 #ifdef DT_REG
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
259 switch (ent->d_type) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
260 case DT_REG: return S_IFREG;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
261 case DT_DIR: return S_IFDIR;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
262 case DT_LNK: return S_IFLNK;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
263 case DT_BLK: return S_IFBLK;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
264 case DT_CHR: return S_IFCHR;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
265 case DT_FIFO: return S_IFIFO;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
266 case DT_SOCK: return S_IFSOCK;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
267 }
5463
3b204881f959 osutil: use fdopendir instead of dirfd
Bryan O'Sullivan <bos@serpentine.com>
parents: 5457
diff changeset
268 #endif
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
269 return -1;
5425
830f6e280c90 osutils: pull file stat loop into its own function
Matt Mackall <mpm@selenic.com>
parents: 5424
diff changeset
270 }
830f6e280c90 osutils: pull file stat loop into its own function
Matt Mackall <mpm@selenic.com>
parents: 5424
diff changeset
271
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
272 static PyObject *_listdir(char *path, int pathlen, int keepstat, char *skip)
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
273 {
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
274 PyObject *list, *elem, *stat, *ret = NULL;
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
275 char fullpath[PATH_MAX + 10];
7136
d834ed27199f _listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
Brendan Cully <brendan@kublai.com>
parents: 7098
diff changeset
276 int kind, err;
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
277 struct stat st;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
278 struct dirent *ent;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
279 DIR *dir;
7136
d834ed27199f _listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
Brendan Cully <brendan@kublai.com>
parents: 7098
diff changeset
280 #ifdef AT_SYMLINK_NOFOLLOW
d834ed27199f _listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
Brendan Cully <brendan@kublai.com>
parents: 7098
diff changeset
281 int dfd = -1;
d834ed27199f _listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
Brendan Cully <brendan@kublai.com>
parents: 7098
diff changeset
282 #endif
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
283
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
284 if (pathlen >= PATH_MAX) {
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
285 PyErr_SetString(PyExc_ValueError, "path too long");
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
286 goto error_value;
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
287 }
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
288 strncpy(fullpath, path, PATH_MAX);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
289 fullpath[pathlen] = '/';
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
290
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
291 #ifdef AT_SYMLINK_NOFOLLOW
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
292 dfd = open(path, O_RDONLY);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
293 if (dfd == -1) {
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
294 PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
295 goto error_value;
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
296 }
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
297 dir = fdopendir(dfd);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
298 #else
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
299 dir = opendir(path);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
300 #endif
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
301 if (!dir) {
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
302 PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
303 goto error_dir;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
304 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
305
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
306 list = PyList_New(0);
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
307 if (!list)
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
308 goto error_list;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
309
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
310 while ((ent = readdir(dir))) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
311 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
312 continue;
5416
ca890c0c3f1f osutil.c: style fix - delete trailing end-of-line spaces
Giorgos Keramidas <keramida@ceid.upatras.gr>
parents: 5398
diff changeset
313
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
314 kind = entkind(ent);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
315 if (kind == -1 || keepstat) {
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
316 #ifdef AT_SYMLINK_NOFOLLOW
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
317 err = fstatat(dfd, ent->d_name, &st,
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
318 AT_SYMLINK_NOFOLLOW);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
319 #else
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
320 strncpy(fullpath + pathlen + 1, ent->d_name,
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
321 PATH_MAX - pathlen);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
322 fullpath[PATH_MAX] = 0;
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
323 err = lstat(fullpath, &st);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
324 #endif
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
325 if (err == -1) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
326 strncpy(fullpath + pathlen + 1, ent->d_name,
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
327 PATH_MAX - pathlen);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
328 fullpath[PATH_MAX] = 0;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
329 PyErr_SetFromErrnoWithFilename(PyExc_OSError,
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
330 fullpath);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
331 goto error;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
332 }
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
333 kind = st.st_mode & S_IFMT;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
334 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
335
7034
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
336 /* quit early? */
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
337 if (skip && kind == S_IFDIR && !strcmp(ent->d_name, skip)) {
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
338 ret = PyList_New(0);
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
339 goto error;
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
340 }
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
341
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
342 if (keepstat) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
343 stat = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
344 if (!stat)
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
345 goto error;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
346 memcpy(&((struct listdir_stat *)stat)->st, &st, sizeof(st));
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
347 elem = Py_BuildValue("siN", ent->d_name, kind, stat);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
348 } else
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
349 elem = Py_BuildValue("si", ent->d_name, kind);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
350 if (!elem)
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
351 goto error;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
352
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
353 PyList_Append(list, elem);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
354 Py_DECREF(elem);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
355 }
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
356
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
357 ret = list;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
358 Py_INCREF(ret);
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
359
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
360 error:
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
361 Py_DECREF(list);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
362 error_list:
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
363 closedir(dir);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
364 error_dir:
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
365 #ifdef AT_SYMLINK_NOFOLLOW
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
366 close(dfd);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
367 #endif
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
368 error_value:
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
369 return ret;
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
370 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
371
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
372 #endif /* ndef _WIN32 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
373
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
374 static PyObject *listdir(PyObject *self, PyObject *args, PyObject *kwargs)
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
375 {
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
376 PyObject *statobj = NULL; /* initialize - optional arg */
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
377 PyObject *skipobj = NULL; /* initialize - optional arg */
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
378 char *path, *skip = NULL;
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
379 int wantstat, plen;
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
380
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
381 static char *kwlist[] = {"path", "stat", "skip", NULL};
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
382
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
383 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|OO:listdir",
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
384 kwlist, &path, &plen, &statobj, &skipobj))
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
385 return NULL;
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
386
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
387 wantstat = statobj && PyObject_IsTrue(statobj);
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
388
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
389 if (skipobj && skipobj != Py_None) {
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
390 skip = PyString_AsString(skipobj);
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
391 if (!skip)
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
392 return NULL;
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
393 }
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
394
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
395 return _listdir(path, plen, wantstat, skip);
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
396 }
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
397
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
398 #ifdef _WIN32
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
399 static PyObject *posixfile(PyObject *self, PyObject *args, PyObject *kwds)
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
400 {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
401 static char *kwlist[] = {"name", "mode", "buffering", NULL};
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
402 PyObject *file_obj = NULL;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
403 char *name = NULL;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
404 char *mode = "rb";
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
405 DWORD access;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
406 DWORD creation;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
407 HANDLE handle;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
408 int fd, flags = 0;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
409 int bufsize = -1;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
410 char m0, m1, m2;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
411 char fpmode[4];
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
412 int fppos = 0;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
413 int plus;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
414 FILE *fp;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
415
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
416 if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|si:posixfile", kwlist,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
417 Py_FileSystemDefaultEncoding,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
418 &name, &mode, &bufsize))
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
419 return NULL;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
420
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
421 m0 = mode[0];
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
422 m1 = m0 ? mode[1] : '\0';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
423 m2 = m1 ? mode[2] : '\0';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
424 plus = m1 == '+' || m2 == '+';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
425
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
426 fpmode[fppos++] = m0;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
427 if (m1 == 'b' || m2 == 'b') {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
428 flags = _O_BINARY;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
429 fpmode[fppos++] = 'b';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
430 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
431 else
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
432 flags = _O_TEXT;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
433 if (plus) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
434 flags |= _O_RDWR;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
435 access = GENERIC_READ | GENERIC_WRITE;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
436 fpmode[fppos++] = '+';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
437 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
438 fpmode[fppos++] = '\0';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
439
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
440 switch (m0) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
441 case 'r':
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
442 creation = OPEN_EXISTING;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
443 if (!plus) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
444 flags |= _O_RDONLY;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
445 access = GENERIC_READ;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
446 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
447 break;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
448 case 'w':
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
449 creation = CREATE_ALWAYS;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
450 if (!plus) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
451 access = GENERIC_WRITE;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
452 flags |= _O_WRONLY;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
453 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
454 break;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
455 case 'a':
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
456 creation = OPEN_ALWAYS;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
457 flags |= _O_APPEND;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
458 if (!plus) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
459 flags |= _O_WRONLY;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
460 access = GENERIC_WRITE;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
461 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
462 break;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
463 default:
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
464 PyErr_Format(PyExc_ValueError,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
465 "mode string must begin with one of 'r', 'w', "
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
466 "or 'a', not '%c'", m0);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
467 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
468 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
469
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
470 handle = CreateFile(name, access,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
471 FILE_SHARE_READ | FILE_SHARE_WRITE |
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
472 FILE_SHARE_DELETE,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
473 NULL,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
474 creation,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
475 FILE_ATTRIBUTE_NORMAL,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
476 0);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
477
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
478 if (handle == INVALID_HANDLE_VALUE) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
479 PyErr_SetFromWindowsErrWithFilename(GetLastError(), name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
480 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
481 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
482
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
483 fd = _open_osfhandle((intptr_t) handle, flags);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
484 if (fd == -1) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
485 CloseHandle(handle);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
486 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
487 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
488 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
489
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
490 fp = _fdopen(fd, fpmode);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
491 if (fp == NULL) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
492 _close(fd);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
493 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
494 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
495 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
496
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
497 file_obj = PyFile_FromFile(fp, name, mode, fclose);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
498 if (file_obj == NULL) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
499 fclose(fp);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
500 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
501 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
502
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
503 PyFile_SetBufSize(file_obj, bufsize);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
504 bail:
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
505 PyMem_Free(name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
506 return file_obj;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
507 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
508 #endif
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
509
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
510 static char osutil_doc[] = "Native operating system services.";
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
511
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
512 static PyMethodDef methods[] = {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
513 {"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS,
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
514 "list a directory\n"},
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
515 #ifdef _WIN32
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
516 {"posixfile", (PyCFunction)posixfile, METH_VARARGS | METH_KEYWORDS,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
517 "Open a file with POSIX-like semantics.\n"
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
518 "On error, this function may raise either a WindowsError or an IOError."},
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
519 #endif
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
520 {NULL, NULL}
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
521 };
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
522
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
523 PyMODINIT_FUNC initosutil(void)
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
524 {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
525 if (PyType_Ready(&listdir_stat_type) == -1)
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
526 return;
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
527
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
528 Py_InitModule3("osutil", methods, osutil_doc);
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
529 }