]> granicus.if.org Git - psmisc/commitdiff
conditionally compile in fork for stat
authorCraig Small <csmall@users.sourceforge.net>
Mon, 18 Jul 2011 11:23:30 +0000 (21:23 +1000)
committerCraig Small <csmall@users.sourceforge.net>
Mon, 18 Jul 2011 11:23:30 +0000 (21:23 +1000)
ChangeLog
README
configure.ac
src/fuser.c

index 815a8a32062bddcd10d351f682100969cd7baaf9..4605f7feafc953e57a6e17163be9f578476d2bea 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 Changes in 22.15
 ================
        * Really apply patch for SF#31110178 RH#651794
+       * Conditionally use fork before stat calls
 
 Changes in 22.14
 ================
diff --git a/README b/README
index 2489b0500b768637bc9bcbba0c9900fc3caf7e0a..2bc973f38073fe4ddf9b41b2ad50b68970d7c81b 100644 (file)
--- a/README
+++ b/README
@@ -17,6 +17,13 @@ They should work with most recent kernels. Man pages are included.
 src/loop.h was stolen from util-linux package which in turn stole it from
 the Linux kernel.
 
+fuser on network fs
+-------------------
+On network filesystems, fuser can hang because its trying to stat files
+that may go away.  If you use the --with-timeout-stat option during
+the configure step then fuser will fork a process to run stat. This means
+fuser doesn't hang, but it is much slower.
+
 Translations
 ------------
 My thanks for the various translators who have cheerfully given me the po
index d9013d5a5f40c98af57d468ebfca58b5ca50a2c7..e8480cb9e6ad482454e4475cc86d8393cf281de8 100644 (file)
@@ -24,6 +24,16 @@ if test "$enable_selinux" = "yes"; then
 fi
 AC_SUBST([SELINUX_LIB])
 
+dnl Call fork before all stat calls to stop hanging on NFS mounts
+AC_SUBST([WITH_TIMEOUT_STAT])
+AC_ARG_ENABLE([TIMEOUT_STAT],
+  [AS_HELP_STRING([--enable-timeout-stat], [Use a timeout on stat calls])],
+  [enable_timeout_stat=$enableval],
+  [enable_timeout_stat="no"])
+if test "$enable_timeout_stat" = "yes"; then
+  AC_DEFINE([WITH_timeout_stat], [1], [Use timeout on stat calls])
+fi
+
 dnl ipv4 only option
 AC_SUBST([WITH_IPV6])
 AC_ARG_ENABLE([ipv6],
index 8f600aa7eb03d5d2000871b0c66cbd4a4271153d..bef14e20f02c21d05daf90a48f4b60069ba34596 100644 (file)
@@ -106,7 +106,11 @@ static dev_t device(const char *path);
 static char *expandpath(const char *path);
 
 typedef int (*stat_t)(const char*, struct stat*);
+#ifdef WITH_TIMEOUT_STAT
 static int timeout(stat_t func, const char *path, struct stat *buf, unsigned int seconds);
+#else
+#define timeout(func,path,buf,dummy) (func)((path),(buf))
+#endif /* WITH_TIMEOUT_STAT */
 
 static void usage(const char *errormsg)
 {
@@ -1321,12 +1325,11 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename)
        if ((st = (struct stat*)malloc(sizeof(struct stat))) == NULL)
                return NULL;
        snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
-       if (timeout(stat, pathname, st, 5) != 0)
-               goto out;
+       if (timeout(stat, pathname, st, 5) != 0) {
+      free(st);
+         return NULL;
+    }
        return st;
-out:
-       free(st);
-       return NULL;
 }
 
 static void
@@ -1783,6 +1786,7 @@ sigalarm(int sig)
                siglongjmp(jenv, 1);
 }
 
+#ifdef HAVE_TIMEOUT_STAT
 static int
 timeout(stat_t func, const char *path, struct stat *buf, unsigned int seconds)
 {
@@ -1831,6 +1835,7 @@ timeout(stat_t func, const char *path, struct stat *buf, unsigned int seconds)
 err:
        return -1;
 }
+#endif /* HAVE_TIMEOUT_STAT */
 
 #ifdef _LISTS_H
 /*