##// END OF EJS Templates
posix: move server side of unix domain sockets out of inotify...
Bryan O'Sullivan -
r18097:ae54cff7 default
parent child Browse files
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.bind(self.realsockpath)
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