##// END OF EJS Templates
py3: pass str into grp.getgrnam...
Pulkit Goyal -
r41645:587a3c97 default
parent child Browse files
Show More
@@ -1,752 +1,753 b''
1 1 test-abort-checkin.t
2 2 test-absorb-edit-lines.t
3 3 test-absorb-filefixupstate.py
4 4 test-absorb-phase.t
5 5 test-absorb-rename.t
6 6 test-absorb-strip.t
7 7 test-absorb.t
8 test-acl.t
8 9 test-add.t
9 10 test-addremove-similar.t
10 11 test-addremove.t
11 12 test-alias.t
12 13 test-amend-subrepo.t
13 14 test-amend.t
14 15 test-ancestor.py
15 16 test-annotate.py
16 17 test-annotate.t
17 18 test-arbitraryfilectx.t
18 19 test-archive-symlinks.t
19 20 test-archive.t
20 21 test-atomictempfile.py
21 22 test-audit-path.t
22 23 test-audit-subrepo.t
23 24 test-automv.t
24 25 test-backout.t
25 26 test-backwards-remove.t
26 27 test-bad-extension.t
27 28 test-bad-pull.t
28 29 test-basic.t
29 30 test-batching.py
30 31 test-bdiff.py
31 32 test-bheads.t
32 33 test-bisect.t
33 34 test-bisect2.t
34 35 test-bisect3.t
35 36 test-blackbox.t
36 37 test-bookflow.t
37 38 test-bookmarks-current.t
38 39 test-bookmarks-merge.t
39 40 test-bookmarks-pushpull.t
40 41 test-bookmarks-rebase.t
41 42 test-bookmarks-strip.t
42 43 test-bookmarks.t
43 44 test-branch-change.t
44 45 test-branch-option.t
45 46 test-branch-tag-confict.t
46 47 test-branches.t
47 48 test-bugzilla.t
48 49 test-bundle-phases.t
49 50 test-bundle-r.t
50 51 test-bundle-type.t
51 52 test-bundle-vs-outgoing.t
52 53 test-bundle.t
53 54 test-bundle2-exchange.t
54 55 test-bundle2-format.t
55 56 test-bundle2-multiple-changegroups.t
56 57 test-bundle2-pushback.t
57 58 test-bundle2-remote-changegroup.t
58 59 test-cache-abuse.t
59 60 test-cappedreader.py
60 61 test-casecollision-merge.t
61 62 test-casecollision.t
62 63 test-casefolding.t
63 64 test-cat.t
64 65 test-cbor.py
65 66 test-censor.t
66 67 test-changelog-exec.t
67 68 test-check-code.t
68 69 test-check-commit.t
69 70 test-check-config.py
70 71 test-check-config.t
71 72 test-check-execute.t
72 73 test-check-help.t
73 74 test-check-interfaces.py
74 75 test-check-module-imports.t
75 76 test-check-py3-compat.t
76 77 test-check-pyflakes.t
77 78 test-check-pylint.t
78 79 test-check-shbang.t
79 80 test-children.t
80 81 test-churn.t
81 82 test-clone-cgi.t
82 83 test-clone-pull-corruption.t
83 84 test-clone-r.t
84 85 test-clone-uncompressed.t
85 86 test-clone-update-order.t
86 87 test-clone.t
87 88 test-clonebundles.t
88 89 test-close-head.t
89 90 test-commandserver.t
90 91 test-commit-amend.t
91 92 test-commit-interactive.t
92 93 test-commit-multiple.t
93 94 test-commit-unresolved.t
94 95 test-commit.t
95 96 test-committer.t
96 97 test-completion.t
97 98 test-config-env.py
98 99 test-config.t
99 100 test-conflict.t
100 101 test-confused-revert.t
101 102 test-context-metadata.t
102 103 test-context.py
103 104 test-contrib-check-code.t
104 105 test-contrib-check-commit.t
105 106 test-contrib-dumprevlog.t
106 107 test-contrib-perf.t
107 108 test-contrib-relnotes.t
108 109 test-contrib-testparseutil.t
109 110 test-contrib.t
110 111 test-convert-authormap.t
111 112 test-convert-clonebranches.t
112 113 test-convert-cvs-branch.t
113 114 test-convert-cvs-detectmerge.t
114 115 test-convert-cvs-synthetic.t
115 116 test-convert-cvs.t
116 117 test-convert-cvsnt-mergepoints.t
117 118 test-convert-datesort.t
118 119 test-convert-filemap.t
119 120 test-convert-git.t
120 121 test-convert-hg-sink.t
121 122 test-convert-hg-source.t
122 123 test-convert-hg-startrev.t
123 124 test-convert-splicemap.t
124 125 test-convert-svn-sink.t
125 126 test-convert-tagsbranch-topology.t
126 127 test-convert.t
127 128 test-copy-move-merge.t
128 129 test-copy.t
129 130 test-copytrace-heuristics.t
130 131 test-custom-filters.t
131 132 test-debugbuilddag.t
132 133 test-debugbundle.t
133 134 test-debugcommands.t
134 135 test-debugextensions.t
135 136 test-debugindexdot.t
136 137 test-debugrename.t
137 138 test-default-push.t
138 139 test-diff-antipatience.t
139 140 test-diff-binary-file.t
140 141 test-diff-change.t
141 142 test-diff-color.t
142 143 test-diff-copy-depth.t
143 144 test-diff-hashes.t
144 145 test-diff-ignore-whitespace.t
145 146 test-diff-indent-heuristic.t
146 147 test-diff-issue2761.t
147 148 test-diff-newlines.t
148 149 test-diff-reverse.t
149 150 test-diff-subdir.t
150 151 test-diff-unified.t
151 152 test-diff-upgrade.t
152 153 test-diffdir.t
153 154 test-diffstat.t
154 155 test-directaccess.t
155 156 test-dirstate-backup.t
156 157 test-dirstate-nonnormalset.t
157 158 test-dirstate-race.t
158 159 test-dirstate.t
159 160 test-dispatch.py
160 161 test-dispatch.t
161 162 test-doctest.py
162 163 test-double-merge.t
163 164 test-drawdag.t
164 165 test-duplicateoptions.py
165 166 test-editor-filename.t
166 167 test-empty-dir.t
167 168 test-empty-file.t
168 169 test-empty-group.t
169 170 test-empty.t
170 171 test-encode.t
171 172 test-encoding-align.t
172 173 test-encoding-func.py
173 174 test-encoding-textwrap.t
174 175 test-encoding.t
175 176 test-eol-add.t
176 177 test-eol-clone.t
177 178 test-eol-hook.t
178 179 test-eol-patch.t
179 180 test-eol-tag.t
180 181 test-eol-update.t
181 182 test-eol.t
182 183 test-eolfilename.t
183 184 test-excessive-merge.t
184 185 test-exchange-obsmarkers-case-A1.t
185 186 test-exchange-obsmarkers-case-A2.t
186 187 test-exchange-obsmarkers-case-A3.t
187 188 test-exchange-obsmarkers-case-A4.t
188 189 test-exchange-obsmarkers-case-A5.t
189 190 test-exchange-obsmarkers-case-A6.t
190 191 test-exchange-obsmarkers-case-A7.t
191 192 test-exchange-obsmarkers-case-B1.t
192 193 test-exchange-obsmarkers-case-B2.t
193 194 test-exchange-obsmarkers-case-B3.t
194 195 test-exchange-obsmarkers-case-B4.t
195 196 test-exchange-obsmarkers-case-B5.t
196 197 test-exchange-obsmarkers-case-B6.t
197 198 test-exchange-obsmarkers-case-B7.t
198 199 test-exchange-obsmarkers-case-C1.t
199 200 test-exchange-obsmarkers-case-C2.t
200 201 test-exchange-obsmarkers-case-C3.t
201 202 test-exchange-obsmarkers-case-C4.t
202 203 test-exchange-obsmarkers-case-D1.t
203 204 test-exchange-obsmarkers-case-D2.t
204 205 test-exchange-obsmarkers-case-D3.t
205 206 test-exchange-obsmarkers-case-D4.t
206 207 test-execute-bit.t
207 208 test-export.t
208 209 test-extdata.t
209 210 test-extdiff.t
210 211 test-extension-timing.t
211 212 test-extensions-afterloaded.t
212 213 test-extensions-wrapfunction.py
213 214 test-extra-filelog-entry.t
214 215 test-fastannotate-corrupt.t
215 216 test-fastannotate-diffopts.t
216 217 test-fastannotate-hg.t
217 218 test-fastannotate-perfhack.t
218 219 test-fastannotate-protocol.t
219 220 test-fastannotate-renames.t
220 221 test-fastannotate-revmap.py
221 222 test-fastannotate.t
222 223 test-fetch.t
223 224 test-filebranch.t
224 225 test-filecache.py
225 226 test-filelog.py
226 227 test-fileset-generated.t
227 228 test-fileset.t
228 229 test-fix-topology.t
229 230 test-fix.t
230 231 test-flags.t
231 232 test-fncache.t
232 233 test-gendoc-da.t
233 234 test-gendoc-de.t
234 235 test-gendoc-el.t
235 236 test-gendoc-fr.t
236 237 test-gendoc-it.t
237 238 test-gendoc-ja.t
238 239 test-gendoc-pt_BR.t
239 240 test-gendoc-ro.t
240 241 test-gendoc-ru.t
241 242 test-gendoc-sv.t
242 243 test-gendoc-zh_CN.t
243 244 test-gendoc-zh_TW.t
244 245 test-gendoc.t
245 246 test-generaldelta.t
246 247 test-getbundle.t
247 248 test-git-export.t
248 249 test-githelp.t
249 250 test-globalopts.t
250 251 test-glog-beautifygraph.t
251 252 test-glog-topological.t
252 253 test-glog.t
253 254 test-gpg.t
254 255 test-graft.t
255 256 test-grep.t
256 257 test-hardlinks.t
257 258 test-help-hide.t
258 259 test-help.t
259 260 test-hg-parseurl.py
260 261 test-hghave.t
261 262 test-hgignore.t
262 263 test-hgk.t
263 264 test-hgrc.t
264 265 test-hgweb-annotate-whitespace.t
265 266 test-hgweb-auth.py
266 267 test-hgweb-bundle.t
267 268 test-hgweb-commands.t
268 269 test-hgweb-csp.t
269 270 test-hgweb-descend-empties.t
270 271 test-hgweb-diffs.t
271 272 test-hgweb-empty.t
272 273 test-hgweb-filelog.t
273 274 test-hgweb-no-path-info.t
274 275 test-hgweb-no-request-uri.t
275 276 test-hgweb-non-interactive.t
276 277 test-hgweb-raw.t
277 278 test-hgweb-removed.t
278 279 test-hgweb-symrev.t
279 280 test-hgweb.t
280 281 test-hgwebdir-paths.py
281 282 test-hgwebdir.t
282 283 test-hgwebdirsym.t
283 284 test-histedit-arguments.t
284 285 test-histedit-base.t
285 286 test-histedit-bookmark-motion.t
286 287 test-histedit-commute.t
287 288 test-histedit-drop.t
288 289 test-histedit-edit.t
289 290 test-histedit-fold-non-commute.t
290 291 test-histedit-fold.t
291 292 test-histedit-no-backup.t
292 293 test-histedit-no-change.t
293 294 test-histedit-non-commute-abort.t
294 295 test-histedit-non-commute.t
295 296 test-histedit-obsolete.t
296 297 test-histedit-outgoing.t
297 298 test-histedit-templates.t
298 299 test-http-api-httpv2.t
299 300 test-http-api.t
300 301 test-http-bad-server.t
301 302 test-http-branchmap.t
302 303 test-http-bundle1.t
303 304 test-http-clone-r.t
304 305 test-http-permissions.t
305 306 test-http-protocol.t
306 307 test-http.t
307 308 test-hybridencode.py
308 309 test-i18n.t
309 310 test-identify.t
310 311 test-impexp-branch.t
311 312 test-import-bypass.t
312 313 test-import-context.t
313 314 test-import-eol.t
314 315 test-import-git.t
315 316 test-import-merge.t
316 317 test-import-unknown.t
317 318 test-import.t
318 319 test-imports-checker.t
319 320 test-incoming-outgoing.t
320 321 test-infinitepush-bundlestore.t
321 322 test-infinitepush-ci.t
322 323 test-infinitepush.t
323 324 test-inherit-mode.t
324 325 test-init.t
325 326 test-install.t
326 327 test-issue1089.t
327 328 test-issue1102.t
328 329 test-issue1175.t
329 330 test-issue1306.t
330 331 test-issue1438.t
331 332 test-issue1502.t
332 333 test-issue1802.t
333 334 test-issue1877.t
334 335 test-issue1993.t
335 336 test-issue2137.t
336 337 test-issue3084.t
337 338 test-issue4074.t
338 339 test-issue522.t
339 340 test-issue586.t
340 341 test-issue5979.t
341 342 test-issue612.t
342 343 test-issue619.t
343 344 test-issue660.t
344 345 test-issue672.t
345 346 test-issue842.t
346 347 test-journal-exists.t
347 348 test-journal-share.t
348 349 test-journal.t
349 350 test-keyword.t
350 351 test-known.t
351 352 test-largefiles-cache.t
352 353 test-largefiles-misc.t
353 354 test-largefiles-small-disk.t
354 355 test-largefiles-update.t
355 356 test-largefiles-wireproto.t
356 357 test-largefiles.t
357 358 test-lfconvert.t
358 359 test-lfs-bundle.t
359 360 test-lfs-largefiles.t
360 361 test-lfs-pointer.py
361 362 test-lfs-test-server.t
362 363 test-lfs.t
363 364 test-linelog.py
364 365 test-linerange.py
365 366 test-locate.t
366 367 test-lock-badness.t
367 368 test-lock.py
368 369 test-log-exthook.t
369 370 test-log-linerange.t
370 371 test-log.t
371 372 test-logexchange.t
372 373 test-logtoprocess.t
373 374 test-lrucachedict.py
374 375 test-mactext.t
375 376 test-mailmap.t
376 377 test-manifest-merging.t
377 378 test-manifest.py
378 379 test-manifest.t
379 380 test-match.py
380 381 test-mdiff.py
381 382 test-merge-changedelete.t
382 383 test-merge-closedheads.t
383 384 test-merge-commit.t
384 385 test-merge-criss-cross.t
385 386 test-merge-default.t
386 387 test-merge-force.t
387 388 test-merge-halt.t
388 389 test-merge-internal-tools-pattern.t
389 390 test-merge-local.t
390 391 test-merge-no-file-change.t
391 392 test-merge-remove.t
392 393 test-merge-revert.t
393 394 test-merge-revert2.t
394 395 test-merge-subrepos.t
395 396 test-merge-symlinks.t
396 397 test-merge-tools.t
397 398 test-merge-types.t
398 399 test-merge1.t
399 400 test-merge10.t
400 401 test-merge2.t
401 402 test-merge4.t
402 403 test-merge5.t
403 404 test-merge6.t
404 405 test-merge7.t
405 406 test-merge8.t
406 407 test-merge9.t
407 408 test-minifileset.py
408 409 test-minirst.py
409 410 test-missing-capability.t
410 411 test-mq-eol.t
411 412 test-mq-git.t
412 413 test-mq-guards.t
413 414 test-mq-header-date.t
414 415 test-mq-header-from.t
415 416 test-mq-merge.t
416 417 test-mq-missingfiles.t
417 418 test-mq-pull-from-bundle.t
418 419 test-mq-qclone-http.t
419 420 test-mq-qdelete.t
420 421 test-mq-qdiff.t
421 422 test-mq-qfold.t
422 423 test-mq-qgoto.t
423 424 test-mq-qimport-fail-cleanup.t
424 425 test-mq-qimport.t
425 426 test-mq-qnew.t
426 427 test-mq-qpush-exact.t
427 428 test-mq-qpush-fail.t
428 429 test-mq-qqueue.t
429 430 test-mq-qrefresh-interactive.t
430 431 test-mq-qrefresh-replace-log-message.t
431 432 test-mq-qrefresh.t
432 433 test-mq-qrename.t
433 434 test-mq-qsave.t
434 435 test-mq-safety.t
435 436 test-mq-subrepo.t
436 437 test-mq-symlinks.t
437 438 test-mq.t
438 439 test-mv-cp-st-diff.t
439 440 test-narrow-acl.t
440 441 test-narrow-archive.t
441 442 test-narrow-clone-no-ellipsis.t
442 443 test-narrow-clone-non-narrow-server.t
443 444 test-narrow-clone-nonlinear.t
444 445 test-narrow-clone-stream.t
445 446 test-narrow-clone.t
446 447 test-narrow-commit.t
447 448 test-narrow-copies.t
448 449 test-narrow-debugcommands.t
449 450 test-narrow-debugrebuilddirstate.t
450 451 test-narrow-exchange-merges.t
451 452 test-narrow-exchange.t
452 453 test-narrow-expanddirstate.t
453 454 test-narrow-merge.t
454 455 test-narrow-patch.t
455 456 test-narrow-patterns.t
456 457 test-narrow-pull.t
457 458 test-narrow-rebase.t
458 459 test-narrow-shallow-merges.t
459 460 test-narrow-shallow.t
460 461 test-narrow-share.t
461 462 test-narrow-sparse.t
462 463 test-narrow-strip.t
463 464 test-narrow-trackedcmd.t
464 465 test-narrow-update.t
465 466 test-narrow-widen-no-ellipsis.t
466 467 test-narrow-widen.t
467 468 test-narrow.t
468 469 test-nested-repo.t
469 470 test-newbranch.t
470 471 test-newcgi.t
471 472 test-newercgi.t
472 473 test-nointerrupt.t
473 474 test-notify-changegroup.t
474 475 test-obshistory.t
475 476 test-obsmarker-template.t
476 477 test-obsmarkers-effectflag.t
477 478 test-obsolete-bounds-checking.t
478 479 test-obsolete-bundle-strip.t
479 480 test-obsolete-changeset-exchange.t
480 481 test-obsolete-checkheads.t
481 482 test-obsolete-distributed.t
482 483 test-obsolete-divergent.t
483 484 test-obsolete-tag-cache.t
484 485 test-obsolete.t
485 486 test-oldcgi.t
486 487 test-origbackup-conflict.t
487 488 test-pager-legacy.t
488 489 test-pager.t
489 490 test-parents.t
490 491 test-parse-date.t
491 492 test-parseindex.t
492 493 test-parseindex2.py
493 494 test-patch-offset.t
494 495 test-patch.t
495 496 test-patchbomb-bookmark.t
496 497 test-patchbomb-tls.t
497 498 test-patchbomb.t
498 499 test-pathconflicts-basic.t
499 500 test-pathconflicts-merge.t
500 501 test-pathconflicts-update.t
501 502 test-pathencode.py
502 503 test-pending.t
503 504 test-permissions.t
504 505 test-phases-exchange.t
505 506 test-phases.t
506 507 test-profile.t
507 508 test-progress.t
508 509 test-propertycache.py
509 510 test-pull-branch.t
510 511 test-pull-bundle.t
511 512 test-pull-http.t
512 513 test-pull-permission.t
513 514 test-pull-pull-corruption.t
514 515 test-pull-r.t
515 516 test-pull-update.t
516 517 test-pull.t
517 518 test-purge.t
518 519 test-push-cgi.t
519 520 test-push-checkheads-partial-C1.t
520 521 test-push-checkheads-partial-C2.t
521 522 test-push-checkheads-partial-C3.t
522 523 test-push-checkheads-partial-C4.t
523 524 test-push-checkheads-pruned-B1.t
524 525 test-push-checkheads-pruned-B2.t
525 526 test-push-checkheads-pruned-B3.t
526 527 test-push-checkheads-pruned-B4.t
527 528 test-push-checkheads-pruned-B5.t
528 529 test-push-checkheads-pruned-B6.t
529 530 test-push-checkheads-pruned-B7.t
530 531 test-push-checkheads-pruned-B8.t
531 532 test-push-checkheads-superceed-A1.t
532 533 test-push-checkheads-superceed-A2.t
533 534 test-push-checkheads-superceed-A3.t
534 535 test-push-checkheads-superceed-A4.t
535 536 test-push-checkheads-superceed-A5.t
536 537 test-push-checkheads-superceed-A6.t
537 538 test-push-checkheads-superceed-A7.t
538 539 test-push-checkheads-superceed-A8.t
539 540 test-push-checkheads-unpushed-D1.t
540 541 test-push-checkheads-unpushed-D2.t
541 542 test-push-checkheads-unpushed-D3.t
542 543 test-push-checkheads-unpushed-D4.t
543 544 test-push-checkheads-unpushed-D5.t
544 545 test-push-checkheads-unpushed-D6.t
545 546 test-push-checkheads-unpushed-D7.t
546 547 test-push-http.t
547 548 test-push-race.t
548 549 test-push-warn.t
549 550 test-push.t
550 551 test-pushvars.t
551 552 test-qrecord.t
552 553 test-rebase-abort.t
553 554 test-rebase-backup.t
554 555 test-rebase-base-flag.t
555 556 test-rebase-bookmarks.t
556 557 test-rebase-brute-force.t
557 558 test-rebase-cache.t
558 559 test-rebase-check-restore.t
559 560 test-rebase-collapse.t
560 561 test-rebase-conflicts.t
561 562 test-rebase-dest.t
562 563 test-rebase-detach.t
563 564 test-rebase-emptycommit.t
564 565 test-rebase-inmemory.t
565 566 test-rebase-interruptions.t
566 567 test-rebase-issue-noparam-single-rev.t
567 568 test-rebase-legacy.t
568 569 test-rebase-mq-skip.t
569 570 test-rebase-mq.t
570 571 test-rebase-named-branches.t
571 572 test-rebase-newancestor.t
572 573 test-rebase-obsolete.t
573 574 test-rebase-parameters.t
574 575 test-rebase-partial.t
575 576 test-rebase-pull.t
576 577 test-rebase-rename.t
577 578 test-rebase-scenario-global.t
578 579 test-rebase-templates.t
579 580 test-rebase-transaction.t
580 581 test-rebuildstate.t
581 582 test-record.t
582 583 test-releasenotes-formatting.t
583 584 test-releasenotes-merging.t
584 585 test-releasenotes-parsing.t
585 586 test-relink.t
586 587 test-remotefilelog-bad-configs.t
587 588 test-remotefilelog-bgprefetch.t
588 589 test-remotefilelog-blame.t
589 590 test-remotefilelog-bundle2.t
590 591 test-remotefilelog-bundles.t
591 592 test-remotefilelog-cacheprocess.t
592 593 test-remotefilelog-clone-tree.t
593 594 test-remotefilelog-clone.t
594 595 test-remotefilelog-datapack.py
595 596 test-remotefilelog-gcrepack.t
596 597 test-remotefilelog-histpack.py
597 598 test-remotefilelog-http.t
598 599 test-remotefilelog-keepset.t
599 600 test-remotefilelog-local.t
600 601 test-remotefilelog-log.t
601 602 test-remotefilelog-partial-shallow.t
602 603 test-remotefilelog-permissions.t
603 604 test-remotefilelog-permisssions.t
604 605 test-remotefilelog-prefetch.t
605 606 test-remotefilelog-pull-noshallow.t
606 607 test-remotefilelog-repack.t
607 608 test-remotefilelog-share.t
608 609 test-remotefilelog-sparse.t
609 610 test-remotefilelog-tags.t
610 611 test-remotefilelog-wireproto.t
611 612 test-remove.t
612 613 test-removeemptydirs.t
613 614 test-rename-after-merge.t
614 615 test-rename-dir-merge.t
615 616 test-rename-merge1.t
616 617 test-rename-merge2.t
617 618 test-rename.t
618 619 test-repair-strip.t
619 620 test-repo-compengines.t
620 621 test-requires.t
621 622 test-resolve.t
622 623 test-revert-flags.t
623 624 test-revert-interactive.t
624 625 test-revert-unknown.t
625 626 test-revert.t
626 627 test-revisions.t
627 628 test-revlog-ancestry.py
628 629 test-revlog-group-emptyiter.t
629 630 test-revlog-mmapindex.t
630 631 test-revlog-packentry.t
631 632 test-revlog-raw.py
632 633 test-revlog-v2.t
633 634 test-revlog.t
634 635 test-revset-dirstate-parents.t
635 636 test-revset-legacy-lookup.t
636 637 test-revset-outgoing.t
637 638 test-revset2.t
638 639 test-rollback.t
639 640 test-run-tests.py
640 641 test-run-tests.t
641 642 test-rust-ancestor.py
642 643 test-schemes.t
643 644 test-serve.t
644 645 test-setdiscovery.t
645 646 test-share.t
646 647 test-shelve.t
647 648 test-shelve2.t
648 649 test-show-stack.t
649 650 test-show-work.t
650 651 test-show.t
651 652 test-simple-update.t
652 653 test-simplekeyvaluefile.py
653 654 test-simplemerge.py
654 655 test-single-head.t
655 656 test-sparse-clear.t
656 657 test-sparse-clone.t
657 658 test-sparse-import.t
658 659 test-sparse-merges.t
659 660 test-sparse-profiles.t
660 661 test-sparse-requirement.t
661 662 test-sparse-verbose-json.t
662 663 test-sparse.t
663 664 test-split.t
664 665 test-ssh-bundle1.t
665 666 test-ssh-clone-r.t
666 667 test-ssh-proto-unbundle.t
667 668 test-ssh-proto.t
668 669 test-ssh-repoerror.t
669 670 test-ssh.t
670 671 test-sshserver.py
671 672 test-stack.t
672 673 test-static-http.t
673 674 test-status-color.t
674 675 test-status-inprocess.py
675 676 test-status-rev.t
676 677 test-status-terse.t
677 678 test-status.t
678 679 test-storage.py
679 680 test-stream-bundle-v2.t
680 681 test-strict.t
681 682 test-strip-cross.t
682 683 test-strip.t
683 684 test-subrepo-deep-nested-change.t
684 685 test-subrepo-git.t
685 686 test-subrepo-missing.t
686 687 test-subrepo-paths.t
687 688 test-subrepo-recursion.t
688 689 test-subrepo-relative-path.t
689 690 test-subrepo.t
690 691 test-symlink-os-yes-fs-no.py
691 692 test-symlink-placeholder.t
692 693 test-symlinks.t
693 694 test-tag.t
694 695 test-tags.t
695 696 test-template-basic.t
696 697 test-template-functions.t
697 698 test-template-keywords.t
698 699 test-template-map.t
699 700 test-tools.t
700 701 test-transplant.t
701 702 test-treediscovery-legacy.t
702 703 test-treediscovery.t
703 704 test-treemanifest.t
704 705 test-ui-color.py
705 706 test-ui-config.py
706 707 test-ui-verbosity.py
707 708 test-unamend.t
708 709 test-unbundlehash.t
709 710 test-uncommit.t
710 711 test-unified-test.t
711 712 test-unionrepo.t
712 713 test-unrelated-pull.t
713 714 test-up-local-change.t
714 715 test-update-atomic.t
715 716 test-update-branches.t
716 717 test-update-dest.t
717 718 test-update-issue1456.t
718 719 test-update-names.t
719 720 test-update-reverse.t
720 721 test-upgrade-repo.t
721 722 test-url-download.t
722 723 test-url-rev.t
723 724 test-url.py
724 725 test-username-newline.t
725 726 test-util.py
726 727 test-verify.t
727 728 test-walk.t
728 729 test-walkrepo.py
729 730 test-websub.t
730 731 test-win32text.t
731 732 test-wireproto-caching.t
732 733 test-wireproto-clientreactor.py
733 734 test-wireproto-command-branchmap.t
734 735 test-wireproto-command-capabilities.t
735 736 test-wireproto-command-changesetdata.t
736 737 test-wireproto-command-filedata.t
737 738 test-wireproto-command-filesdata.t
738 739 test-wireproto-command-heads.t
739 740 test-wireproto-command-known.t
740 741 test-wireproto-command-listkeys.t
741 742 test-wireproto-command-lookup.t
742 743 test-wireproto-command-manifestdata.t
743 744 test-wireproto-command-pushkey.t
744 745 test-wireproto-command-rawstorefiledata.t
745 746 test-wireproto-content-redirects.t
746 747 test-wireproto-exchangev2.t
747 748 test-wireproto-framing.py
748 749 test-wireproto-serverreactor.py
749 750 test-wireproto.py
750 751 test-wireproto.t
751 752 test-wsgirequest.py
752 753 test-xdg.t
@@ -1,705 +1,706 b''
1 1 # posix.py - Posix utility function implementations for Mercurial
2 2 #
3 3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import errno
11 11 import fcntl
12 12 import getpass
13 13 import grp
14 14 import os
15 15 import pwd
16 16 import re
17 17 import select
18 18 import stat
19 19 import sys
20 20 import tempfile
21 21 import unicodedata
22 22
23 23 from .i18n import _
24 24 from . import (
25 25 encoding,
26 26 error,
27 27 policy,
28 28 pycompat,
29 29 )
30 30
31 31 osutil = policy.importmod(r'osutil')
32 32
33 33 posixfile = open
34 34 normpath = os.path.normpath
35 35 samestat = os.path.samestat
36 36 try:
37 37 oslink = os.link
38 38 except AttributeError:
39 39 # Some platforms build Python without os.link on systems that are
40 40 # vaguely unix-like but don't have hardlink support. For those
41 41 # poor souls, just say we tried and that it failed so we fall back
42 42 # to copies.
43 43 def oslink(src, dst):
44 44 raise OSError(errno.EINVAL,
45 45 'hardlinks not supported: %s to %s' % (src, dst))
46 46 readlink = os.readlink
47 47 unlink = os.unlink
48 48 rename = os.rename
49 49 removedirs = os.removedirs
50 50 expandglobs = False
51 51
52 52 umask = os.umask(0)
53 53 os.umask(umask)
54 54
55 55 def split(p):
56 56 '''Same as posixpath.split, but faster
57 57
58 58 >>> import posixpath
59 59 >>> for f in [b'/absolute/path/to/file',
60 60 ... b'relative/path/to/file',
61 61 ... b'file_alone',
62 62 ... b'path/to/directory/',
63 63 ... b'/multiple/path//separators',
64 64 ... b'/file_at_root',
65 65 ... b'///multiple_leading_separators_at_root',
66 66 ... b'']:
67 67 ... assert split(f) == posixpath.split(f), f
68 68 '''
69 69 ht = p.rsplit('/', 1)
70 70 if len(ht) == 1:
71 71 return '', p
72 72 nh = ht[0].rstrip('/')
73 73 if nh:
74 74 return nh, ht[1]
75 75 return ht[0] + '/', ht[1]
76 76
77 77 def openhardlinks():
78 78 '''return true if it is safe to hold open file handles to hardlinks'''
79 79 return True
80 80
81 81 def nlinks(name):
82 82 '''return number of hardlinks for the given file'''
83 83 return os.lstat(name).st_nlink
84 84
85 85 def parsepatchoutput(output_line):
86 86 """parses the output produced by patch and returns the filename"""
87 87 pf = output_line[14:]
88 88 if pycompat.sysplatform == 'OpenVMS':
89 89 if pf[0] == '`':
90 90 pf = pf[1:-1] # Remove the quotes
91 91 else:
92 92 if pf.startswith("'") and pf.endswith("'") and " " in pf:
93 93 pf = pf[1:-1] # Remove the quotes
94 94 return pf
95 95
96 96 def sshargs(sshcmd, host, user, port):
97 97 '''Build argument list for ssh'''
98 98 args = user and ("%s@%s" % (user, host)) or host
99 99 if '-' in args[:1]:
100 100 raise error.Abort(
101 101 _('illegal ssh hostname or username starting with -: %s') % args)
102 102 args = shellquote(args)
103 103 if port:
104 104 args = '-p %s %s' % (shellquote(port), args)
105 105 return args
106 106
107 107 def isexec(f):
108 108 """check whether a file is executable"""
109 109 return (os.lstat(f).st_mode & 0o100 != 0)
110 110
111 111 def setflags(f, l, x):
112 112 st = os.lstat(f)
113 113 s = st.st_mode
114 114 if l:
115 115 if not stat.S_ISLNK(s):
116 116 # switch file to link
117 117 fp = open(f, 'rb')
118 118 data = fp.read()
119 119 fp.close()
120 120 unlink(f)
121 121 try:
122 122 os.symlink(data, f)
123 123 except OSError:
124 124 # failed to make a link, rewrite file
125 125 fp = open(f, "wb")
126 126 fp.write(data)
127 127 fp.close()
128 128 # no chmod needed at this point
129 129 return
130 130 if stat.S_ISLNK(s):
131 131 # switch link to file
132 132 data = os.readlink(f)
133 133 unlink(f)
134 134 fp = open(f, "wb")
135 135 fp.write(data)
136 136 fp.close()
137 137 s = 0o666 & ~umask # avoid restatting for chmod
138 138
139 139 sx = s & 0o100
140 140 if st.st_nlink > 1 and bool(x) != bool(sx):
141 141 # the file is a hardlink, break it
142 142 with open(f, "rb") as fp:
143 143 data = fp.read()
144 144 unlink(f)
145 145 with open(f, "wb") as fp:
146 146 fp.write(data)
147 147
148 148 if x and not sx:
149 149 # Turn on +x for every +r bit when making a file executable
150 150 # and obey umask.
151 151 os.chmod(f, s | (s & 0o444) >> 2 & ~umask)
152 152 elif not x and sx:
153 153 # Turn off all +x bits
154 154 os.chmod(f, s & 0o666)
155 155
156 156 def copymode(src, dst, mode=None, enforcewritable=False):
157 157 '''Copy the file mode from the file at path src to dst.
158 158 If src doesn't exist, we're using mode instead. If mode is None, we're
159 159 using umask.'''
160 160 try:
161 161 st_mode = os.lstat(src).st_mode & 0o777
162 162 except OSError as inst:
163 163 if inst.errno != errno.ENOENT:
164 164 raise
165 165 st_mode = mode
166 166 if st_mode is None:
167 167 st_mode = ~umask
168 168 st_mode &= 0o666
169 169
170 170 new_mode = st_mode
171 171
172 172 if enforcewritable:
173 173 new_mode |= stat.S_IWUSR
174 174
175 175 os.chmod(dst, new_mode)
176 176
177 177 def checkexec(path):
178 178 """
179 179 Check whether the given path is on a filesystem with UNIX-like exec flags
180 180
181 181 Requires a directory (like /foo/.hg)
182 182 """
183 183
184 184 # VFAT on some Linux versions can flip mode but it doesn't persist
185 185 # a FS remount. Frequently we can detect it if files are created
186 186 # with exec bit on.
187 187
188 188 try:
189 189 EXECFLAGS = stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH
190 190 basedir = os.path.join(path, '.hg')
191 191 cachedir = os.path.join(basedir, 'wcache')
192 192 storedir = os.path.join(basedir, 'store')
193 193 if not os.path.exists(cachedir):
194 194 try:
195 195 # we want to create the 'cache' directory, not the '.hg' one.
196 196 # Automatically creating '.hg' directory could silently spawn
197 197 # invalid Mercurial repositories. That seems like a bad idea.
198 198 os.mkdir(cachedir)
199 199 if os.path.exists(storedir):
200 200 copymode(storedir, cachedir)
201 201 else:
202 202 copymode(basedir, cachedir)
203 203 except (IOError, OSError):
204 204 # we other fallback logic triggers
205 205 pass
206 206 if os.path.isdir(cachedir):
207 207 checkisexec = os.path.join(cachedir, 'checkisexec')
208 208 checknoexec = os.path.join(cachedir, 'checknoexec')
209 209
210 210 try:
211 211 m = os.stat(checkisexec).st_mode
212 212 except OSError as e:
213 213 if e.errno != errno.ENOENT:
214 214 raise
215 215 # checkisexec does not exist - fall through ...
216 216 else:
217 217 # checkisexec exists, check if it actually is exec
218 218 if m & EXECFLAGS != 0:
219 219 # ensure checkisexec exists, check it isn't exec
220 220 try:
221 221 m = os.stat(checknoexec).st_mode
222 222 except OSError as e:
223 223 if e.errno != errno.ENOENT:
224 224 raise
225 225 open(checknoexec, 'w').close() # might fail
226 226 m = os.stat(checknoexec).st_mode
227 227 if m & EXECFLAGS == 0:
228 228 # check-exec is exec and check-no-exec is not exec
229 229 return True
230 230 # checknoexec exists but is exec - delete it
231 231 unlink(checknoexec)
232 232 # checkisexec exists but is not exec - delete it
233 233 unlink(checkisexec)
234 234
235 235 # check using one file, leave it as checkisexec
236 236 checkdir = cachedir
237 237 else:
238 238 # check directly in path and don't leave checkisexec behind
239 239 checkdir = path
240 240 checkisexec = None
241 241 fh, fn = pycompat.mkstemp(dir=checkdir, prefix='hg-checkexec-')
242 242 try:
243 243 os.close(fh)
244 244 m = os.stat(fn).st_mode
245 245 if m & EXECFLAGS == 0:
246 246 os.chmod(fn, m & 0o777 | EXECFLAGS)
247 247 if os.stat(fn).st_mode & EXECFLAGS != 0:
248 248 if checkisexec is not None:
249 249 os.rename(fn, checkisexec)
250 250 fn = None
251 251 return True
252 252 finally:
253 253 if fn is not None:
254 254 unlink(fn)
255 255 except (IOError, OSError):
256 256 # we don't care, the user probably won't be able to commit anyway
257 257 return False
258 258
259 259 def checklink(path):
260 260 """check whether the given path is on a symlink-capable filesystem"""
261 261 # mktemp is not racy because symlink creation will fail if the
262 262 # file already exists
263 263 while True:
264 264 cachedir = os.path.join(path, '.hg', 'wcache')
265 265 checklink = os.path.join(cachedir, 'checklink')
266 266 # try fast path, read only
267 267 if os.path.islink(checklink):
268 268 return True
269 269 if os.path.isdir(cachedir):
270 270 checkdir = cachedir
271 271 else:
272 272 checkdir = path
273 273 cachedir = None
274 274 name = tempfile.mktemp(dir=pycompat.fsdecode(checkdir),
275 275 prefix=r'checklink-')
276 276 name = pycompat.fsencode(name)
277 277 try:
278 278 fd = None
279 279 if cachedir is None:
280 280 fd = pycompat.namedtempfile(dir=checkdir,
281 281 prefix='hg-checklink-')
282 282 target = os.path.basename(fd.name)
283 283 else:
284 284 # create a fixed file to link to; doesn't matter if it
285 285 # already exists.
286 286 target = 'checklink-target'
287 287 try:
288 288 fullpath = os.path.join(cachedir, target)
289 289 open(fullpath, 'w').close()
290 290 except IOError as inst:
291 291 if inst[0] == errno.EACCES:
292 292 # If we can't write to cachedir, just pretend
293 293 # that the fs is readonly and by association
294 294 # that the fs won't support symlinks. This
295 295 # seems like the least dangerous way to avoid
296 296 # data loss.
297 297 return False
298 298 raise
299 299 try:
300 300 os.symlink(target, name)
301 301 if cachedir is None:
302 302 unlink(name)
303 303 else:
304 304 try:
305 305 os.rename(name, checklink)
306 306 except OSError:
307 307 unlink(name)
308 308 return True
309 309 except OSError as inst:
310 310 # link creation might race, try again
311 311 if inst.errno == errno.EEXIST:
312 312 continue
313 313 raise
314 314 finally:
315 315 if fd is not None:
316 316 fd.close()
317 317 except AttributeError:
318 318 return False
319 319 except OSError as inst:
320 320 # sshfs might report failure while successfully creating the link
321 321 if inst.errno == errno.EIO and os.path.exists(name):
322 322 unlink(name)
323 323 return False
324 324
325 325 def checkosfilename(path):
326 326 '''Check that the base-relative path is a valid filename on this platform.
327 327 Returns None if the path is ok, or a UI string describing the problem.'''
328 328 return None # on posix platforms, every path is ok
329 329
330 330 def getfsmountpoint(dirpath):
331 331 '''Get the filesystem mount point from a directory (best-effort)
332 332
333 333 Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
334 334 '''
335 335 return getattr(osutil, 'getfsmountpoint', lambda x: None)(dirpath)
336 336
337 337 def getfstype(dirpath):
338 338 '''Get the filesystem type name from a directory (best-effort)
339 339
340 340 Returns None if we are unsure. Raises OSError on ENOENT, EPERM, etc.
341 341 '''
342 342 return getattr(osutil, 'getfstype', lambda x: None)(dirpath)
343 343
344 344 def setbinary(fd):
345 345 pass
346 346
347 347 def pconvert(path):
348 348 return path
349 349
350 350 def localpath(path):
351 351 return path
352 352
353 353 def samefile(fpath1, fpath2):
354 354 """Returns whether path1 and path2 refer to the same file. This is only
355 355 guaranteed to work for files, not directories."""
356 356 return os.path.samefile(fpath1, fpath2)
357 357
358 358 def samedevice(fpath1, fpath2):
359 359 """Returns whether fpath1 and fpath2 are on the same device. This is only
360 360 guaranteed to work for files, not directories."""
361 361 st1 = os.lstat(fpath1)
362 362 st2 = os.lstat(fpath2)
363 363 return st1.st_dev == st2.st_dev
364 364
365 365 # os.path.normcase is a no-op, which doesn't help us on non-native filesystems
366 366 def normcase(path):
367 367 return path.lower()
368 368
369 369 # what normcase does to ASCII strings
370 370 normcasespec = encoding.normcasespecs.lower
371 371 # fallback normcase function for non-ASCII strings
372 372 normcasefallback = normcase
373 373
374 374 if pycompat.isdarwin:
375 375
376 376 def normcase(path):
377 377 '''
378 378 Normalize a filename for OS X-compatible comparison:
379 379 - escape-encode invalid characters
380 380 - decompose to NFD
381 381 - lowercase
382 382 - omit ignored characters [200c-200f, 202a-202e, 206a-206f,feff]
383 383
384 384 >>> normcase(b'UPPER')
385 385 'upper'
386 386 >>> normcase(b'Caf\\xc3\\xa9')
387 387 'cafe\\xcc\\x81'
388 388 >>> normcase(b'\\xc3\\x89')
389 389 'e\\xcc\\x81'
390 390 >>> normcase(b'\\xb8\\xca\\xc3\\xca\\xbe\\xc8.JPG') # issue3918
391 391 '%b8%ca%c3\\xca\\xbe%c8.jpg'
392 392 '''
393 393
394 394 try:
395 395 return encoding.asciilower(path) # exception for non-ASCII
396 396 except UnicodeDecodeError:
397 397 return normcasefallback(path)
398 398
399 399 normcasespec = encoding.normcasespecs.lower
400 400
401 401 def normcasefallback(path):
402 402 try:
403 403 u = path.decode('utf-8')
404 404 except UnicodeDecodeError:
405 405 # OS X percent-encodes any bytes that aren't valid utf-8
406 406 s = ''
407 407 pos = 0
408 408 l = len(path)
409 409 while pos < l:
410 410 try:
411 411 c = encoding.getutf8char(path, pos)
412 412 pos += len(c)
413 413 except ValueError:
414 414 c = '%%%02X' % ord(path[pos:pos + 1])
415 415 pos += 1
416 416 s += c
417 417
418 418 u = s.decode('utf-8')
419 419
420 420 # Decompose then lowercase (HFS+ technote specifies lower)
421 421 enc = unicodedata.normalize(r'NFD', u).lower().encode('utf-8')
422 422 # drop HFS+ ignored characters
423 423 return encoding.hfsignoreclean(enc)
424 424
425 425 if pycompat.sysplatform == 'cygwin':
426 426 # workaround for cygwin, in which mount point part of path is
427 427 # treated as case sensitive, even though underlying NTFS is case
428 428 # insensitive.
429 429
430 430 # default mount points
431 431 cygwinmountpoints = sorted([
432 432 "/usr/bin",
433 433 "/usr/lib",
434 434 "/cygdrive",
435 435 ], reverse=True)
436 436
437 437 # use upper-ing as normcase as same as NTFS workaround
438 438 def normcase(path):
439 439 pathlen = len(path)
440 440 if (pathlen == 0) or (path[0] != pycompat.ossep):
441 441 # treat as relative
442 442 return encoding.upper(path)
443 443
444 444 # to preserve case of mountpoint part
445 445 for mp in cygwinmountpoints:
446 446 if not path.startswith(mp):
447 447 continue
448 448
449 449 mplen = len(mp)
450 450 if mplen == pathlen: # mount point itself
451 451 return mp
452 452 if path[mplen] == pycompat.ossep:
453 453 return mp + encoding.upper(path[mplen:])
454 454
455 455 return encoding.upper(path)
456 456
457 457 normcasespec = encoding.normcasespecs.other
458 458 normcasefallback = normcase
459 459
460 460 # Cygwin translates native ACLs to POSIX permissions,
461 461 # but these translations are not supported by native
462 462 # tools, so the exec bit tends to be set erroneously.
463 463 # Therefore, disable executable bit access on Cygwin.
464 464 def checkexec(path):
465 465 return False
466 466
467 467 # Similarly, Cygwin's symlink emulation is likely to create
468 468 # problems when Mercurial is used from both Cygwin and native
469 469 # Windows, with other native tools, or on shared volumes
470 470 def checklink(path):
471 471 return False
472 472
473 473 _needsshellquote = None
474 474 def shellquote(s):
475 475 if pycompat.sysplatform == 'OpenVMS':
476 476 return '"%s"' % s
477 477 global _needsshellquote
478 478 if _needsshellquote is None:
479 479 _needsshellquote = re.compile(br'[^a-zA-Z0-9._/+-]').search
480 480 if s and not _needsshellquote(s):
481 481 # "s" shouldn't have to be quoted
482 482 return s
483 483 else:
484 484 return "'%s'" % s.replace("'", "'\\''")
485 485
486 486 def shellsplit(s):
487 487 """Parse a command string in POSIX shell way (best-effort)"""
488 488 return pycompat.shlexsplit(s, posix=True)
489 489
490 490 def quotecommand(cmd):
491 491 return cmd
492 492
493 493 def testpid(pid):
494 494 '''return False if pid dead, True if running or not sure'''
495 495 if pycompat.sysplatform == 'OpenVMS':
496 496 return True
497 497 try:
498 498 os.kill(pid, 0)
499 499 return True
500 500 except OSError as inst:
501 501 return inst.errno != errno.ESRCH
502 502
503 503 def isowner(st):
504 504 """Return True if the stat object st is from the current user."""
505 505 return st.st_uid == os.getuid()
506 506
507 507 def findexe(command):
508 508 '''Find executable for command searching like which does.
509 509 If command is a basename then PATH is searched for command.
510 510 PATH isn't searched if command is an absolute or relative path.
511 511 If command isn't found None is returned.'''
512 512 if pycompat.sysplatform == 'OpenVMS':
513 513 return command
514 514
515 515 def findexisting(executable):
516 516 'Will return executable if existing file'
517 517 if os.path.isfile(executable) and os.access(executable, os.X_OK):
518 518 return executable
519 519 return None
520 520
521 521 if pycompat.ossep in command:
522 522 return findexisting(command)
523 523
524 524 if pycompat.sysplatform == 'plan9':
525 525 return findexisting(os.path.join('/bin', command))
526 526
527 527 for path in encoding.environ.get('PATH', '').split(pycompat.ospathsep):
528 528 executable = findexisting(os.path.join(path, command))
529 529 if executable is not None:
530 530 return executable
531 531 return None
532 532
533 533 def setsignalhandler():
534 534 pass
535 535
536 536 _wantedkinds = {stat.S_IFREG, stat.S_IFLNK}
537 537
538 538 def statfiles(files):
539 539 '''Stat each file in files. Yield each stat, or None if a file does not
540 540 exist or has a type we don't care about.'''
541 541 lstat = os.lstat
542 542 getkind = stat.S_IFMT
543 543 for nf in files:
544 544 try:
545 545 st = lstat(nf)
546 546 if getkind(st.st_mode) not in _wantedkinds:
547 547 st = None
548 548 except OSError as err:
549 549 if err.errno not in (errno.ENOENT, errno.ENOTDIR):
550 550 raise
551 551 st = None
552 552 yield st
553 553
554 554 def getuser():
555 555 '''return name of current user'''
556 556 return pycompat.fsencode(getpass.getuser())
557 557
558 558 def username(uid=None):
559 559 """Return the name of the user with the given uid.
560 560
561 561 If uid is None, return the name of the current user."""
562 562
563 563 if uid is None:
564 564 uid = os.getuid()
565 565 try:
566 566 return pycompat.fsencode(pwd.getpwuid(uid)[0])
567 567 except KeyError:
568 568 return b'%d' % uid
569 569
570 570 def groupname(gid=None):
571 571 """Return the name of the group with the given gid.
572 572
573 573 If gid is None, return the name of the current group."""
574 574
575 575 if gid is None:
576 576 gid = os.getgid()
577 577 try:
578 578 return grp.getgrgid(gid)[0]
579 579 except KeyError:
580 580 return str(gid)
581 581
582 582 def groupmembers(name):
583 583 """Return the list of members of the group with the given
584 584 name, KeyError if the group does not exist.
585 585 """
586 name = pycompat.sysstr(name)
586 587 return list(grp.getgrnam(name).gr_mem)
587 588
588 589 def spawndetached(args):
589 590 return os.spawnvp(os.P_NOWAIT | getattr(os, 'P_DETACH', 0),
590 591 args[0], args)
591 592
592 593 def gethgcmd():
593 594 return sys.argv[:1]
594 595
595 596 def makedir(path, notindexed):
596 597 os.mkdir(path)
597 598
598 599 def lookupreg(key, name=None, scope=None):
599 600 return None
600 601
601 602 def hidewindow():
602 603 """Hide current shell window.
603 604
604 605 Used to hide the window opened when starting asynchronous
605 606 child process under Windows, unneeded on other systems.
606 607 """
607 608 pass
608 609
609 610 class cachestat(object):
610 611 def __init__(self, path):
611 612 self.stat = os.stat(path)
612 613
613 614 def cacheable(self):
614 615 return bool(self.stat.st_ino)
615 616
616 617 __hash__ = object.__hash__
617 618
618 619 def __eq__(self, other):
619 620 try:
620 621 # Only dev, ino, size, mtime and atime are likely to change. Out
621 622 # of these, we shouldn't compare atime but should compare the
622 623 # rest. However, one of the other fields changing indicates
623 624 # something fishy going on, so return False if anything but atime
624 625 # changes.
625 626 return (self.stat.st_mode == other.stat.st_mode and
626 627 self.stat.st_ino == other.stat.st_ino and
627 628 self.stat.st_dev == other.stat.st_dev and
628 629 self.stat.st_nlink == other.stat.st_nlink and
629 630 self.stat.st_uid == other.stat.st_uid and
630 631 self.stat.st_gid == other.stat.st_gid and
631 632 self.stat.st_size == other.stat.st_size and
632 633 self.stat[stat.ST_MTIME] == other.stat[stat.ST_MTIME] and
633 634 self.stat[stat.ST_CTIME] == other.stat[stat.ST_CTIME])
634 635 except AttributeError:
635 636 return False
636 637
637 638 def __ne__(self, other):
638 639 return not self == other
639 640
640 641 def statislink(st):
641 642 '''check whether a stat result is a symlink'''
642 643 return st and stat.S_ISLNK(st.st_mode)
643 644
644 645 def statisexec(st):
645 646 '''check whether a stat result is an executable file'''
646 647 return st and (st.st_mode & 0o100 != 0)
647 648
648 649 def poll(fds):
649 650 """block until something happens on any file descriptor
650 651
651 652 This is a generic helper that will check for any activity
652 653 (read, write. exception) and return the list of touched files.
653 654
654 655 In unsupported cases, it will raise a NotImplementedError"""
655 656 try:
656 657 while True:
657 658 try:
658 659 res = select.select(fds, fds, fds)
659 660 break
660 661 except select.error as inst:
661 662 if inst.args[0] == errno.EINTR:
662 663 continue
663 664 raise
664 665 except ValueError: # out of range file descriptor
665 666 raise NotImplementedError()
666 667 return sorted(list(set(sum(res, []))))
667 668
668 669 def readpipe(pipe):
669 670 """Read all available data from a pipe."""
670 671 # We can't fstat() a pipe because Linux will always report 0.
671 672 # So, we set the pipe to non-blocking mode and read everything
672 673 # that's available.
673 674 flags = fcntl.fcntl(pipe, fcntl.F_GETFL)
674 675 flags |= os.O_NONBLOCK
675 676 oldflags = fcntl.fcntl(pipe, fcntl.F_SETFL, flags)
676 677
677 678 try:
678 679 chunks = []
679 680 while True:
680 681 try:
681 682 s = pipe.read()
682 683 if not s:
683 684 break
684 685 chunks.append(s)
685 686 except IOError:
686 687 break
687 688
688 689 return ''.join(chunks)
689 690 finally:
690 691 fcntl.fcntl(pipe, fcntl.F_SETFL, oldflags)
691 692
692 693 def bindunixsocket(sock, path):
693 694 """Bind the UNIX domain socket to the specified path"""
694 695 # use relative path instead of full path at bind() if possible, since
695 696 # AF_UNIX path has very small length limit (107 chars) on common
696 697 # platforms (see sys/un.h)
697 698 dirname, basename = os.path.split(path)
698 699 bakwdfd = None
699 700 if dirname:
700 701 bakwdfd = os.open('.', os.O_DIRECTORY)
701 702 os.chdir(dirname)
702 703 sock.bind(basename)
703 704 if bakwdfd:
704 705 os.fchdir(bakwdfd)
705 706 os.close(bakwdfd)
General Comments 0
You need to be logged in to leave comments. Login now