diff -ru xapian-core-0.9.10-orig/backends/flint/flint_database.cc xapian-core-0.9.10/backends/flint/flint_database.cc
--- xapian-core-0.9.10-orig/backends/flint/flint_database.cc	2007-03-05 23:36:18.000000000 +0000
+++ xapian-core-0.9.10/backends/flint/flint_database.cc	2007-04-23 03:33:54.000000000 +0100
@@ -319,8 +319,16 @@
 FlintDatabase::get_database_write_lock()
 {
     DEBUGCALL(DB, void, "FlintDatabase::get_database_write_lock", "");
-    if (!lock.lock(true)) {
-	throw Xapian::DatabaseLockError("Unable to acquire database write lock on " + db_dir);
+    FlintLock::reason why = lock.lock(true);
+    if (why != FlintLock::SUCCESS) {
+	string msg("Unable to acquire database write lock on ");
+	msg += db_dir;
+	if (why == FlintLock::INUSE) {
+	    msg += ": already locked";
+	} else if (why == FlintLock::UNSUPPORTED) {
+	    msg += ": locking probably not supported by this FS";
+	}
+	throw Xapian::DatabaseLockError(msg);
     }
 }
 
Only in xapian-core-0.9.10/backends/flint: flint_database.cc.orig
diff -ru xapian-core-0.9.10-orig/backends/flint/flint_lock.cc xapian-core-0.9.10/backends/flint/flint_lock.cc
--- xapian-core-0.9.10-orig/backends/flint/flint_lock.cc	2007-03-05 23:36:18.000000000 +0000
+++ xapian-core-0.9.10/backends/flint/flint_lock.cc	2007-04-23 03:38:08.000000000 +0100
@@ -1,6 +1,6 @@
 /* flint_lock.cc: database locking for flint backend.
  *
- * Copyright (C) 2005,2006 Olly Betts
+ * Copyright (C) 2005,2006,2007 Olly Betts
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -26,7 +26,6 @@
 #include "safefcntl.h"
 #include <unistd.h>
 #include <stdlib.h>
-#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/wait.h>
@@ -35,53 +34,83 @@
 
 #include "flint_lock.h"
 
+#include "omassert.h"
+
 #ifdef __CYGWIN__
 #include <sys/cygwin.h>
 #endif
 
-bool
+FlintLock::reason
 FlintLock::lock(bool exclusive) {
-    (void)exclusive; // Ignore for now.
+    // Currently we only support exclusive locks.
+    (void)exclusive;
+    Assert(exclusive);
+#if defined __CYGWIN__ || defined __WIN32__
+    Assert(hFile == INVALID_HANDLE_VALUE);
 #ifdef __CYGWIN__
-    if (hFile != INVALID_HANDLE_VALUE) return false; // Already locked!?
     char fnm[MAX_PATH];
     cygwin_conv_to_win32_path(filename.c_str(), fnm);
+#else
+    const char *fnm = filename.c_str();
+#endif
     hFile = CreateFile(fnm, GENERIC_WRITE, FILE_SHARE_READ,
 		       NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-    return (hFile != INVALID_HANDLE_VALUE);
-#elif defined __WIN32__
-    if (hFile != INVALID_HANDLE_VALUE) return false; // Already locked!?
-    hFile = CreateFile(filename.c_str(), GENERIC_WRITE, FILE_SHARE_READ,
-		       NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-    return (hFile != INVALID_HANDLE_VALUE);
+    if (hFile != INVALID_HANDLE_VALUE) return SUCCESS;
+    if (GetLastError() == ERROR_ALREADY_EXISTS) return INUSE;
+    return UNKNOWN;
 #else
-    if (fd >= 0) return false; // Already locked!?
+    Assert(fd == -1);
     int lockfd = open(filename.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0600);
-    if (lockfd < 0) return false; // Couldn't open lockfile.
+    if (lockfd < 0) return UNKNOWN; // Couldn't open lockfile.
 
     int fds[2];
     if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) < 0) {
 	// Couldn't create socketpair.
 	close(lockfd);
-	return false;
+	return UNKNOWN;
     }
 
     pid_t child = fork();
     if (child == 0) {
 	// Child process.
 	close(fds[0]);
-	struct flock fl;
-	fl.l_type = F_WRLCK;
-	fl.l_whence = SEEK_SET;
-	fl.l_start = 0;
-	fl.l_len = 1;
-	while (fcntl(lockfd, F_SETLK, &fl) == -1) {
-	    if (errno == EINTR) continue; /* Interrupted by a signal. */
-	    // Lock failed.
-	    // Just exit and the parent will realise.
-	    exit(0);
+
+	reason why = SUCCESS;
+	{
+	    struct flock fl;
+	    fl.l_type = F_WRLCK;
+	    fl.l_whence = SEEK_SET;
+	    fl.l_start = 0;
+	    fl.l_len = 1;
+	    while (fcntl(lockfd, F_SETLK, &fl) == -1) {
+		if (errno != EINTR) {
+		    // Lock failed - translate known errno values into a reason
+		    // code.
+		    if (errno == EACCES || errno == EAGAIN) {
+			why = INUSE;
+		    } else if (errno == ENOLCK) {
+			why = UNSUPPORTED;
+		    } else {
+			_exit(0);
+		    }
+		    break;
+		}
+	    }
 	}
-	write(fds[1], "", 1); // Signal OK to parent.
+
+	{
+	    // Tell the parent if we got the lock, and if not, why not.
+	    char ch = static_cast<char>(why);
+	    while (write(fds[1], &ch, 1) < 0) {
+		// EINTR means a signal interrupted us, so retry.
+		// Otherwise we're DOOMED!  The best we can do is just exit
+		// and the parent process should get EOF and know the lock
+		// failed.
+		if (errno != EINTR) _exit(1);
+	    }
+	    if (why != SUCCESS) _exit(0);
+	}
+
 	//shutdown(fds[1], 1); // Disable further sends.
 	// Connect pipe to stdin.
 	dup2(fds[1], 0);
@@ -90,7 +119,7 @@
 	// Emulate cat ourselves (we try to avoid this to reduce VM overhead).
 	char ch;
 	while (read(0, &ch, 1) != 0) { /* Do nothing */ }
-	exit(0);
+	_exit(0);
     }
 
     close(lockfd);
