annotate mercurial/osutil.c @ 13955:86b5cc1e8be8 stable

help config: explain that config files do not exist by default Inspired by critique given on StackOverflow where a user writes: I can have a good guess at what "%USERPROFILE%" might signify but none of the files listed in the "hg help config" output exist after running the installer. Previous experience would suggest that missing files mean something somewhere has gone seriously wrong. http://stackoverflow.com/questions/2329023/2351139#2351139
author Martin Geisler <mg@lazybytes.net>
date Mon, 18 Apr 2011 13:57:22 +0200
parents a4e0908ce35b
children 16118b4859a1
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
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
17 #include <windows.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
18 #include <io.h>
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
19 #else
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
20 #include <dirent.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
21 #include <sys/stat.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
22 #include <sys/types.h>
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
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
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
26 #include "util.h"
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
27
9353
3ac42ca1f3e6 osutil: fix compilation with -ansi
Sebastien Binet <binet@cern.ch>
parents: 8723
diff changeset
28 /* some platforms lack the PATH_MAX definition (eg. GNU/Hurd) */
8722
48da69ff79bd Some platforms lack the PATH_MAX definition (eg. GNU/Hurd).
Arne Babenhauserheide <bab@draketo.de>
parents: 7190
diff changeset
29 #ifndef PATH_MAX
48da69ff79bd Some platforms lack the PATH_MAX definition (eg. GNU/Hurd).
Arne Babenhauserheide <bab@draketo.de>
parents: 7190
diff changeset
30 #define PATH_MAX 4096
48da69ff79bd Some platforms lack the PATH_MAX definition (eg. GNU/Hurd).
Arne Babenhauserheide <bab@draketo.de>
parents: 7190
diff changeset
31 #endif
48da69ff79bd Some platforms lack the PATH_MAX definition (eg. GNU/Hurd).
Arne Babenhauserheide <bab@draketo.de>
parents: 7190
diff changeset
32
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
33 #ifdef _WIN32
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
34 /*
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
35 stat struct compatible with hg expectations
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
36 Mercurial only uses st_mode, st_size and st_mtime
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
37 the rest is kept to minimize changes between implementations
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
38 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
39 struct hg_stat {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
40 int st_dev;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
41 int st_mode;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
42 int st_nlink;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
43 __int64 st_size;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
44 int st_mtime;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
45 int st_ctime;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
46 };
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
47 struct listdir_stat {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
48 PyObject_HEAD
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
49 struct hg_stat st;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
50 };
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
51 #else
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
52 struct listdir_stat {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
53 PyObject_HEAD
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
54 struct stat st;
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
55 };
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
56 #endif
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
57
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
58 #define listdir_slot(name) \
7190
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7136
diff changeset
59 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
60 { \
aecea6934fdd Some additional space/tab cleanups
Thomas Arendsen Hein <thomas@intevation.de>
parents: 7136
diff changeset
61 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
62 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
63
5431
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
64 listdir_slot(st_dev)
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
65 listdir_slot(st_mode)
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
66 listdir_slot(st_nlink)
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
67 #ifdef _WIN32
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
68 static PyObject *listdir_stat_st_size(PyObject *self, void *x)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
69 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
70 return PyLong_FromLongLong(
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
71 (PY_LONG_LONG)((struct listdir_stat *)self)->st.st_size);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
72 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
73 #else
5431
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
74 listdir_slot(st_size)
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
75 #endif
5431
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
76 listdir_slot(st_mtime)
a7c832abd29c Fix build error with Sun C compiler.
Bryan O'Sullivan <bos@serpentine.com>
parents: 5430
diff changeset
77 listdir_slot(st_ctime)
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
78
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
79 static struct PyGetSetDef listdir_stat_getsets[] = {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
80 {"st_dev", listdir_stat_st_dev, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
81 {"st_mode", listdir_stat_st_mode, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
82 {"st_nlink", listdir_stat_st_nlink, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
83 {"st_size", listdir_stat_st_size, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
84 {"st_mtime", listdir_stat_st_mtime, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
85 {"st_ctime", listdir_stat_st_ctime, 0, 0, 0},
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
86 {0, 0, 0, 0, 0}
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
87 };
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
88
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
89 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
90 {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
91 return t->tp_alloc(t, 0);
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
92 }
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
93
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
94 static void listdir_stat_dealloc(PyObject *o)
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
95 {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
96 o->ob_type->tp_free(o);
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
97 }
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
98
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
99 static PyTypeObject listdir_stat_type = {
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
100 PyVarObject_HEAD_INIT(NULL, 0)
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
101 "osutil.stat", /*tp_name*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
102 sizeof(struct listdir_stat), /*tp_basicsize*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
103 0, /*tp_itemsize*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
104 (destructor)listdir_stat_dealloc, /*tp_dealloc*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
105 0, /*tp_print*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
106 0, /*tp_getattr*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
107 0, /*tp_setattr*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
108 0, /*tp_compare*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
109 0, /*tp_repr*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
110 0, /*tp_as_number*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
111 0, /*tp_as_sequence*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
112 0, /*tp_as_mapping*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
113 0, /*tp_hash */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
114 0, /*tp_call*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
115 0, /*tp_str*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
116 0, /*tp_getattro*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
117 0, /*tp_setattro*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
118 0, /*tp_as_buffer*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
119 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
120 "stat objects", /* tp_doc */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
121 0, /* tp_traverse */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
122 0, /* tp_clear */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
123 0, /* tp_richcompare */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
124 0, /* tp_weaklistoffset */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
125 0, /* tp_iter */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
126 0, /* tp_iternext */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
127 0, /* tp_methods */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
128 0, /* tp_members */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
129 listdir_stat_getsets, /* tp_getset */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
130 0, /* tp_base */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
131 0, /* tp_dict */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
132 0, /* tp_descr_get */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
133 0, /* tp_descr_set */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
134 0, /* tp_dictoffset */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
135 0, /* tp_init */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
136 0, /* tp_alloc */
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
137 listdir_stat_new, /* tp_new */
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
138 };
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
139
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
140 #ifdef _WIN32
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
141
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
142 static int to_python_time(const FILETIME *tm)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
143 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
144 /* number of seconds between epoch and January 1 1601 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
145 const __int64 a0 = (__int64)134774L * (__int64)24L * (__int64)3600L;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
146 /* conversion factor from 100ns to 1s */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
147 const __int64 a1 = 10000000;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
148 /* explicit (int) cast to suspend compiler warnings */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
149 return (int)((((__int64)tm->dwHighDateTime << 32)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
150 + tm->dwLowDateTime) / a1 - a0);
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
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
153 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
154 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
155 PyObject *py_st;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
156 struct hg_stat *stp;
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 int kind = (fd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
159 ? _S_IFDIR : _S_IFREG;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
160
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
161 if (!wantstat)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
162 return Py_BuildValue("si", fd->cFileName, kind);
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 py_st = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
165 if (!py_st)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
166 return NULL;
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 = &((struct listdir_stat *)py_st)->st;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
169 /*
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
170 use kind as st_mode
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
171 rwx bits on Win32 are meaningless
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
172 and Hg does not use them anyway
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
173 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
174 stp->st_mode = kind;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
175 stp->st_mtime = to_python_time(&fd->ftLastWriteTime);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
176 stp->st_ctime = to_python_time(&fd->ftCreationTime);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
177 if (kind == _S_IFREG)
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
178 stp->st_size = ((__int64)fd->nFileSizeHigh << 32)
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
179 + fd->nFileSizeLow;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
180 return Py_BuildValue("siN", fd->cFileName,
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
181 kind, py_st);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
182 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
183
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
184 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
185 {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
186 PyObject *rval = NULL; /* initialize - return value */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
187 PyObject *list;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
188 HANDLE fh;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
189 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
190 char *pattern;
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 /* build the path + \* pattern string */
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
193 pattern = malloc(plen + 3); /* path + \* + \0 */
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
194 if (!pattern) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
195 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
196 goto error_nomem;
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
197 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
198 strcpy(pattern, path);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
199
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
200 if (plen > 0) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
201 char c = path[plen-1];
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
202 if (c != ':' && c != '/' && c != '\\')
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
203 pattern[plen++] = '\\';
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
204 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
205 strcpy(pattern + plen, "*");
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 fh = FindFirstFileA(pattern, &fd);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
208 if (fh == INVALID_HANDLE_VALUE) {
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
209 PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
210 goto error_file;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
211 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
212
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
213 list = PyList_New(0);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
214 if (!list)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
215 goto error_list;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
216
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
217 do {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
218 PyObject *item;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
219
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
220 if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
221 if (!strcmp(fd.cFileName, ".")
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
222 || !strcmp(fd.cFileName, ".."))
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
223 continue;
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 if (skip && !strcmp(fd.cFileName, skip)) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
226 rval = PyList_New(0);
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 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
230
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
231 item = make_item(&fd, wantstat);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
232 if (!item)
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
233 goto error;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
234
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
235 if (PyList_Append(list, item)) {
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
236 Py_XDECREF(item);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
237 goto error;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
238 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
239
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
240 Py_XDECREF(item);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
241 } while (FindNextFileA(fh, &fd));
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
242
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
243 if (GetLastError() != ERROR_NO_MORE_FILES) {
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
244 PyErr_SetFromWindowsErrWithFilename(GetLastError(), path);
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
245 goto error;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
246 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
247
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
248 rval = list;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
249 Py_XINCREF(rval);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
250 error:
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
251 Py_XDECREF(list);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
252 error_list:
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
253 FindClose(fh);
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
254 error_file:
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
255 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
256 error_nomem:
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
257 return rval;
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
258 }
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
259
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
260 #else
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
261
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
262 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
263 {
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
264 #ifdef DT_REG
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
265 switch (ent->d_type) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
266 case DT_REG: return S_IFREG;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
267 case DT_DIR: return S_IFDIR;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
268 case DT_LNK: return S_IFLNK;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
269 case DT_BLK: return S_IFBLK;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
270 case DT_CHR: return S_IFCHR;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
271 case DT_FIFO: return S_IFIFO;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
272 case DT_SOCK: return S_IFSOCK;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
273 }
5463
3b204881f959 osutil: use fdopendir instead of dirfd
Bryan O'Sullivan <bos@serpentine.com>
parents: 5457
diff changeset
274 #endif
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
275 return -1;
5425
830f6e280c90 osutils: pull file stat loop into its own function
Matt Mackall <mpm@selenic.com>
parents: 5424
diff changeset
276 }
830f6e280c90 osutils: pull file stat loop into its own function
Matt Mackall <mpm@selenic.com>
parents: 5424
diff changeset
277
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
278 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
279 {
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
280 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
281 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
282 int kind, err;
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
283 struct stat st;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
284 struct dirent *ent;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
285 DIR *dir;
7136
d834ed27199f _listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
Brendan Cully <brendan@kublai.com>
parents: 7098
diff changeset
286 #ifdef AT_SYMLINK_NOFOLLOW
d834ed27199f _listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
Brendan Cully <brendan@kublai.com>
parents: 7098
diff changeset
287 int dfd = -1;
d834ed27199f _listdir only uses dfd if AT_SYMLINK_NOFOLLOW is defined
Brendan Cully <brendan@kublai.com>
parents: 7098
diff changeset
288 #endif
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
289
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
290 if (pathlen >= PATH_MAX) {
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
291 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
292 goto error_value;
7059
6a76cf980999 Improve error handling in osutil.c
Petr Kodl <petrkodl@gmail.com>
parents: 7056
diff changeset
293 }
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
294 strncpy(fullpath, path, PATH_MAX);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
295 fullpath[pathlen] = '/';
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
296
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
297 #ifdef AT_SYMLINK_NOFOLLOW
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
298 dfd = open(path, O_RDONLY);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
299 if (dfd == -1) {
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
300 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
301 goto error_value;
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
302 }
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
303 dir = fdopendir(dfd);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
304 #else
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
305 dir = opendir(path);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
306 #endif
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
307 if (!dir) {
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
308 PyErr_SetFromErrnoWithFilename(PyExc_OSError, path);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
309 goto error_dir;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
310 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
311
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
312 list = PyList_New(0);
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
313 if (!list)
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
314 goto error_list;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
315
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
316 while ((ent = readdir(dir))) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
317 if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
318 continue;
5416
ca890c0c3f1f osutil.c: style fix - delete trailing end-of-line spaces
Giorgos Keramidas <keramida@ceid.upatras.gr>
parents: 5398
diff changeset
319
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
320 kind = entkind(ent);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
321 if (kind == -1 || keepstat) {
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
322 #ifdef AT_SYMLINK_NOFOLLOW
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
323 err = fstatat(dfd, ent->d_name, &st,
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
324 AT_SYMLINK_NOFOLLOW);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
325 #else
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
326 strncpy(fullpath + pathlen + 1, ent->d_name,
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
327 PATH_MAX - pathlen);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
328 fullpath[PATH_MAX] = 0;
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
329 err = lstat(fullpath, &st);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
330 #endif
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
331 if (err == -1) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
332 strncpy(fullpath + pathlen + 1, ent->d_name,
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
333 PATH_MAX - pathlen);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
334 fullpath[PATH_MAX] = 0;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
335 PyErr_SetFromErrnoWithFilename(PyExc_OSError,
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
336 fullpath);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
337 goto error;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
338 }
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
339 kind = st.st_mode & S_IFMT;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
340 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
341
7034
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
342 /* quit early? */
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
343 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
344 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
345 goto error;
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
346 }
0d513661d6c2 listdir: add support for aborting if a certain path is found
Matt Mackall <mpm@selenic.com>
parents: 7033
diff changeset
347
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
348 if (keepstat) {
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
349 stat = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
350 if (!stat)
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 memcpy(&((struct listdir_stat *)stat)->st, &st, sizeof(st));
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
353 elem = Py_BuildValue("siN", ent->d_name, kind, stat);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
354 } else
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
355 elem = Py_BuildValue("si", ent->d_name, kind);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
356 if (!elem)
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
357 goto error;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
358
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
359 PyList_Append(list, elem);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
360 Py_DECREF(elem);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
361 }
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
362
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
363 ret = list;
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
364 Py_INCREF(ret);
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
365
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
366 error:
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
367 Py_DECREF(list);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
368 error_list:
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
369 closedir(dir);
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
370 error_dir:
7033
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
371 #ifdef AT_SYMLINK_NOFOLLOW
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
372 close(dfd);
892d27fb04a5 osutil: fix some braindamage
Matt Mackall <mpm@selenic.com>
parents: 7031
diff changeset
373 #endif
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
374 error_value:
7031
19e8d034932e osutil: major listdir cleanup
Matt Mackall <mpm@selenic.com>
parents: 7022
diff changeset
375 return ret;
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
376 }
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
377
7056
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
378 #endif /* ndef _WIN32 */
2c1f18b88b6a osutil: implementation for Win32
Petr Kodl <petrkodl@gmail.com>
parents: 7034
diff changeset
379
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
380 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
381 {
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
382 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
383 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
384 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
385 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
386
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
387 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
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 (!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
390 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
391 return NULL;
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
392
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
393 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
394
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
395 if (skipobj && skipobj != Py_None) {
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
396 skip = PyBytes_AsString(skipobj);
7098
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
397 if (!skip)
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
398 return NULL;
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
399 }
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
400
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
401 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
402 }
8a5c88c7e97b osutil.c: refactor argument parsing, allow skip=None being passed
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 7059
diff changeset
403
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
404 #ifdef _WIN32
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
405 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
406 {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
407 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
408 PyObject *file_obj = NULL;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
409 char *name = NULL;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
410 char *mode = "rb";
8597
dc1b9e22f288 osutil: silence uninitialized variable warning
Patrick Mezard <pmezard@gmail.com>
parents: 8330
diff changeset
411 DWORD access = 0;
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
412 DWORD creation;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
413 HANDLE handle;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
414 int fd, flags = 0;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
415 int bufsize = -1;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
416 char m0, m1, m2;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
417 char fpmode[4];
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
418 int fppos = 0;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
419 int plus;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
420 FILE *fp;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
421
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
422 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
423 Py_FileSystemDefaultEncoding,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
424 &name, &mode, &bufsize))
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
425 return NULL;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
426
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
427 m0 = mode[0];
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
428 m1 = m0 ? mode[1] : '\0';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
429 m2 = m1 ? mode[2] : '\0';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
430 plus = m1 == '+' || m2 == '+';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
431
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
432 fpmode[fppos++] = m0;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
433 if (m1 == 'b' || m2 == 'b') {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
434 flags = _O_BINARY;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
435 fpmode[fppos++] = 'b';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
436 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
437 else
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
438 flags = _O_TEXT;
13273
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
439 if (m0 == 'r' && !plus) {
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
440 flags |= _O_RDONLY;
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
441 access = GENERIC_READ;
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
442 } else {
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
443 /*
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
444 work around http://support.microsoft.com/kb/899149 and
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
445 set _O_RDWR for 'w' and 'a', even if mode has no '+'
764441ecbf2e osutil: treat open modes 'w' and 'a' as 'w+' and 'a+' in posixfile
Adrian Buehlmann <adrian@cadifra.com>
parents: 11359
diff changeset
446 */
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
447 flags |= _O_RDWR;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
448 access = GENERIC_READ | GENERIC_WRITE;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
449 fpmode[fppos++] = '+';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
450 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
451 fpmode[fppos++] = '\0';
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
452
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
453 switch (m0) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
454 case 'r':
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
455 creation = OPEN_EXISTING;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
456 break;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
457 case 'w':
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
458 creation = CREATE_ALWAYS;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
459 break;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
460 case 'a':
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
461 creation = OPEN_ALWAYS;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
462 flags |= _O_APPEND;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
463 break;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
464 default:
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
465 PyErr_Format(PyExc_ValueError,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
466 "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
467 "or 'a', not '%c'", m0);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
468 goto bail;
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
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
471 handle = CreateFile(name, access,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
472 FILE_SHARE_READ | FILE_SHARE_WRITE |
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
473 FILE_SHARE_DELETE,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
474 NULL,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
475 creation,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
476 FILE_ATTRIBUTE_NORMAL,
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
477 0);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
478
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
479 if (handle == INVALID_HANDLE_VALUE) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
480 PyErr_SetFromWindowsErrWithFilename(GetLastError(), name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
481 goto bail;
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
10282
08a0f04b56bd many, many trivial check-code fixups
Matt Mackall <mpm@selenic.com>
parents: 9353
diff changeset
484 fd = _open_osfhandle((intptr_t)handle, flags);
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
485
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
486 if (fd == -1) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
487 CloseHandle(handle);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
488 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
489 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
490 }
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
491 #ifndef IS_PY3K
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
492 fp = _fdopen(fd, fpmode);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
493 if (fp == NULL) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
494 _close(fd);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
495 PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
496 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
497 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
498
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
499 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
500 if (file_obj == NULL) {
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
501 fclose(fp);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
502 goto bail;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
503 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
504
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
505 PyFile_SetBufSize(file_obj, bufsize);
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
506 #else
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
507 file_obj = PyFile_FromFd(fd, name, mode, bufsize, NULL, NULL, NULL, 1);
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
508 if (file_obj == NULL)
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
509 goto bail;
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
510 #endif
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
511 bail:
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
512 PyMem_Free(name);
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
513 return file_obj;
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
514 }
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
515 #endif
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
516
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
517 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
518
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
519 static PyMethodDef methods[] = {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
520 {"listdir", (PyCFunction)listdir, METH_VARARGS | METH_KEYWORDS,
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
521 "list a directory\n"},
8330
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
522 #ifdef _WIN32
7de68012f86e Windows: improve performance via buffered I/O
Bryan O'Sullivan <bos@serpentine.com>
parents: 7190
diff changeset
523 {"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
524 "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
525 "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
526 #endif
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
527 {NULL, NULL}
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
528 };
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
529
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
530 #ifdef IS_PY3K
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
531 static struct PyModuleDef osutil_module = {
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
532 PyModuleDef_HEAD_INIT,
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
533 "osutil",
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
534 osutil_doc,
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
535 -1,
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
536 methods
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
537 };
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
538
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
539 PyMODINIT_FUNC PyInit_osutil(void)
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
540 {
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
541 if (PyType_Ready(&listdir_stat_type) < 0)
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
542 return NULL;
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
543
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
544 return PyModule_Create(&osutil_module);
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
545 }
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
546 #else
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
547 PyMODINIT_FUNC initosutil(void)
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
548 {
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
549 if (PyType_Ready(&listdir_stat_type) == -1)
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
550 return;
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
551
5421
9b5d626be8ba osutil: cleanups
Matt Mackall <mpm@selenic.com>
parents: 5416
diff changeset
552 Py_InitModule3("osutil", methods, osutil_doc);
5396
5105b119edd2 Add osutil module, containing a listdir function.
Bryan O'Sullivan <bos@serpentine.com>
parents:
diff changeset
553 }
11359
4eaacccbb2ca osutil.c: Support for py3k added.
Renato Cunha <renatoc@gmail.com>
parents: 10282
diff changeset
554 #endif