inotify: workaround ENAMETOOLONG by using symlinks
authorBenoit Boissinot <benoit.boissinot@ens-lyon.org>
Sat, 06 Sep 2008 14:11:33 +0200
changeset 6997 9c4e488f105e
parent 6996 fecf060f32a1
child 6998 ddfcefab8b97
child 7024 ee308d44ad76
inotify: workaround ENAMETOOLONG by using symlinks If we can't create the unix socket because the path is too long we create the socket in a temporary directory and symlink it into the repo. Fix issue1208
hgext/inotify/__init__.py
hgext/inotify/server.py
tests/test-inotify-issue1208
tests/test-inotify-issue1208.out
--- a/hgext/inotify/__init__.py	Sat Sep 06 12:49:20 2008 +0200
+++ b/hgext/inotify/__init__.py	Sat Sep 06 14:11:33 2008 +0200
@@ -58,7 +58,7 @@
                                           list_clean, list_unknown)
                     if result is not None:
                         return result
-            except socket.error, err:
+            except (OSError, socket.error), err:
                 if err[0] == errno.ECONNREFUSED:
                     ui.warn(_('(found dead inotify server socket; '
                                    'removing it)\n'))
--- a/hgext/inotify/server.py	Sat Sep 06 12:49:20 2008 +0200
+++ b/hgext/inotify/server.py	Sat Sep 06 14:11:33 2008 +0200
@@ -9,7 +9,7 @@
 from mercurial.i18n import gettext as _
 from mercurial import osutil, ui, util
 import common
-import errno, os, select, socket, stat, struct, sys, time
+import errno, os, select, socket, stat, struct, sys, tempfile, time
 
 try:
     import linux as inotify
@@ -556,13 +556,31 @@
         self.timeout = timeout
         self.sock = socket.socket(socket.AF_UNIX)
         self.sockpath = self.repo.join('inotify.sock')
+        self.realsockpath = None
         try:
             self.sock.bind(self.sockpath)
         except socket.error, err:
             if err[0] == errno.EADDRINUSE:
-                raise AlreadyStartedException(_('could not start server: %s') \
+                raise AlreadyStartedException(_('could not start server: %s')
                                               % err[1])
-            raise
+            if err[0] == "AF_UNIX path too long":
+                tempdir = tempfile.mkdtemp(prefix="hg-inotify-")
+                self.realsockpath = os.path.join(tempdir, "inotify.sock")
+                try:
+                    self.sock.bind(self.realsockpath)
+                    os.symlink(self.realsockpath, self.sockpath)
+                except (OSError, socket.error), inst:
+                    try:
+                        os.unlink(self.realsockpath)
+                    except:
+                        pass
+                    os.rmdir(tempdir)
+                    if inst.errno == errno.EEXIST:
+                        raise AlreadyStartedException(_('could not start server: %s')
+                                                      % inst.strerror)
+                    raise
+            else:
+                raise
         self.sock.listen(5)
         self.fileno = self.sock.fileno
 
@@ -635,6 +653,9 @@
         self.sock.close()
         try:
             os.unlink(self.sockpath)
+            if self.realsockpath:
+                os.unlink(self.realsockpath)
+                os.rmdir(os.path.dirname(self.realsockpath))
         except OSError, err:
             if err.errno != errno.ENOENT:
                 raise
--- a/tests/test-inotify-issue1208	Sat Sep 06 12:49:20 2008 +0200
+++ b/tests/test-inotify-issue1208	Sat Sep 06 14:11:33 2008 +0200
@@ -9,7 +9,16 @@
 hg init $p
 cd $p
 
+echo % fail
+ln -sf doesnotexist .hg/inotify.sock
+hg st
+hg inserve
+rm .hg/inotify.sock
+
 echo % inserve
-hg inserve
+hg inserve -d --pid-file=hg.pid
+cat hg.pid >> "$DAEMON_PIDS"
 echo % status
 hg status
+
+kill `cat hg.pid`
--- a/tests/test-inotify-issue1208.out	Sat Sep 06 12:49:20 2008 +0200
+++ b/tests/test-inotify-issue1208.out	Sat Sep 06 14:11:33 2008 +0200
@@ -1,5 +1,9 @@
+% fail
+failed to contact inotify server: AF_UNIX path too long
+deactivating inotify
+abort: could not start server: File exists
 % inserve
-abort: AF_UNIX path too long
 % status
 failed to contact inotify server: AF_UNIX path too long
 deactivating inotify
+? hg.pid