@@ -99,25 +128,31 @@
 	// Couldn't fork.
 	close(fds[0]);
 	close(fds[1]);
-	return false;
+	return UNKNOWN;
     }
-   
+
     // Parent process.
     close(fds[1]);
     while (true) {
 	char ch;
 	int n = read(fds[0], &ch, 1);
-	if (n == 1) break; // Got the lock.
-	if (n == 0) {
-	    // EOF means lock failed.
+	if (n == 1) {
+	    reason why = static_cast<reason>(ch);
+	    if (why == SUCCESS) break; // Got the lock.
 	    close(fds[0]);
-	    return false;
+	    return why;
+	}
+	if (n == 0 || errno != EINTR) {
+	    // EOF means the lock failed; we also treat unexpected errors from
+	    // read() the same way.
+	    close(fds[0]);
+	    return UNKNOWN;
 	}
     }
     //shutdown(fds[0], 0); // Disable further receives.
     fd = fds[0];
     pid = child;
-    return true;
+    return SUCCESS;
 #endif
 }
 
@@ -131,10 +166,15 @@
     if (fd < 0) return;
     close(fd);
     fd = -1;
-    int status;
-    kill(pid, SIGHUP);
-    while (waitpid(pid, &status, 0) < 0) {
-	if (errno != EINTR) break;
+    // The only likely error from kill is ESRCH.  The other possibilities
+    // (according to the Linux man page) are EINVAL (invalid signal) and EPERM
+    // (don't have permission to SIGHUP the process) but in none of the cases
+    // does calling waitpid do us any good!
+    if (kill(pid, SIGHUP) == 0) {
+	int status;
+	while (waitpid(pid, &status, 0) < 0) {
+	    if (errno != EINTR) break;
+	}
     }
 #endif
 }
Only in xapian-core-0.9.10/backends/flint: flint_lock.cc.orig
Only in xapian-core-0.9.10/backends/flint: flint_lock.cc.rej
diff -ru xapian-core-0.9.10-orig/backends/flint/flint_lock.h xapian-core-0.9.10/backends/flint/flint_lock.h
--- xapian-core-0.9.10-orig/backends/flint/flint_lock.h	2007-03-05 23:36:18.000000000 +0000
+++ xapian-core-0.9.10/backends/flint/flint_lock.h	2007-04-23 03:38:27.000000000 +0100
@@ -1,6 +1,6 @@
 /* flint_lock.h: database locking for flint backend.
  *
- * Copyright (C) 2005,2006 Olly Betts
+ * Copyright (C) 2005,2006,2007 Olly Betts
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -14,7 +14,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
  * USA
  */
 
@@ -35,7 +35,6 @@
 #include <netinet/in.h>
 #endif
 #include <sys/socket.h>
-#include <sys/stat.h>
 #include <sys/types.h>
 #include <sys/wait.h>
 #endif
@@ -50,6 +49,12 @@
 #endif
 
   public:
+    typedef enum {
+	SUCCESS, // We got the lock!
+	INUSE, // Already locked by someone else.
+	UNSUPPORTED, // Locking probably not supported (e.g. NFS without lockd).
+	UNKNOWN // The attempt failed for some unspecified reason.
+    } reason;
 #if defined __CYGWIN__ || defined __WIN32__
     FlintLock(const std::string &filename_)
 	: filename(filename_), hFile(INVALID_HANDLE_VALUE) { }
@@ -59,7 +64,7 @@
     operator bool() { return fd != -1; }
 #endif
 
-    bool lock(bool exclusive);
+    reason lock(bool exclusive);
     void release();
 };
 
Only in xapian-core-0.9.10/backends/flint: flint_lock.h.orig
