##// END OF EJS Templates
win32: read system rcpath from registry...
Steve Borho -
r5583:1b5b81d9 default
parent child Browse files
Show More
@@ -1,579 +1,583
1 HGRC(5)
1 HGRC(5)
2 =======
2 =======
3 Bryan O'Sullivan <bos@serpentine.com>
3 Bryan O'Sullivan <bos@serpentine.com>
4
4
5 NAME
5 NAME
6 ----
6 ----
7 hgrc - configuration files for Mercurial
7 hgrc - configuration files for Mercurial
8
8
9 SYNOPSIS
9 SYNOPSIS
10 --------
10 --------
11
11
12 The Mercurial system uses a set of configuration files to control
12 The Mercurial system uses a set of configuration files to control
13 aspects of its behaviour.
13 aspects of its behaviour.
14
14
15 FILES
15 FILES
16 -----
16 -----
17
17
18 Mercurial reads configuration data from several files, if they exist.
18 Mercurial reads configuration data from several files, if they exist.
19 The names of these files depend on the system on which Mercurial is
19 The names of these files depend on the system on which Mercurial is
20 installed.
20 installed. Windows registry keys contain PATH-like strings, every
21 part must reference a Mercurial.ini file or be a directory where *.rc
22 files will be read.
21
23
22 (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc::
24 (Unix) <install-root>/etc/mercurial/hgrc.d/*.rc::
23 (Unix) <install-root>/etc/mercurial/hgrc::
25 (Unix) <install-root>/etc/mercurial/hgrc::
24 Per-installation configuration files, searched for in the
26 Per-installation configuration files, searched for in the
25 directory where Mercurial is installed. For example, if installed
27 directory where Mercurial is installed. For example, if installed
26 in /shared/tools, Mercurial will look in
28 in /shared/tools, Mercurial will look in
27 /shared/tools/etc/mercurial/hgrc. Options in these files apply to
29 /shared/tools/etc/mercurial/hgrc. Options in these files apply to
28 all Mercurial commands executed by any user in any directory.
30 all Mercurial commands executed by any user in any directory.
29
31
30 (Unix) /etc/mercurial/hgrc.d/*.rc::
32 (Unix) /etc/mercurial/hgrc.d/*.rc::
31 (Unix) /etc/mercurial/hgrc::
33 (Unix) /etc/mercurial/hgrc::
34 (Windows) HKEY_LOCAL_MACHINE\SOFTWARE\Mercurial::
35 or::
32 (Windows) C:\Mercurial\Mercurial.ini::
36 (Windows) C:\Mercurial\Mercurial.ini::
33 Per-system configuration files, for the system on which Mercurial
37 Per-system configuration files, for the system on which Mercurial
34 is running. Options in these files apply to all Mercurial
38 is running. Options in these files apply to all Mercurial
35 commands executed by any user in any directory. Options in these
39 commands executed by any user in any directory. Options in these
36 files override per-installation options.
40 files override per-installation options.
37
41
38 (Unix) $HOME/.hgrc::
42 (Unix) $HOME/.hgrc::
39 (Windows) C:\Documents and Settings\USERNAME\Mercurial.ini::
43 (Windows) C:\Documents and Settings\USERNAME\Mercurial.ini::
40 (Windows) $HOME\Mercurial.ini::
44 (Windows) $HOME\Mercurial.ini::
41 Per-user configuration file, for the user running Mercurial.
45 Per-user configuration file, for the user running Mercurial.
42 Options in this file apply to all Mercurial commands executed by
46 Options in this file apply to all Mercurial commands executed by
43 any user in any directory. Options in this file override
47 any user in any directory. Options in this file override
44 per-installation and per-system options.
48 per-installation and per-system options.
45 On Windows system, one of these is chosen exclusively according
49 On Windows system, one of these is chosen exclusively according
46 to definition of HOME environment variable.
50 to definition of HOME environment variable.
47
51
48 (Unix, Windows) <repo>/.hg/hgrc::
52 (Unix, Windows) <repo>/.hg/hgrc::
49 Per-repository configuration options that only apply in a
53 Per-repository configuration options that only apply in a
50 particular repository. This file is not version-controlled, and
54 particular repository. This file is not version-controlled, and
51 will not get transferred during a "clone" operation. Options in
55 will not get transferred during a "clone" operation. Options in
52 this file override options in all other configuration files.
56 this file override options in all other configuration files.
53 On Unix, most of this file will be ignored if it doesn't belong
57 On Unix, most of this file will be ignored if it doesn't belong
54 to a trusted user or to a trusted group. See the documentation
58 to a trusted user or to a trusted group. See the documentation
55 for the trusted section below for more details.
59 for the trusted section below for more details.
56
60
57 SYNTAX
61 SYNTAX
58 ------
62 ------
59
63
60 A configuration file consists of sections, led by a "[section]" header
64 A configuration file consists of sections, led by a "[section]" header
61 and followed by "name: value" entries; "name=value" is also accepted.
65 and followed by "name: value" entries; "name=value" is also accepted.
62
66
63 [spam]
67 [spam]
64 eggs=ham
68 eggs=ham
65 green=
69 green=
66 eggs
70 eggs
67
71
68 Each line contains one entry. If the lines that follow are indented,
72 Each line contains one entry. If the lines that follow are indented,
69 they are treated as continuations of that entry.
73 they are treated as continuations of that entry.
70
74
71 Leading whitespace is removed from values. Empty lines are skipped.
75 Leading whitespace is removed from values. Empty lines are skipped.
72
76
73 The optional values can contain format strings which refer to other
77 The optional values can contain format strings which refer to other
74 values in the same section, or values in a special DEFAULT section.
78 values in the same section, or values in a special DEFAULT section.
75
79
76 Lines beginning with "#" or ";" are ignored and may be used to provide
80 Lines beginning with "#" or ";" are ignored and may be used to provide
77 comments.
81 comments.
78
82
79 SECTIONS
83 SECTIONS
80 --------
84 --------
81
85
82 This section describes the different sections that may appear in a
86 This section describes the different sections that may appear in a
83 Mercurial "hgrc" file, the purpose of each section, its possible
87 Mercurial "hgrc" file, the purpose of each section, its possible
84 keys, and their possible values.
88 keys, and their possible values.
85
89
86 decode/encode::
90 decode/encode::
87 Filters for transforming files on checkout/checkin. This would
91 Filters for transforming files on checkout/checkin. This would
88 typically be used for newline processing or other
92 typically be used for newline processing or other
89 localization/canonicalization of files.
93 localization/canonicalization of files.
90
94
91 Filters consist of a filter pattern followed by a filter command.
95 Filters consist of a filter pattern followed by a filter command.
92 Filter patterns are globs by default, rooted at the repository
96 Filter patterns are globs by default, rooted at the repository
93 root. For example, to match any file ending in ".txt" in the root
97 root. For example, to match any file ending in ".txt" in the root
94 directory only, use the pattern "*.txt". To match any file ending
98 directory only, use the pattern "*.txt". To match any file ending
95 in ".c" anywhere in the repository, use the pattern "**.c".
99 in ".c" anywhere in the repository, use the pattern "**.c".
96
100
97 The filter command can start with a specifier, either "pipe:" or
101 The filter command can start with a specifier, either "pipe:" or
98 "tempfile:". If no specifier is given, "pipe:" is used by default.
102 "tempfile:". If no specifier is given, "pipe:" is used by default.
99
103
100 A "pipe:" command must accept data on stdin and return the
104 A "pipe:" command must accept data on stdin and return the
101 transformed data on stdout.
105 transformed data on stdout.
102
106
103 Pipe example:
107 Pipe example:
104
108
105 [encode]
109 [encode]
106 # uncompress gzip files on checkin to improve delta compression
110 # uncompress gzip files on checkin to improve delta compression
107 # note: not necessarily a good idea, just an example
111 # note: not necessarily a good idea, just an example
108 *.gz = pipe: gunzip
112 *.gz = pipe: gunzip
109
113
110 [decode]
114 [decode]
111 # recompress gzip files when writing them to the working dir (we
115 # recompress gzip files when writing them to the working dir (we
112 # can safely omit "pipe:", because it's the default)
116 # can safely omit "pipe:", because it's the default)
113 *.gz = gzip
117 *.gz = gzip
114
118
115 A "tempfile:" command is a template. The string INFILE is replaced
119 A "tempfile:" command is a template. The string INFILE is replaced
116 with the name of a temporary file that contains the data to be
120 with the name of a temporary file that contains the data to be
117 filtered by the command. The string OUTFILE is replaced with the
121 filtered by the command. The string OUTFILE is replaced with the
118 name of an empty temporary file, where the filtered data must be
122 name of an empty temporary file, where the filtered data must be
119 written by the command.
123 written by the command.
120
124
121 NOTE: the tempfile mechanism is recommended for Windows systems,
125 NOTE: the tempfile mechanism is recommended for Windows systems,
122 where the standard shell I/O redirection operators often have
126 where the standard shell I/O redirection operators often have
123 strange effects. In particular, if you are doing line ending
127 strange effects. In particular, if you are doing line ending
124 conversion on Windows using the popular dos2unix and unix2dos
128 conversion on Windows using the popular dos2unix and unix2dos
125 programs, you *must* use the tempfile mechanism, as using pipes will
129 programs, you *must* use the tempfile mechanism, as using pipes will
126 corrupt the contents of your files.
130 corrupt the contents of your files.
127
131
128 Tempfile example:
132 Tempfile example:
129
133
130 [encode]
134 [encode]
131 # convert files to unix line ending conventions on checkin
135 # convert files to unix line ending conventions on checkin
132 **.txt = tempfile: dos2unix -n INFILE OUTFILE
136 **.txt = tempfile: dos2unix -n INFILE OUTFILE
133
137
134 [decode]
138 [decode]
135 # convert files to windows line ending conventions when writing
139 # convert files to windows line ending conventions when writing
136 # them to the working dir
140 # them to the working dir
137 **.txt = tempfile: unix2dos -n INFILE OUTFILE
141 **.txt = tempfile: unix2dos -n INFILE OUTFILE
138
142
139 defaults::
143 defaults::
140 Use the [defaults] section to define command defaults, i.e. the
144 Use the [defaults] section to define command defaults, i.e. the
141 default options/arguments to pass to the specified commands.
145 default options/arguments to pass to the specified commands.
142
146
143 The following example makes 'hg log' run in verbose mode, and
147 The following example makes 'hg log' run in verbose mode, and
144 'hg status' show only the modified files, by default.
148 'hg status' show only the modified files, by default.
145
149
146 [defaults]
150 [defaults]
147 log = -v
151 log = -v
148 status = -m
152 status = -m
149
153
150 The actual commands, instead of their aliases, must be used when
154 The actual commands, instead of their aliases, must be used when
151 defining command defaults. The command defaults will also be
155 defining command defaults. The command defaults will also be
152 applied to the aliases of the commands defined.
156 applied to the aliases of the commands defined.
153
157
154 diff::
158 diff::
155 Settings used when displaying diffs. They are all boolean and
159 Settings used when displaying diffs. They are all boolean and
156 defaults to False.
160 defaults to False.
157 git;;
161 git;;
158 Use git extended diff format.
162 Use git extended diff format.
159 nodates;;
163 nodates;;
160 Don't include dates in diff headers.
164 Don't include dates in diff headers.
161 showfunc;;
165 showfunc;;
162 Show which function each change is in.
166 Show which function each change is in.
163 ignorews;;
167 ignorews;;
164 Ignore white space when comparing lines.
168 Ignore white space when comparing lines.
165 ignorewsamount;;
169 ignorewsamount;;
166 Ignore changes in the amount of white space.
170 Ignore changes in the amount of white space.
167 ignoreblanklines;;
171 ignoreblanklines;;
168 Ignore changes whose lines are all blank.
172 Ignore changes whose lines are all blank.
169
173
170 email::
174 email::
171 Settings for extensions that send email messages.
175 Settings for extensions that send email messages.
172 from;;
176 from;;
173 Optional. Email address to use in "From" header and SMTP envelope
177 Optional. Email address to use in "From" header and SMTP envelope
174 of outgoing messages.
178 of outgoing messages.
175 to;;
179 to;;
176 Optional. Comma-separated list of recipients' email addresses.
180 Optional. Comma-separated list of recipients' email addresses.
177 cc;;
181 cc;;
178 Optional. Comma-separated list of carbon copy recipients'
182 Optional. Comma-separated list of carbon copy recipients'
179 email addresses.
183 email addresses.
180 bcc;;
184 bcc;;
181 Optional. Comma-separated list of blind carbon copy
185 Optional. Comma-separated list of blind carbon copy
182 recipients' email addresses. Cannot be set interactively.
186 recipients' email addresses. Cannot be set interactively.
183 method;;
187 method;;
184 Optional. Method to use to send email messages. If value is
188 Optional. Method to use to send email messages. If value is
185 "smtp" (default), use SMTP (see section "[smtp]" for
189 "smtp" (default), use SMTP (see section "[smtp]" for
186 configuration). Otherwise, use as name of program to run that
190 configuration). Otherwise, use as name of program to run that
187 acts like sendmail (takes "-f" option for sender, list of
191 acts like sendmail (takes "-f" option for sender, list of
188 recipients on command line, message on stdin). Normally, setting
192 recipients on command line, message on stdin). Normally, setting
189 this to "sendmail" or "/usr/sbin/sendmail" is enough to use
193 this to "sendmail" or "/usr/sbin/sendmail" is enough to use
190 sendmail to send messages.
194 sendmail to send messages.
191
195
192 Email example:
196 Email example:
193
197
194 [email]
198 [email]
195 from = Joseph User <joe.user@example.com>
199 from = Joseph User <joe.user@example.com>
196 method = /usr/sbin/sendmail
200 method = /usr/sbin/sendmail
197
201
198 extensions::
202 extensions::
199 Mercurial has an extension mechanism for adding new features. To
203 Mercurial has an extension mechanism for adding new features. To
200 enable an extension, create an entry for it in this section.
204 enable an extension, create an entry for it in this section.
201
205
202 If you know that the extension is already in Python's search path,
206 If you know that the extension is already in Python's search path,
203 you can give the name of the module, followed by "=", with nothing
207 you can give the name of the module, followed by "=", with nothing
204 after the "=".
208 after the "=".
205
209
206 Otherwise, give a name that you choose, followed by "=", followed by
210 Otherwise, give a name that you choose, followed by "=", followed by
207 the path to the ".py" file (including the file name extension) that
211 the path to the ".py" file (including the file name extension) that
208 defines the extension.
212 defines the extension.
209
213
210 Example for ~/.hgrc:
214 Example for ~/.hgrc:
211
215
212 [extensions]
216 [extensions]
213 # (the mq extension will get loaded from mercurial's path)
217 # (the mq extension will get loaded from mercurial's path)
214 hgext.mq =
218 hgext.mq =
215 # (this extension will get loaded from the file specified)
219 # (this extension will get loaded from the file specified)
216 myfeature = ~/.hgext/myfeature.py
220 myfeature = ~/.hgext/myfeature.py
217
221
218 format::
222 format::
219
223
220 usestore;;
224 usestore;;
221 Enable or disable the "store" repository format which improves
225 Enable or disable the "store" repository format which improves
222 compatibility with systems that fold case or otherwise mangle
226 compatibility with systems that fold case or otherwise mangle
223 filenames. Enabled by default. Disabling this option will allow
227 filenames. Enabled by default. Disabling this option will allow
224 you to store longer filenames in some situations at the expense of
228 you to store longer filenames in some situations at the expense of
225 compatibility.
229 compatibility.
226
230
227 hooks::
231 hooks::
228 Commands or Python functions that get automatically executed by
232 Commands or Python functions that get automatically executed by
229 various actions such as starting or finishing a commit. Multiple
233 various actions such as starting or finishing a commit. Multiple
230 hooks can be run for the same action by appending a suffix to the
234 hooks can be run for the same action by appending a suffix to the
231 action. Overriding a site-wide hook can be done by changing its
235 action. Overriding a site-wide hook can be done by changing its
232 value or setting it to an empty string.
236 value or setting it to an empty string.
233
237
234 Example .hg/hgrc:
238 Example .hg/hgrc:
235
239
236 [hooks]
240 [hooks]
237 # do not use the site-wide hook
241 # do not use the site-wide hook
238 incoming =
242 incoming =
239 incoming.email = /my/email/hook
243 incoming.email = /my/email/hook
240 incoming.autobuild = /my/build/hook
244 incoming.autobuild = /my/build/hook
241
245
242 Most hooks are run with environment variables set that give added
246 Most hooks are run with environment variables set that give added
243 useful information. For each hook below, the environment variables
247 useful information. For each hook below, the environment variables
244 it is passed are listed with names of the form "$HG_foo".
248 it is passed are listed with names of the form "$HG_foo".
245
249
246 changegroup;;
250 changegroup;;
247 Run after a changegroup has been added via push, pull or
251 Run after a changegroup has been added via push, pull or
248 unbundle. ID of the first new changeset is in $HG_NODE. URL from
252 unbundle. ID of the first new changeset is in $HG_NODE. URL from
249 which changes came is in $HG_URL.
253 which changes came is in $HG_URL.
250 commit;;
254 commit;;
251 Run after a changeset has been created in the local repository.
255 Run after a changeset has been created in the local repository.
252 ID of the newly created changeset is in $HG_NODE. Parent
256 ID of the newly created changeset is in $HG_NODE. Parent
253 changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
257 changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
254 incoming;;
258 incoming;;
255 Run after a changeset has been pulled, pushed, or unbundled into
259 Run after a changeset has been pulled, pushed, or unbundled into
256 the local repository. The ID of the newly arrived changeset is in
260 the local repository. The ID of the newly arrived changeset is in
257 $HG_NODE. URL that was source of changes came is in $HG_URL.
261 $HG_NODE. URL that was source of changes came is in $HG_URL.
258 outgoing;;
262 outgoing;;
259 Run after sending changes from local repository to another. ID of
263 Run after sending changes from local repository to another. ID of
260 first changeset sent is in $HG_NODE. Source of operation is in
264 first changeset sent is in $HG_NODE. Source of operation is in
261 $HG_SOURCE; see "preoutgoing" hook for description.
265 $HG_SOURCE; see "preoutgoing" hook for description.
262 post-<command>;;
266 post-<command>;;
263 Run after successful invocations of the associated command. The
267 Run after successful invocations of the associated command. The
264 contents of the command line are passed as $HG_ARGS and the result
268 contents of the command line are passed as $HG_ARGS and the result
265 code in $HG_RESULT. Hook failure is ignored.
269 code in $HG_RESULT. Hook failure is ignored.
266 pre-<command>;;
270 pre-<command>;;
267 Run before executing the associated command. The contents of the
271 Run before executing the associated command. The contents of the
268 command line are passed as $HG_ARGS. If the hook returns failure,
272 command line are passed as $HG_ARGS. If the hook returns failure,
269 the command doesn't execute and Mercurial returns the failure code.
273 the command doesn't execute and Mercurial returns the failure code.
270 prechangegroup;;
274 prechangegroup;;
271 Run before a changegroup is added via push, pull or unbundle.
275 Run before a changegroup is added via push, pull or unbundle.
272 Exit status 0 allows the changegroup to proceed. Non-zero status
276 Exit status 0 allows the changegroup to proceed. Non-zero status
273 will cause the push, pull or unbundle to fail. URL from which
277 will cause the push, pull or unbundle to fail. URL from which
274 changes will come is in $HG_URL.
278 changes will come is in $HG_URL.
275 precommit;;
279 precommit;;
276 Run before starting a local commit. Exit status 0 allows the
280 Run before starting a local commit. Exit status 0 allows the
277 commit to proceed. Non-zero status will cause the commit to fail.
281 commit to proceed. Non-zero status will cause the commit to fail.
278 Parent changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
282 Parent changeset IDs are in $HG_PARENT1 and $HG_PARENT2.
279 preoutgoing;;
283 preoutgoing;;
280 Run before computing changes to send from the local repository to
284 Run before computing changes to send from the local repository to
281 another. Non-zero status will cause failure. This lets you
285 another. Non-zero status will cause failure. This lets you
282 prevent pull over http or ssh. Also prevents against local pull,
286 prevent pull over http or ssh. Also prevents against local pull,
283 push (outbound) or bundle commands, but not effective, since you
287 push (outbound) or bundle commands, but not effective, since you
284 can just copy files instead then. Source of operation is in
288 can just copy files instead then. Source of operation is in
285 $HG_SOURCE. If "serve", operation is happening on behalf of
289 $HG_SOURCE. If "serve", operation is happening on behalf of
286 remote ssh or http repository. If "push", "pull" or "bundle",
290 remote ssh or http repository. If "push", "pull" or "bundle",
287 operation is happening on behalf of repository on same system.
291 operation is happening on behalf of repository on same system.
288 pretag;;
292 pretag;;
289 Run before creating a tag. Exit status 0 allows the tag to be
293 Run before creating a tag. Exit status 0 allows the tag to be
290 created. Non-zero status will cause the tag to fail. ID of
294 created. Non-zero status will cause the tag to fail. ID of
291 changeset to tag is in $HG_NODE. Name of tag is in $HG_TAG. Tag
295 changeset to tag is in $HG_NODE. Name of tag is in $HG_TAG. Tag
292 is local if $HG_LOCAL=1, in repo if $HG_LOCAL=0.
296 is local if $HG_LOCAL=1, in repo if $HG_LOCAL=0.
293 pretxnchangegroup;;
297 pretxnchangegroup;;
294 Run after a changegroup has been added via push, pull or unbundle,
298 Run after a changegroup has been added via push, pull or unbundle,
295 but before the transaction has been committed. Changegroup is
299 but before the transaction has been committed. Changegroup is
296 visible to hook program. This lets you validate incoming changes
300 visible to hook program. This lets you validate incoming changes
297 before accepting them. Passed the ID of the first new changeset
301 before accepting them. Passed the ID of the first new changeset
298 in $HG_NODE. Exit status 0 allows the transaction to commit.
302 in $HG_NODE. Exit status 0 allows the transaction to commit.
299 Non-zero status will cause the transaction to be rolled back and
303 Non-zero status will cause the transaction to be rolled back and
300 the push, pull or unbundle will fail. URL that was source of
304 the push, pull or unbundle will fail. URL that was source of
301 changes is in $HG_URL.
305 changes is in $HG_URL.
302 pretxncommit;;
306 pretxncommit;;
303 Run after a changeset has been created but the transaction not yet
307 Run after a changeset has been created but the transaction not yet
304 committed. Changeset is visible to hook program. This lets you
308 committed. Changeset is visible to hook program. This lets you
305 validate commit message and changes. Exit status 0 allows the
309 validate commit message and changes. Exit status 0 allows the
306 commit to proceed. Non-zero status will cause the transaction to
310 commit to proceed. Non-zero status will cause the transaction to
307 be rolled back. ID of changeset is in $HG_NODE. Parent changeset
311 be rolled back. ID of changeset is in $HG_NODE. Parent changeset
308 IDs are in $HG_PARENT1 and $HG_PARENT2.
312 IDs are in $HG_PARENT1 and $HG_PARENT2.
309 preupdate;;
313 preupdate;;
310 Run before updating the working directory. Exit status 0 allows
314 Run before updating the working directory. Exit status 0 allows
311 the update to proceed. Non-zero status will prevent the update.
315 the update to proceed. Non-zero status will prevent the update.
312 Changeset ID of first new parent is in $HG_PARENT1. If merge, ID
316 Changeset ID of first new parent is in $HG_PARENT1. If merge, ID
313 of second new parent is in $HG_PARENT2.
317 of second new parent is in $HG_PARENT2.
314 tag;;
318 tag;;
315 Run after a tag is created. ID of tagged changeset is in
319 Run after a tag is created. ID of tagged changeset is in
316 $HG_NODE. Name of tag is in $HG_TAG. Tag is local if
320 $HG_NODE. Name of tag is in $HG_TAG. Tag is local if
317 $HG_LOCAL=1, in repo if $HG_LOCAL=0.
321 $HG_LOCAL=1, in repo if $HG_LOCAL=0.
318 update;;
322 update;;
319 Run after updating the working directory. Changeset ID of first
323 Run after updating the working directory. Changeset ID of first
320 new parent is in $HG_PARENT1. If merge, ID of second new parent
324 new parent is in $HG_PARENT1. If merge, ID of second new parent
321 is in $HG_PARENT2. If update succeeded, $HG_ERROR=0. If update
325 is in $HG_PARENT2. If update succeeded, $HG_ERROR=0. If update
322 failed (e.g. because conflicts not resolved), $HG_ERROR=1.
326 failed (e.g. because conflicts not resolved), $HG_ERROR=1.
323
327
324 Note: it is generally better to use standard hooks rather than the
328 Note: it is generally better to use standard hooks rather than the
325 generic pre- and post- command hooks as they are guaranteed to be
329 generic pre- and post- command hooks as they are guaranteed to be
326 called in the appropriate contexts for influencing transactions.
330 called in the appropriate contexts for influencing transactions.
327 Also, hooks like "commit" will be called in all contexts that
331 Also, hooks like "commit" will be called in all contexts that
328 generate a commit (eg. tag) and not just the commit command.
332 generate a commit (eg. tag) and not just the commit command.
329
333
330 Note2: Environment variables with empty values may not be passed to
334 Note2: Environment variables with empty values may not be passed to
331 hooks on platforms like Windows. For instance, $HG_PARENT2 will
335 hooks on platforms like Windows. For instance, $HG_PARENT2 will
332 not be available under Windows for non-merge changesets while being
336 not be available under Windows for non-merge changesets while being
333 set to an empty value under Unix-like systems.
337 set to an empty value under Unix-like systems.
334
338
335 The syntax for Python hooks is as follows:
339 The syntax for Python hooks is as follows:
336
340
337 hookname = python:modulename.submodule.callable
341 hookname = python:modulename.submodule.callable
338
342
339 Python hooks are run within the Mercurial process. Each hook is
343 Python hooks are run within the Mercurial process. Each hook is
340 called with at least three keyword arguments: a ui object (keyword
344 called with at least three keyword arguments: a ui object (keyword
341 "ui"), a repository object (keyword "repo"), and a "hooktype"
345 "ui"), a repository object (keyword "repo"), and a "hooktype"
342 keyword that tells what kind of hook is used. Arguments listed as
346 keyword that tells what kind of hook is used. Arguments listed as
343 environment variables above are passed as keyword arguments, with no
347 environment variables above are passed as keyword arguments, with no
344 "HG_" prefix, and names in lower case.
348 "HG_" prefix, and names in lower case.
345
349
346 If a Python hook returns a "true" value or raises an exception, this
350 If a Python hook returns a "true" value or raises an exception, this
347 is treated as failure of the hook.
351 is treated as failure of the hook.
348
352
349 http_proxy::
353 http_proxy::
350 Used to access web-based Mercurial repositories through a HTTP
354 Used to access web-based Mercurial repositories through a HTTP
351 proxy.
355 proxy.
352 host;;
356 host;;
353 Host name and (optional) port of the proxy server, for example
357 Host name and (optional) port of the proxy server, for example
354 "myproxy:8000".
358 "myproxy:8000".
355 no;;
359 no;;
356 Optional. Comma-separated list of host names that should bypass
360 Optional. Comma-separated list of host names that should bypass
357 the proxy.
361 the proxy.
358 passwd;;
362 passwd;;
359 Optional. Password to authenticate with at the proxy server.
363 Optional. Password to authenticate with at the proxy server.
360 user;;
364 user;;
361 Optional. User name to authenticate with at the proxy server.
365 Optional. User name to authenticate with at the proxy server.
362
366
363 smtp::
367 smtp::
364 Configuration for extensions that need to send email messages.
368 Configuration for extensions that need to send email messages.
365 host;;
369 host;;
366 Host name of mail server, e.g. "mail.example.com".
370 Host name of mail server, e.g. "mail.example.com".
367 port;;
371 port;;
368 Optional. Port to connect to on mail server. Default: 25.
372 Optional. Port to connect to on mail server. Default: 25.
369 tls;;
373 tls;;
370 Optional. Whether to connect to mail server using TLS. True or
374 Optional. Whether to connect to mail server using TLS. True or
371 False. Default: False.
375 False. Default: False.
372 username;;
376 username;;
373 Optional. User name to authenticate to SMTP server with.
377 Optional. User name to authenticate to SMTP server with.
374 If username is specified, password must also be specified.
378 If username is specified, password must also be specified.
375 Default: none.
379 Default: none.
376 password;;
380 password;;
377 Optional. Password to authenticate to SMTP server with.
381 Optional. Password to authenticate to SMTP server with.
378 If username is specified, password must also be specified.
382 If username is specified, password must also be specified.
379 Default: none.
383 Default: none.
380 local_hostname;;
384 local_hostname;;
381 Optional. It's the hostname that the sender can use to identify itself
385 Optional. It's the hostname that the sender can use to identify itself
382 to the MTA.
386 to the MTA.
383
387
384 paths::
388 paths::
385 Assigns symbolic names to repositories. The left side is the
389 Assigns symbolic names to repositories. The left side is the
386 symbolic name, and the right gives the directory or URL that is the
390 symbolic name, and the right gives the directory or URL that is the
387 location of the repository. Default paths can be declared by
391 location of the repository. Default paths can be declared by
388 setting the following entries.
392 setting the following entries.
389 default;;
393 default;;
390 Directory or URL to use when pulling if no source is specified.
394 Directory or URL to use when pulling if no source is specified.
391 Default is set to repository from which the current repository
395 Default is set to repository from which the current repository
392 was cloned.
396 was cloned.
393 default-push;;
397 default-push;;
394 Optional. Directory or URL to use when pushing if no destination
398 Optional. Directory or URL to use when pushing if no destination
395 is specified.
399 is specified.
396
400
397 server::
401 server::
398 Controls generic server settings.
402 Controls generic server settings.
399 uncompressed;;
403 uncompressed;;
400 Whether to allow clients to clone a repo using the uncompressed
404 Whether to allow clients to clone a repo using the uncompressed
401 streaming protocol. This transfers about 40% more data than a
405 streaming protocol. This transfers about 40% more data than a
402 regular clone, but uses less memory and CPU on both server and
406 regular clone, but uses less memory and CPU on both server and
403 client. Over a LAN (100Mbps or better) or a very fast WAN, an
407 client. Over a LAN (100Mbps or better) or a very fast WAN, an
404 uncompressed streaming clone is a lot faster (~10x) than a regular
408 uncompressed streaming clone is a lot faster (~10x) than a regular
405 clone. Over most WAN connections (anything slower than about
409 clone. Over most WAN connections (anything slower than about
406 6Mbps), uncompressed streaming is slower, because of the extra
410 6Mbps), uncompressed streaming is slower, because of the extra
407 data transfer overhead. Default is False.
411 data transfer overhead. Default is False.
408
412
409 trusted::
413 trusted::
410 For security reasons, Mercurial will not use the settings in
414 For security reasons, Mercurial will not use the settings in
411 the .hg/hgrc file from a repository if it doesn't belong to a
415 the .hg/hgrc file from a repository if it doesn't belong to a
412 trusted user or to a trusted group. The main exception is the
416 trusted user or to a trusted group. The main exception is the
413 web interface, which automatically uses some safe settings, since
417 web interface, which automatically uses some safe settings, since
414 it's common to serve repositories from different users.
418 it's common to serve repositories from different users.
415
419
416 This section specifies what users and groups are trusted. The
420 This section specifies what users and groups are trusted. The
417 current user is always trusted. To trust everybody, list a user
421 current user is always trusted. To trust everybody, list a user
418 or a group with name "*".
422 or a group with name "*".
419
423
420 users;;
424 users;;
421 Comma-separated list of trusted users.
425 Comma-separated list of trusted users.
422 groups;;
426 groups;;
423 Comma-separated list of trusted groups.
427 Comma-separated list of trusted groups.
424
428
425 ui::
429 ui::
426 User interface controls.
430 User interface controls.
427 debug;;
431 debug;;
428 Print debugging information. True or False. Default is False.
432 Print debugging information. True or False. Default is False.
429 editor;;
433 editor;;
430 The editor to use during a commit. Default is $EDITOR or "vi".
434 The editor to use during a commit. Default is $EDITOR or "vi".
431 fallbackencoding;;
435 fallbackencoding;;
432 Encoding to try if it's not possible to decode the changelog using
436 Encoding to try if it's not possible to decode the changelog using
433 UTF-8. Default is ISO-8859-1.
437 UTF-8. Default is ISO-8859-1.
434 ignore;;
438 ignore;;
435 A file to read per-user ignore patterns from. This file should be in
439 A file to read per-user ignore patterns from. This file should be in
436 the same format as a repository-wide .hgignore file. This option
440 the same format as a repository-wide .hgignore file. This option
437 supports hook syntax, so if you want to specify multiple ignore
441 supports hook syntax, so if you want to specify multiple ignore
438 files, you can do so by setting something like
442 files, you can do so by setting something like
439 "ignore.other = ~/.hgignore2". For details of the ignore file
443 "ignore.other = ~/.hgignore2". For details of the ignore file
440 format, see the hgignore(5) man page.
444 format, see the hgignore(5) man page.
441 interactive;;
445 interactive;;
442 Allow to prompt the user. True or False. Default is True.
446 Allow to prompt the user. True or False. Default is True.
443 logtemplate;;
447 logtemplate;;
444 Template string for commands that print changesets.
448 Template string for commands that print changesets.
445 merge;;
449 merge;;
446 The conflict resolution program to use during a manual merge.
450 The conflict resolution program to use during a manual merge.
447 Default is "hgmerge".
451 Default is "hgmerge".
448 patch;;
452 patch;;
449 command to use to apply patches. Look for 'gpatch' or 'patch' in PATH if
453 command to use to apply patches. Look for 'gpatch' or 'patch' in PATH if
450 unset.
454 unset.
451 quiet;;
455 quiet;;
452 Reduce the amount of output printed. True or False. Default is False.
456 Reduce the amount of output printed. True or False. Default is False.
453 remotecmd;;
457 remotecmd;;
454 remote command to use for clone/push/pull operations. Default is 'hg'.
458 remote command to use for clone/push/pull operations. Default is 'hg'.
455 report_untrusted;;
459 report_untrusted;;
456 Warn if a .hg/hgrc file is ignored due to not being owned by a
460 Warn if a .hg/hgrc file is ignored due to not being owned by a
457 trusted user or group. True or False. Default is True.
461 trusted user or group. True or False. Default is True.
458 slash;;
462 slash;;
459 Display paths using a slash ("/") as the path separator. This only
463 Display paths using a slash ("/") as the path separator. This only
460 makes a difference on systems where the default path separator is not
464 makes a difference on systems where the default path separator is not
461 the slash character (e.g. Windows uses the backslash character ("\")).
465 the slash character (e.g. Windows uses the backslash character ("\")).
462 Default is False.
466 Default is False.
463 ssh;;
467 ssh;;
464 command to use for SSH connections. Default is 'ssh'.
468 command to use for SSH connections. Default is 'ssh'.
465 strict;;
469 strict;;
466 Require exact command names, instead of allowing unambiguous
470 Require exact command names, instead of allowing unambiguous
467 abbreviations. True or False. Default is False.
471 abbreviations. True or False. Default is False.
468 style;;
472 style;;
469 Name of style to use for command output.
473 Name of style to use for command output.
470 timeout;;
474 timeout;;
471 The timeout used when a lock is held (in seconds), a negative value
475 The timeout used when a lock is held (in seconds), a negative value
472 means no timeout. Default is 600.
476 means no timeout. Default is 600.
473 username;;
477 username;;
474 The committer of a changeset created when running "commit".
478 The committer of a changeset created when running "commit".
475 Typically a person's name and email address, e.g. "Fred Widget
479 Typically a person's name and email address, e.g. "Fred Widget
476 <fred@example.com>". Default is $EMAIL or username@hostname.
480 <fred@example.com>". Default is $EMAIL or username@hostname.
477 If the username in hgrc is empty, it has to be specified manually or
481 If the username in hgrc is empty, it has to be specified manually or
478 in a different hgrc file (e.g. $HOME/.hgrc, if the admin set "username ="
482 in a different hgrc file (e.g. $HOME/.hgrc, if the admin set "username ="
479 in the system hgrc).
483 in the system hgrc).
480 verbose;;
484 verbose;;
481 Increase the amount of output printed. True or False. Default is False.
485 Increase the amount of output printed. True or False. Default is False.
482
486
483
487
484 web::
488 web::
485 Web interface configuration.
489 Web interface configuration.
486 accesslog;;
490 accesslog;;
487 Where to output the access log. Default is stdout.
491 Where to output the access log. Default is stdout.
488 address;;
492 address;;
489 Interface address to bind to. Default is all.
493 Interface address to bind to. Default is all.
490 allow_archive;;
494 allow_archive;;
491 List of archive format (bz2, gz, zip) allowed for downloading.
495 List of archive format (bz2, gz, zip) allowed for downloading.
492 Default is empty.
496 Default is empty.
493 allowbz2;;
497 allowbz2;;
494 (DEPRECATED) Whether to allow .tar.bz2 downloading of repo revisions.
498 (DEPRECATED) Whether to allow .tar.bz2 downloading of repo revisions.
495 Default is false.
499 Default is false.
496 allowgz;;
500 allowgz;;
497 (DEPRECATED) Whether to allow .tar.gz downloading of repo revisions.
501 (DEPRECATED) Whether to allow .tar.gz downloading of repo revisions.
498 Default is false.
502 Default is false.
499 allowpull;;
503 allowpull;;
500 Whether to allow pulling from the repository. Default is true.
504 Whether to allow pulling from the repository. Default is true.
501 allow_push;;
505 allow_push;;
502 Whether to allow pushing to the repository. If empty or not set,
506 Whether to allow pushing to the repository. If empty or not set,
503 push is not allowed. If the special value "*", any remote user
507 push is not allowed. If the special value "*", any remote user
504 can push, including unauthenticated users. Otherwise, the remote
508 can push, including unauthenticated users. Otherwise, the remote
505 user must have been authenticated, and the authenticated user name
509 user must have been authenticated, and the authenticated user name
506 must be present in this list (separated by whitespace or ",").
510 must be present in this list (separated by whitespace or ",").
507 The contents of the allow_push list are examined after the
511 The contents of the allow_push list are examined after the
508 deny_push list.
512 deny_push list.
509 allowzip;;
513 allowzip;;
510 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
514 (DEPRECATED) Whether to allow .zip downloading of repo revisions.
511 Default is false. This feature creates temporary files.
515 Default is false. This feature creates temporary files.
512 baseurl;;
516 baseurl;;
513 Base URL to use when publishing URLs in other locations, so
517 Base URL to use when publishing URLs in other locations, so
514 third-party tools like email notification hooks can construct URLs.
518 third-party tools like email notification hooks can construct URLs.
515 Example: "http://hgserver/repos/"
519 Example: "http://hgserver/repos/"
516 contact;;
520 contact;;
517 Name or email address of the person in charge of the repository.
521 Name or email address of the person in charge of the repository.
518 Default is "unknown".
522 Default is "unknown".
519 deny_push;;
523 deny_push;;
520 Whether to deny pushing to the repository. If empty or not set,
524 Whether to deny pushing to the repository. If empty or not set,
521 push is not denied. If the special value "*", all remote users
525 push is not denied. If the special value "*", all remote users
522 are denied push. Otherwise, unauthenticated users are all denied,
526 are denied push. Otherwise, unauthenticated users are all denied,
523 and any authenticated user name present in this list (separated by
527 and any authenticated user name present in this list (separated by
524 whitespace or ",") is also denied. The contents of the deny_push
528 whitespace or ",") is also denied. The contents of the deny_push
525 list are examined before the allow_push list.
529 list are examined before the allow_push list.
526 description;;
530 description;;
527 Textual description of the repository's purpose or contents.
531 Textual description of the repository's purpose or contents.
528 Default is "unknown".
532 Default is "unknown".
529 encoding;;
533 encoding;;
530 Character encoding name.
534 Character encoding name.
531 Example: "UTF-8"
535 Example: "UTF-8"
532 errorlog;;
536 errorlog;;
533 Where to output the error log. Default is stderr.
537 Where to output the error log. Default is stderr.
534 hidden;;
538 hidden;;
535 Whether to hide the repository in the hgwebdir index. Default is false.
539 Whether to hide the repository in the hgwebdir index. Default is false.
536 ipv6;;
540 ipv6;;
537 Whether to use IPv6. Default is false.
541 Whether to use IPv6. Default is false.
538 name;;
542 name;;
539 Repository name to use in the web interface. Default is current
543 Repository name to use in the web interface. Default is current
540 working directory.
544 working directory.
541 maxchanges;;
545 maxchanges;;
542 Maximum number of changes to list on the changelog. Default is 10.
546 Maximum number of changes to list on the changelog. Default is 10.
543 maxfiles;;
547 maxfiles;;
544 Maximum number of files to list per changeset. Default is 10.
548 Maximum number of files to list per changeset. Default is 10.
545 port;;
549 port;;
546 Port to listen on. Default is 8000.
550 Port to listen on. Default is 8000.
547 push_ssl;;
551 push_ssl;;
548 Whether to require that inbound pushes be transported over SSL to
552 Whether to require that inbound pushes be transported over SSL to
549 prevent password sniffing. Default is true.
553 prevent password sniffing. Default is true.
550 staticurl;;
554 staticurl;;
551 Base URL to use for static files. If unset, static files (e.g.
555 Base URL to use for static files. If unset, static files (e.g.
552 the hgicon.png favicon) will be served by the CGI script itself.
556 the hgicon.png favicon) will be served by the CGI script itself.
553 Use this setting to serve them directly with the HTTP server.
557 Use this setting to serve them directly with the HTTP server.
554 Example: "http://hgserver/static/"
558 Example: "http://hgserver/static/"
555 stripes;;
559 stripes;;
556 How many lines a "zebra stripe" should span in multiline output.
560 How many lines a "zebra stripe" should span in multiline output.
557 Default is 1; set to 0 to disable.
561 Default is 1; set to 0 to disable.
558 style;;
562 style;;
559 Which template map style to use.
563 Which template map style to use.
560 templates;;
564 templates;;
561 Where to find the HTML templates. Default is install path.
565 Where to find the HTML templates. Default is install path.
562
566
563
567
564 AUTHOR
568 AUTHOR
565 ------
569 ------
566 Bryan O'Sullivan <bos@serpentine.com>.
570 Bryan O'Sullivan <bos@serpentine.com>.
567
571
568 Mercurial was written by Matt Mackall <mpm@selenic.com>.
572 Mercurial was written by Matt Mackall <mpm@selenic.com>.
569
573
570 SEE ALSO
574 SEE ALSO
571 --------
575 --------
572 hg(1), hgignore(5)
576 hg(1), hgignore(5)
573
577
574 COPYING
578 COPYING
575 -------
579 -------
576 This manual page is copyright 2005 Bryan O'Sullivan.
580 This manual page is copyright 2005 Bryan O'Sullivan.
577 Mercurial is copyright 2005-2007 Matt Mackall.
581 Mercurial is copyright 2005-2007 Matt Mackall.
578 Free use of this software is granted under the terms of the GNU General
582 Free use of this software is granted under the terms of the GNU General
579 Public License (GPL).
583 Public License (GPL).
@@ -1,310 +1,325
1 # util_win32.py - utility functions that use win32 API
1 # util_win32.py - utility functions that use win32 API
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
4 # Copyright 2006 Vadim Gelfer <vadim.gelfer@gmail.com>
5 #
5 #
6 # This software may be used and distributed according to the terms of
6 # This software may be used and distributed according to the terms of
7 # the GNU General Public License, incorporated herein by reference.
7 # the GNU General Public License, incorporated herein by reference.
8
8
9 # Mark Hammond's win32all package allows better functionality on
9 # Mark Hammond's win32all package allows better functionality on
10 # Windows. this module overrides definitions in util.py. if not
10 # Windows. this module overrides definitions in util.py. if not
11 # available, import of this module will fail, and generic code will be
11 # available, import of this module will fail, and generic code will be
12 # used.
12 # used.
13
13
14 import win32api
14 import win32api
15
15
16 from i18n import _
16 from i18n import _
17 import errno, os, pywintypes, win32con, win32file, win32process
17 import errno, os, pywintypes, win32con, win32file, win32process
18 import cStringIO, winerror
18 import cStringIO, winerror
19 import osutil
19 from win32com.shell import shell,shellcon
20 from win32com.shell import shell,shellcon
20
21
21 class WinError:
22 class WinError:
22 winerror_map = {
23 winerror_map = {
23 winerror.ERROR_ACCESS_DENIED: errno.EACCES,
24 winerror.ERROR_ACCESS_DENIED: errno.EACCES,
24 winerror.ERROR_ACCOUNT_DISABLED: errno.EACCES,
25 winerror.ERROR_ACCOUNT_DISABLED: errno.EACCES,
25 winerror.ERROR_ACCOUNT_RESTRICTION: errno.EACCES,
26 winerror.ERROR_ACCOUNT_RESTRICTION: errno.EACCES,
26 winerror.ERROR_ALREADY_ASSIGNED: errno.EBUSY,
27 winerror.ERROR_ALREADY_ASSIGNED: errno.EBUSY,
27 winerror.ERROR_ALREADY_EXISTS: errno.EEXIST,
28 winerror.ERROR_ALREADY_EXISTS: errno.EEXIST,
28 winerror.ERROR_ARITHMETIC_OVERFLOW: errno.ERANGE,
29 winerror.ERROR_ARITHMETIC_OVERFLOW: errno.ERANGE,
29 winerror.ERROR_BAD_COMMAND: errno.EIO,
30 winerror.ERROR_BAD_COMMAND: errno.EIO,
30 winerror.ERROR_BAD_DEVICE: errno.ENODEV,
31 winerror.ERROR_BAD_DEVICE: errno.ENODEV,
31 winerror.ERROR_BAD_DRIVER_LEVEL: errno.ENXIO,
32 winerror.ERROR_BAD_DRIVER_LEVEL: errno.ENXIO,
32 winerror.ERROR_BAD_EXE_FORMAT: errno.ENOEXEC,
33 winerror.ERROR_BAD_EXE_FORMAT: errno.ENOEXEC,
33 winerror.ERROR_BAD_FORMAT: errno.ENOEXEC,
34 winerror.ERROR_BAD_FORMAT: errno.ENOEXEC,
34 winerror.ERROR_BAD_LENGTH: errno.EINVAL,
35 winerror.ERROR_BAD_LENGTH: errno.EINVAL,
35 winerror.ERROR_BAD_PATHNAME: errno.ENOENT,
36 winerror.ERROR_BAD_PATHNAME: errno.ENOENT,
36 winerror.ERROR_BAD_PIPE: errno.EPIPE,
37 winerror.ERROR_BAD_PIPE: errno.EPIPE,
37 winerror.ERROR_BAD_UNIT: errno.ENODEV,
38 winerror.ERROR_BAD_UNIT: errno.ENODEV,
38 winerror.ERROR_BAD_USERNAME: errno.EINVAL,
39 winerror.ERROR_BAD_USERNAME: errno.EINVAL,
39 winerror.ERROR_BROKEN_PIPE: errno.EPIPE,
40 winerror.ERROR_BROKEN_PIPE: errno.EPIPE,
40 winerror.ERROR_BUFFER_OVERFLOW: errno.ENAMETOOLONG,
41 winerror.ERROR_BUFFER_OVERFLOW: errno.ENAMETOOLONG,
41 winerror.ERROR_BUSY: errno.EBUSY,
42 winerror.ERROR_BUSY: errno.EBUSY,
42 winerror.ERROR_BUSY_DRIVE: errno.EBUSY,
43 winerror.ERROR_BUSY_DRIVE: errno.EBUSY,
43 winerror.ERROR_CALL_NOT_IMPLEMENTED: errno.ENOSYS,
44 winerror.ERROR_CALL_NOT_IMPLEMENTED: errno.ENOSYS,
44 winerror.ERROR_CANNOT_MAKE: errno.EACCES,
45 winerror.ERROR_CANNOT_MAKE: errno.EACCES,
45 winerror.ERROR_CANTOPEN: errno.EIO,
46 winerror.ERROR_CANTOPEN: errno.EIO,
46 winerror.ERROR_CANTREAD: errno.EIO,
47 winerror.ERROR_CANTREAD: errno.EIO,
47 winerror.ERROR_CANTWRITE: errno.EIO,
48 winerror.ERROR_CANTWRITE: errno.EIO,
48 winerror.ERROR_CRC: errno.EIO,
49 winerror.ERROR_CRC: errno.EIO,
49 winerror.ERROR_CURRENT_DIRECTORY: errno.EACCES,
50 winerror.ERROR_CURRENT_DIRECTORY: errno.EACCES,
50 winerror.ERROR_DEVICE_IN_USE: errno.EBUSY,
51 winerror.ERROR_DEVICE_IN_USE: errno.EBUSY,
51 winerror.ERROR_DEV_NOT_EXIST: errno.ENODEV,
52 winerror.ERROR_DEV_NOT_EXIST: errno.ENODEV,
52 winerror.ERROR_DIRECTORY: errno.EINVAL,
53 winerror.ERROR_DIRECTORY: errno.EINVAL,
53 winerror.ERROR_DIR_NOT_EMPTY: errno.ENOTEMPTY,
54 winerror.ERROR_DIR_NOT_EMPTY: errno.ENOTEMPTY,
54 winerror.ERROR_DISK_CHANGE: errno.EIO,
55 winerror.ERROR_DISK_CHANGE: errno.EIO,
55 winerror.ERROR_DISK_FULL: errno.ENOSPC,
56 winerror.ERROR_DISK_FULL: errno.ENOSPC,
56 winerror.ERROR_DRIVE_LOCKED: errno.EBUSY,
57 winerror.ERROR_DRIVE_LOCKED: errno.EBUSY,
57 winerror.ERROR_ENVVAR_NOT_FOUND: errno.EINVAL,
58 winerror.ERROR_ENVVAR_NOT_FOUND: errno.EINVAL,
58 winerror.ERROR_EXE_MARKED_INVALID: errno.ENOEXEC,
59 winerror.ERROR_EXE_MARKED_INVALID: errno.ENOEXEC,
59 winerror.ERROR_FILENAME_EXCED_RANGE: errno.ENAMETOOLONG,
60 winerror.ERROR_FILENAME_EXCED_RANGE: errno.ENAMETOOLONG,
60 winerror.ERROR_FILE_EXISTS: errno.EEXIST,
61 winerror.ERROR_FILE_EXISTS: errno.EEXIST,
61 winerror.ERROR_FILE_INVALID: errno.ENODEV,
62 winerror.ERROR_FILE_INVALID: errno.ENODEV,
62 winerror.ERROR_FILE_NOT_FOUND: errno.ENOENT,
63 winerror.ERROR_FILE_NOT_FOUND: errno.ENOENT,
63 winerror.ERROR_GEN_FAILURE: errno.EIO,
64 winerror.ERROR_GEN_FAILURE: errno.EIO,
64 winerror.ERROR_HANDLE_DISK_FULL: errno.ENOSPC,
65 winerror.ERROR_HANDLE_DISK_FULL: errno.ENOSPC,
65 winerror.ERROR_INSUFFICIENT_BUFFER: errno.ENOMEM,
66 winerror.ERROR_INSUFFICIENT_BUFFER: errno.ENOMEM,
66 winerror.ERROR_INVALID_ACCESS: errno.EACCES,
67 winerror.ERROR_INVALID_ACCESS: errno.EACCES,
67 winerror.ERROR_INVALID_ADDRESS: errno.EFAULT,
68 winerror.ERROR_INVALID_ADDRESS: errno.EFAULT,
68 winerror.ERROR_INVALID_BLOCK: errno.EFAULT,
69 winerror.ERROR_INVALID_BLOCK: errno.EFAULT,
69 winerror.ERROR_INVALID_DATA: errno.EINVAL,
70 winerror.ERROR_INVALID_DATA: errno.EINVAL,
70 winerror.ERROR_INVALID_DRIVE: errno.ENODEV,
71 winerror.ERROR_INVALID_DRIVE: errno.ENODEV,
71 winerror.ERROR_INVALID_EXE_SIGNATURE: errno.ENOEXEC,
72 winerror.ERROR_INVALID_EXE_SIGNATURE: errno.ENOEXEC,
72 winerror.ERROR_INVALID_FLAGS: errno.EINVAL,
73 winerror.ERROR_INVALID_FLAGS: errno.EINVAL,
73 winerror.ERROR_INVALID_FUNCTION: errno.ENOSYS,
74 winerror.ERROR_INVALID_FUNCTION: errno.ENOSYS,
74 winerror.ERROR_INVALID_HANDLE: errno.EBADF,
75 winerror.ERROR_INVALID_HANDLE: errno.EBADF,
75 winerror.ERROR_INVALID_LOGON_HOURS: errno.EACCES,
76 winerror.ERROR_INVALID_LOGON_HOURS: errno.EACCES,
76 winerror.ERROR_INVALID_NAME: errno.EINVAL,
77 winerror.ERROR_INVALID_NAME: errno.EINVAL,
77 winerror.ERROR_INVALID_OWNER: errno.EINVAL,
78 winerror.ERROR_INVALID_OWNER: errno.EINVAL,
78 winerror.ERROR_INVALID_PARAMETER: errno.EINVAL,
79 winerror.ERROR_INVALID_PARAMETER: errno.EINVAL,
79 winerror.ERROR_INVALID_PASSWORD: errno.EPERM,
80 winerror.ERROR_INVALID_PASSWORD: errno.EPERM,
80 winerror.ERROR_INVALID_PRIMARY_GROUP: errno.EINVAL,
81 winerror.ERROR_INVALID_PRIMARY_GROUP: errno.EINVAL,
81 winerror.ERROR_INVALID_SIGNAL_NUMBER: errno.EINVAL,
82 winerror.ERROR_INVALID_SIGNAL_NUMBER: errno.EINVAL,
82 winerror.ERROR_INVALID_TARGET_HANDLE: errno.EIO,
83 winerror.ERROR_INVALID_TARGET_HANDLE: errno.EIO,
83 winerror.ERROR_INVALID_WORKSTATION: errno.EACCES,
84 winerror.ERROR_INVALID_WORKSTATION: errno.EACCES,
84 winerror.ERROR_IO_DEVICE: errno.EIO,
85 winerror.ERROR_IO_DEVICE: errno.EIO,
85 winerror.ERROR_IO_INCOMPLETE: errno.EINTR,
86 winerror.ERROR_IO_INCOMPLETE: errno.EINTR,
86 winerror.ERROR_LOCKED: errno.EBUSY,
87 winerror.ERROR_LOCKED: errno.EBUSY,
87 winerror.ERROR_LOCK_VIOLATION: errno.EACCES,
88 winerror.ERROR_LOCK_VIOLATION: errno.EACCES,
88 winerror.ERROR_LOGON_FAILURE: errno.EACCES,
89 winerror.ERROR_LOGON_FAILURE: errno.EACCES,
89 winerror.ERROR_MAPPED_ALIGNMENT: errno.EINVAL,
90 winerror.ERROR_MAPPED_ALIGNMENT: errno.EINVAL,
90 winerror.ERROR_META_EXPANSION_TOO_LONG: errno.E2BIG,
91 winerror.ERROR_META_EXPANSION_TOO_LONG: errno.E2BIG,
91 winerror.ERROR_MORE_DATA: errno.EPIPE,
92 winerror.ERROR_MORE_DATA: errno.EPIPE,
92 winerror.ERROR_NEGATIVE_SEEK: errno.ESPIPE,
93 winerror.ERROR_NEGATIVE_SEEK: errno.ESPIPE,
93 winerror.ERROR_NOACCESS: errno.EFAULT,
94 winerror.ERROR_NOACCESS: errno.EFAULT,
94 winerror.ERROR_NONE_MAPPED: errno.EINVAL,
95 winerror.ERROR_NONE_MAPPED: errno.EINVAL,
95 winerror.ERROR_NOT_ENOUGH_MEMORY: errno.ENOMEM,
96 winerror.ERROR_NOT_ENOUGH_MEMORY: errno.ENOMEM,
96 winerror.ERROR_NOT_READY: errno.EAGAIN,
97 winerror.ERROR_NOT_READY: errno.EAGAIN,
97 winerror.ERROR_NOT_SAME_DEVICE: errno.EXDEV,
98 winerror.ERROR_NOT_SAME_DEVICE: errno.EXDEV,
98 winerror.ERROR_NO_DATA: errno.EPIPE,
99 winerror.ERROR_NO_DATA: errno.EPIPE,
99 winerror.ERROR_NO_MORE_SEARCH_HANDLES: errno.EIO,
100 winerror.ERROR_NO_MORE_SEARCH_HANDLES: errno.EIO,
100 winerror.ERROR_NO_PROC_SLOTS: errno.EAGAIN,
101 winerror.ERROR_NO_PROC_SLOTS: errno.EAGAIN,
101 winerror.ERROR_NO_SUCH_PRIVILEGE: errno.EACCES,
102 winerror.ERROR_NO_SUCH_PRIVILEGE: errno.EACCES,
102 winerror.ERROR_OPEN_FAILED: errno.EIO,
103 winerror.ERROR_OPEN_FAILED: errno.EIO,
103 winerror.ERROR_OPEN_FILES: errno.EBUSY,
104 winerror.ERROR_OPEN_FILES: errno.EBUSY,
104 winerror.ERROR_OPERATION_ABORTED: errno.EINTR,
105 winerror.ERROR_OPERATION_ABORTED: errno.EINTR,
105 winerror.ERROR_OUTOFMEMORY: errno.ENOMEM,
106 winerror.ERROR_OUTOFMEMORY: errno.ENOMEM,
106 winerror.ERROR_PASSWORD_EXPIRED: errno.EACCES,
107 winerror.ERROR_PASSWORD_EXPIRED: errno.EACCES,
107 winerror.ERROR_PATH_BUSY: errno.EBUSY,
108 winerror.ERROR_PATH_BUSY: errno.EBUSY,
108 winerror.ERROR_PATH_NOT_FOUND: errno.ENOENT,
109 winerror.ERROR_PATH_NOT_FOUND: errno.ENOENT,
109 winerror.ERROR_PIPE_BUSY: errno.EBUSY,
110 winerror.ERROR_PIPE_BUSY: errno.EBUSY,
110 winerror.ERROR_PIPE_CONNECTED: errno.EPIPE,
111 winerror.ERROR_PIPE_CONNECTED: errno.EPIPE,
111 winerror.ERROR_PIPE_LISTENING: errno.EPIPE,
112 winerror.ERROR_PIPE_LISTENING: errno.EPIPE,
112 winerror.ERROR_PIPE_NOT_CONNECTED: errno.EPIPE,
113 winerror.ERROR_PIPE_NOT_CONNECTED: errno.EPIPE,
113 winerror.ERROR_PRIVILEGE_NOT_HELD: errno.EACCES,
114 winerror.ERROR_PRIVILEGE_NOT_HELD: errno.EACCES,
114 winerror.ERROR_READ_FAULT: errno.EIO,
115 winerror.ERROR_READ_FAULT: errno.EIO,
115 winerror.ERROR_SEEK: errno.EIO,
116 winerror.ERROR_SEEK: errno.EIO,
116 winerror.ERROR_SEEK_ON_DEVICE: errno.ESPIPE,
117 winerror.ERROR_SEEK_ON_DEVICE: errno.ESPIPE,
117 winerror.ERROR_SHARING_BUFFER_EXCEEDED: errno.ENFILE,
118 winerror.ERROR_SHARING_BUFFER_EXCEEDED: errno.ENFILE,
118 winerror.ERROR_SHARING_VIOLATION: errno.EACCES,
119 winerror.ERROR_SHARING_VIOLATION: errno.EACCES,
119 winerror.ERROR_STACK_OVERFLOW: errno.ENOMEM,
120 winerror.ERROR_STACK_OVERFLOW: errno.ENOMEM,
120 winerror.ERROR_SWAPERROR: errno.ENOENT,
121 winerror.ERROR_SWAPERROR: errno.ENOENT,
121 winerror.ERROR_TOO_MANY_MODULES: errno.EMFILE,
122 winerror.ERROR_TOO_MANY_MODULES: errno.EMFILE,
122 winerror.ERROR_TOO_MANY_OPEN_FILES: errno.EMFILE,
123 winerror.ERROR_TOO_MANY_OPEN_FILES: errno.EMFILE,
123 winerror.ERROR_UNRECOGNIZED_MEDIA: errno.ENXIO,
124 winerror.ERROR_UNRECOGNIZED_MEDIA: errno.ENXIO,
124 winerror.ERROR_UNRECOGNIZED_VOLUME: errno.ENODEV,
125 winerror.ERROR_UNRECOGNIZED_VOLUME: errno.ENODEV,
125 winerror.ERROR_WAIT_NO_CHILDREN: errno.ECHILD,
126 winerror.ERROR_WAIT_NO_CHILDREN: errno.ECHILD,
126 winerror.ERROR_WRITE_FAULT: errno.EIO,
127 winerror.ERROR_WRITE_FAULT: errno.EIO,
127 winerror.ERROR_WRITE_PROTECT: errno.EROFS,
128 winerror.ERROR_WRITE_PROTECT: errno.EROFS,
128 }
129 }
129
130
130 def __init__(self, err):
131 def __init__(self, err):
131 self.win_errno, self.win_function, self.win_strerror = err
132 self.win_errno, self.win_function, self.win_strerror = err
132 if self.win_strerror.endswith('.'):
133 if self.win_strerror.endswith('.'):
133 self.win_strerror = self.win_strerror[:-1]
134 self.win_strerror = self.win_strerror[:-1]
134
135
135 class WinIOError(WinError, IOError):
136 class WinIOError(WinError, IOError):
136 def __init__(self, err, filename=None):
137 def __init__(self, err, filename=None):
137 WinError.__init__(self, err)
138 WinError.__init__(self, err)
138 IOError.__init__(self, self.winerror_map.get(self.win_errno, 0),
139 IOError.__init__(self, self.winerror_map.get(self.win_errno, 0),
139 self.win_strerror)
140 self.win_strerror)
140 self.filename = filename
141 self.filename = filename
141
142
142 class WinOSError(WinError, OSError):
143 class WinOSError(WinError, OSError):
143 def __init__(self, err):
144 def __init__(self, err):
144 WinError.__init__(self, err)
145 WinError.__init__(self, err)
145 OSError.__init__(self, self.winerror_map.get(self.win_errno, 0),
146 OSError.__init__(self, self.winerror_map.get(self.win_errno, 0),
146 self.win_strerror)
147 self.win_strerror)
147
148
148 def os_link(src, dst):
149 def os_link(src, dst):
149 # NB will only succeed on NTFS
150 # NB will only succeed on NTFS
150 try:
151 try:
151 win32file.CreateHardLink(dst, src)
152 win32file.CreateHardLink(dst, src)
152 except pywintypes.error, details:
153 except pywintypes.error, details:
153 raise WinOSError(details)
154 raise WinOSError(details)
154
155
155 def nlinks(pathname):
156 def nlinks(pathname):
156 """Return number of hardlinks for the given file."""
157 """Return number of hardlinks for the given file."""
157 try:
158 try:
158 fh = win32file.CreateFile(pathname,
159 fh = win32file.CreateFile(pathname,
159 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
160 win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
160 None, win32file.OPEN_EXISTING, 0, None)
161 None, win32file.OPEN_EXISTING, 0, None)
161 res = win32file.GetFileInformationByHandle(fh)
162 res = win32file.GetFileInformationByHandle(fh)
162 fh.Close()
163 fh.Close()
163 return res[7]
164 return res[7]
164 except pywintypes.error:
165 except pywintypes.error:
165 return os.lstat(pathname).st_nlink
166 return os.lstat(pathname).st_nlink
166
167
167 def testpid(pid):
168 def testpid(pid):
168 '''return True if pid is still running or unable to
169 '''return True if pid is still running or unable to
169 determine, False otherwise'''
170 determine, False otherwise'''
170 try:
171 try:
171 handle = win32api.OpenProcess(
172 handle = win32api.OpenProcess(
172 win32con.PROCESS_QUERY_INFORMATION, False, pid)
173 win32con.PROCESS_QUERY_INFORMATION, False, pid)
173 if handle:
174 if handle:
174 status = win32process.GetExitCodeProcess(handle)
175 status = win32process.GetExitCodeProcess(handle)
175 return status == win32con.STILL_ACTIVE
176 return status == win32con.STILL_ACTIVE
176 except pywintypes.error, details:
177 except pywintypes.error, details:
177 return details[0] != winerror.ERROR_INVALID_PARAMETER
178 return details[0] != winerror.ERROR_INVALID_PARAMETER
178 return True
179 return True
179
180
180 def system_rcpath_win32():
181 def system_rcpath_win32():
181 '''return default os-specific hgrc search path'''
182 '''return default os-specific hgrc search path'''
183 try:
184 value = win32api.RegQueryValue(
185 win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
186 rcpath = []
187 for p in value.split(os.pathsep):
188 if p.lower().endswith('mercurial.ini'):
189 rcpath.append(p)
190 elif os.path.isdir(p):
191 for f, kind in osutil.listdir(p):
192 if f.endswith('.rc'):
193 rcpath.append(os.path.join(p, f))
194 return rcpath
195 except pywintypes.error:
196 pass
182 proc = win32api.GetCurrentProcess()
197 proc = win32api.GetCurrentProcess()
183 try:
198 try:
184 # This will fail on windows < NT
199 # This will fail on windows < NT
185 filename = win32process.GetModuleFileNameEx(proc, 0)
200 filename = win32process.GetModuleFileNameEx(proc, 0)
186 except:
201 except:
187 filename = win32api.GetModuleFileName(0)
202 filename = win32api.GetModuleFileName(0)
188 return [os.path.join(os.path.dirname(filename), 'mercurial.ini')]
203 return [os.path.join(os.path.dirname(filename), 'mercurial.ini')]
189
204
190 def user_rcpath_win32():
205 def user_rcpath_win32():
191 '''return os-specific hgrc search path to the user dir'''
206 '''return os-specific hgrc search path to the user dir'''
192 userdir = os.path.expanduser('~')
207 userdir = os.path.expanduser('~')
193 if userdir == '~':
208 if userdir == '~':
194 # We are on win < nt: fetch the APPDATA directory location and use
209 # We are on win < nt: fetch the APPDATA directory location and use
195 # the parent directory as the user home dir.
210 # the parent directory as the user home dir.
196 appdir = shell.SHGetPathFromIDList(
211 appdir = shell.SHGetPathFromIDList(
197 shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
212 shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
198 userdir = os.path.dirname(appdir)
213 userdir = os.path.dirname(appdir)
199 return os.path.join(userdir, 'mercurial.ini')
214 return os.path.join(userdir, 'mercurial.ini')
200
215
201 class posixfile_nt(object):
216 class posixfile_nt(object):
202 '''file object with posix-like semantics. on windows, normal
217 '''file object with posix-like semantics. on windows, normal
203 files can not be deleted or renamed if they are open. must open
218 files can not be deleted or renamed if they are open. must open
204 with win32file.FILE_SHARE_DELETE. this flag does not exist on
219 with win32file.FILE_SHARE_DELETE. this flag does not exist on
205 windows < nt, so do not use this class there.'''
220 windows < nt, so do not use this class there.'''
206
221
207 # tried to use win32file._open_osfhandle to pass fd to os.fdopen,
222 # tried to use win32file._open_osfhandle to pass fd to os.fdopen,
208 # but does not work at all. wrap win32 file api instead.
223 # but does not work at all. wrap win32 file api instead.
209
224
210 def __init__(self, name, mode='rb'):
225 def __init__(self, name, mode='rb'):
211 access = 0
226 access = 0
212 if 'r' in mode or '+' in mode:
227 if 'r' in mode or '+' in mode:
213 access |= win32file.GENERIC_READ
228 access |= win32file.GENERIC_READ
214 if 'w' in mode or 'a' in mode or '+' in mode:
229 if 'w' in mode or 'a' in mode or '+' in mode:
215 access |= win32file.GENERIC_WRITE
230 access |= win32file.GENERIC_WRITE
216 if 'r' in mode:
231 if 'r' in mode:
217 creation = win32file.OPEN_EXISTING
232 creation = win32file.OPEN_EXISTING
218 elif 'a' in mode:
233 elif 'a' in mode:
219 creation = win32file.OPEN_ALWAYS
234 creation = win32file.OPEN_ALWAYS
220 else:
235 else:
221 creation = win32file.CREATE_ALWAYS
236 creation = win32file.CREATE_ALWAYS
222 try:
237 try:
223 self.handle = win32file.CreateFile(name,
238 self.handle = win32file.CreateFile(name,
224 access,
239 access,
225 win32file.FILE_SHARE_READ |
240 win32file.FILE_SHARE_READ |
226 win32file.FILE_SHARE_WRITE |
241 win32file.FILE_SHARE_WRITE |
227 win32file.FILE_SHARE_DELETE,
242 win32file.FILE_SHARE_DELETE,
228 None,
243 None,
229 creation,
244 creation,
230 win32file.FILE_ATTRIBUTE_NORMAL,
245 win32file.FILE_ATTRIBUTE_NORMAL,
231 0)
246 0)
232 except pywintypes.error, err:
247 except pywintypes.error, err:
233 raise WinIOError(err, name)
248 raise WinIOError(err, name)
234 self.closed = False
249 self.closed = False
235 self.name = name
250 self.name = name
236 self.mode = mode
251 self.mode = mode
237
252
238 def __iter__(self):
253 def __iter__(self):
239 for line in self.read().splitlines(True):
254 for line in self.read().splitlines(True):
240 yield line
255 yield line
241
256
242 def read(self, count=-1):
257 def read(self, count=-1):
243 try:
258 try:
244 cs = cStringIO.StringIO()
259 cs = cStringIO.StringIO()
245 while count:
260 while count:
246 wincount = int(count)
261 wincount = int(count)
247 if wincount == -1:
262 if wincount == -1:
248 wincount = 1048576
263 wincount = 1048576
249 val, data = win32file.ReadFile(self.handle, wincount)
264 val, data = win32file.ReadFile(self.handle, wincount)
250 if not data: break
265 if not data: break
251 cs.write(data)
266 cs.write(data)
252 if count != -1:
267 if count != -1:
253 count -= len(data)
268 count -= len(data)
254 return cs.getvalue()
269 return cs.getvalue()
255 except pywintypes.error, err:
270 except pywintypes.error, err:
256 raise WinIOError(err)
271 raise WinIOError(err)
257
272
258 def write(self, data):
273 def write(self, data):
259 try:
274 try:
260 if 'a' in self.mode:
275 if 'a' in self.mode:
261 win32file.SetFilePointer(self.handle, 0, win32file.FILE_END)
276 win32file.SetFilePointer(self.handle, 0, win32file.FILE_END)
262 nwrit = 0
277 nwrit = 0
263 while nwrit < len(data):
278 while nwrit < len(data):
264 val, nwrit = win32file.WriteFile(self.handle, data)
279 val, nwrit = win32file.WriteFile(self.handle, data)
265 data = data[nwrit:]
280 data = data[nwrit:]
266 except pywintypes.error, err:
281 except pywintypes.error, err:
267 raise WinIOError(err)
282 raise WinIOError(err)
268
283
269 def seek(self, pos, whence=0):
284 def seek(self, pos, whence=0):
270 try:
285 try:
271 win32file.SetFilePointer(self.handle, int(pos), whence)
286 win32file.SetFilePointer(self.handle, int(pos), whence)
272 except pywintypes.error, err:
287 except pywintypes.error, err:
273 raise WinIOError(err)
288 raise WinIOError(err)
274
289
275 def tell(self):
290 def tell(self):
276 try:
291 try:
277 return win32file.SetFilePointer(self.handle, 0,
292 return win32file.SetFilePointer(self.handle, 0,
278 win32file.FILE_CURRENT)
293 win32file.FILE_CURRENT)
279 except pywintypes.error, err:
294 except pywintypes.error, err:
280 raise WinIOError(err)
295 raise WinIOError(err)
281
296
282 def close(self):
297 def close(self):
283 if not self.closed:
298 if not self.closed:
284 self.handle = None
299 self.handle = None
285 self.closed = True
300 self.closed = True
286
301
287 def flush(self):
302 def flush(self):
288 try:
303 try:
289 win32file.FlushFileBuffers(self.handle)
304 win32file.FlushFileBuffers(self.handle)
290 except pywintypes.error, err:
305 except pywintypes.error, err:
291 raise WinIOError(err)
306 raise WinIOError(err)
292
307
293 def truncate(self, pos=0):
308 def truncate(self, pos=0):
294 try:
309 try:
295 win32file.SetFilePointer(self.handle, int(pos),
310 win32file.SetFilePointer(self.handle, int(pos),
296 win32file.FILE_BEGIN)
311 win32file.FILE_BEGIN)
297 win32file.SetEndOfFile(self.handle)
312 win32file.SetEndOfFile(self.handle)
298 except pywintypes.error, err:
313 except pywintypes.error, err:
299 raise WinIOError(err)
314 raise WinIOError(err)
300
315
301 getuser_fallback = win32api.GetUserName
316 getuser_fallback = win32api.GetUserName
302
317
303 def set_signal_handler_win32():
318 def set_signal_handler_win32():
304 """Register a termination handler for console events including
319 """Register a termination handler for console events including
305 CTRL+C. python signal handlers do not work well with socket
320 CTRL+C. python signal handlers do not work well with socket
306 operations.
321 operations.
307 """
322 """
308 def handler(event):
323 def handler(event):
309 win32process.ExitProcess(1)
324 win32process.ExitProcess(1)
310 win32api.SetConsoleCtrlHandler(handler)
325 win32api.SetConsoleCtrlHandler(handler)
General Comments 0
You need to be logged in to leave comments. Login now