4 # |
4 # |
5 # This software may be used and distributed according to the terms of the |
5 # This software may be used and distributed according to the terms of the |
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 |
13 import os |
13 import os |
14 import socket |
14 import socket |
328 Listens for client queries on unix socket inotify.sock |
328 Listens for client queries on unix socket inotify.sock |
329 """ |
329 """ |
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) |
333 try: |
334 self.sockpath = join(root, '.hg/inotify.sock') |
334 self.sock = posix.unixdomainserver( |
335 |
335 lambda p: os.path.join(root, '.hg', p), |
336 self.realsockpath = self.sockpath |
336 'inotify') |
337 if os.path.islink(self.sockpath): |
337 except (OSError, socket.error), err: |
338 if os.path.exists(self.sockpath): |
338 if err.errno == errno.EADDRINUSE: |
339 self.realsockpath = os.readlink(self.sockpath) |
339 raise AlreadyStartedException(_('cannot start: ' |
340 else: |
340 'socket is already bound')) |
341 os.unlink(self.sockpath) |
341 raise |
342 try: |
|
343 self.sock.bind(self.realsockpath) |
|
344 except socket.error, err: |
|
345 if err.args[0] == errno.EADDRINUSE: |
|
346 raise AlreadyStartedException(_('cannot start: socket is ' |
|
347 'already bound')) |
|
348 if err.args[0] == "AF_UNIX path too long": |
|
349 tempdir = tempfile.mkdtemp(prefix="hg-inotify-") |
|
350 self.realsockpath = os.path.join(tempdir, "inotify.sock") |
|
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): |
371 names = cs.read().split('\0') |
345 names = cs.read().split('\0') |
372 |
346 |