Show More
@@ -405,14 +405,7 b' class socketlistener(server.socketlisten' | |||||
405 |
|
405 | |||
406 | def shutdown(self): |
|
406 | def shutdown(self): | |
407 | self.sock.close() |
|
407 | self.sock.close() | |
408 | try: |
|
408 | self.sock.cleanup() | |
409 | os.unlink(self.sockpath) |
|
|||
410 | if self.realsockpath: |
|
|||
411 | os.unlink(self.realsockpath) |
|
|||
412 | os.rmdir(os.path.dirname(self.realsockpath)) |
|
|||
413 | except OSError, err: |
|
|||
414 | if err.errno != errno.ENOENT: |
|
|||
415 | raise |
|
|||
416 |
|
409 | |||
417 | def answer_stat_query(self, cs): |
|
410 | def answer_stat_query(self, cs): | |
418 | if self.repowatcher.timeout: |
|
411 | if self.repowatcher.timeout: |
@@ -6,7 +6,7 b'' | |||||
6 | # GNU General Public License version 2 or any later version. |
|
6 | # GNU General Public License version 2 or any later version. | |
7 |
|
7 | |||
8 | from mercurial.i18n import _ |
|
8 | from mercurial.i18n import _ | |
9 | from mercurial import cmdutil, osutil, util |
|
9 | from mercurial import cmdutil, posix, osutil, util | |
10 | import common |
|
10 | import common | |
11 |
|
11 | |||
12 | import errno |
|
12 | import errno | |
@@ -330,41 +330,15 b' class socketlistener(object):' | |||||
330 | def __init__(self, ui, root, repowatcher, timeout): |
|
330 | def __init__(self, ui, root, repowatcher, timeout): | |
331 | self.ui = ui |
|
331 | self.ui = ui | |
332 | self.repowatcher = repowatcher |
|
332 | self.repowatcher = repowatcher | |
333 | self.sock = socket.socket(socket.AF_UNIX) |
|
|||
334 | self.sockpath = join(root, '.hg/inotify.sock') |
|
|||
335 |
|
||||
336 | self.realsockpath = self.sockpath |
|
|||
337 | if os.path.islink(self.sockpath): |
|
|||
338 | if os.path.exists(self.sockpath): |
|
|||
339 | self.realsockpath = os.readlink(self.sockpath) |
|
|||
340 | else: |
|
|||
341 | os.unlink(self.sockpath) |
|
|||
342 | try: |
|
333 | try: | |
343 |
self.sock. |
|
334 | self.sock = posix.unixdomainserver( | |
344 | except socket.error, err: |
|
335 | lambda p: os.path.join(root, '.hg', p), | |
345 | if err.args[0] == errno.EADDRINUSE: |
|
336 | 'inotify') | |
346 | raise AlreadyStartedException(_('cannot start: socket is ' |
|
337 | except (OSError, socket.error), err: | |
347 | 'already bound')) |
|
338 | if err.errno == errno.EADDRINUSE: | |
348 | if err.args[0] == "AF_UNIX path too long": |
|
339 | raise AlreadyStartedException(_('cannot start: ' | |
349 | tempdir = tempfile.mkdtemp(prefix="hg-inotify-") |
|
340 | 'socket is already bound')) | |
350 | self.realsockpath = os.path.join(tempdir, "inotify.sock") |
|
341 | raise | |
351 | try: |
|
|||
352 | self.sock.bind(self.realsockpath) |
|
|||
353 | os.symlink(self.realsockpath, self.sockpath) |
|
|||
354 | except (OSError, socket.error), inst: |
|
|||
355 | try: |
|
|||
356 | os.unlink(self.realsockpath) |
|
|||
357 | except OSError: |
|
|||
358 | pass |
|
|||
359 | os.rmdir(tempdir) |
|
|||
360 | if inst.errno == errno.EEXIST: |
|
|||
361 | raise AlreadyStartedException(_('cannot start: tried ' |
|
|||
362 | 'linking .hg/inotify.sock to a temporary socket but' |
|
|||
363 | ' .hg/inotify.sock already exists')) |
|
|||
364 | raise |
|
|||
365 | else: |
|
|||
366 | raise |
|
|||
367 | self.sock.listen(5) |
|
|||
368 | self.fileno = self.sock.fileno |
|
342 | self.fileno = self.sock.fileno | |
369 |
|
343 | |||
370 | def answer_stat_query(self, cs): |
|
344 | def answer_stat_query(self, cs): |
@@ -7,7 +7,7 b'' | |||||
7 |
|
7 | |||
8 | from i18n import _ |
|
8 | from i18n import _ | |
9 | import encoding |
|
9 | import encoding | |
10 | import os, sys, errno, stat, getpass, pwd, grp, tempfile, unicodedata |
|
10 | import os, sys, errno, stat, getpass, pwd, grp, socket, tempfile, unicodedata | |
11 |
|
11 | |||
12 | posixfile = open |
|
12 | posixfile = open | |
13 | normpath = os.path.normpath |
|
13 | normpath = os.path.normpath | |
@@ -483,3 +483,43 b' class cachestat(object):' | |||||
483 |
|
483 | |||
484 | def executablepath(): |
|
484 | def executablepath(): | |
485 | return None # available on Windows only |
|
485 | return None # available on Windows only | |
|
486 | ||||
|
487 | class unixdomainserver(socket.socket): | |||
|
488 | def __init__(self, join, subsystem): | |||
|
489 | '''Create a unix domain socket with the given prefix.''' | |||
|
490 | super(unixdomainserver, self).__init__(socket.AF_UNIX) | |||
|
491 | sockname = subsystem + '.sock' | |||
|
492 | self.realpath = self.path = join(sockname) | |||
|
493 | if os.path.islink(self.path): | |||
|
494 | if os.path.exists(self.path): | |||
|
495 | self.realpath = os.readlink(self.path) | |||
|
496 | else: | |||
|
497 | os.unlink(self.path) | |||
|
498 | try: | |||
|
499 | self.bind(self.realpath) | |||
|
500 | except socket.error, err: | |||
|
501 | if err.args[0] == 'AF_UNIX path too long': | |||
|
502 | tmpdir = tempfile.mkdtemp(prefix='hg-%s-' % subsystem) | |||
|
503 | self.realpath = os.path.join(tmpdir, sockname) | |||
|
504 | try: | |||
|
505 | self.bind(self.realpath) | |||
|
506 | os.symlink(self.realpath, self.path) | |||
|
507 | except (OSError, socket.error): | |||
|
508 | self.cleanup() | |||
|
509 | raise | |||
|
510 | else: | |||
|
511 | raise | |||
|
512 | self.listen(5) | |||
|
513 | ||||
|
514 | def cleanup(self): | |||
|
515 | def okayifmissing(f, path): | |||
|
516 | try: | |||
|
517 | f(path) | |||
|
518 | except OSError, err: | |||
|
519 | if err.errno != errno.ENOENT: | |||
|
520 | raise | |||
|
521 | ||||
|
522 | okayifmissing(os.unlink, self.path) | |||
|
523 | if self.realpath != self.path: | |||
|
524 | okayifmissing(os.unlink, self.realpath) | |||
|
525 | okayifmissing(os.rmdir, os.path.dirname(self.realpath)) |
General Comments 0
You need to be logged in to leave comments.
Login now