]> git.decadent.org.uk Git - nfs-utils.git/blobdiff - support/nfs/cacheio.c
Use __fpurge to ensure single-line writes to cache files
[nfs-utils.git] / support / nfs / cacheio.c
index 36473cf3b911beb1fa7670a2a57225b58c8130bc..9d271cd4733d77328a6f2b3e5ec8a80b5da8a73b 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <nfslib.h>
 #include <stdio.h>
+#include <stdio_ext.h>
 #include <ctype.h>
 #include <unistd.h>
 #include <sys/types.h>
@@ -111,7 +112,18 @@ void qword_printint(FILE *f, int num)
 
 int qword_eol(FILE *f)
 {
+       int err;
+
        fprintf(f,"\n");
+       err = fflush(f);
+       /*
+        * We must send one line (and one line only) in a single write
+        * call.  In case of a write error, libc may accumulate the
+        * unwritten data and try to write it again later, resulting in a
+        * multi-line write.  So we must explicitly ask it to throw away
+        * any such cached data:
+        */
+       __fpurge(f);
        return fflush(f);
 }
 
@@ -247,20 +259,24 @@ cache_flush(int force)
        int c;
        char stime[20];
        char path[200];
+       time_t now;
        /* Note: the order of these caches is important.
-        * The need to be flushed in dependancy order. So
+        * They need to be flushed in dependancy order. So
         * a cache that references items in another cache,
         * as nfsd.fh entries reference items in nfsd.export,
         * must be flushed before the cache that it references.
         */
        static char *cachelist[] = {
                "auth.unix.ip",
+               "auth.unix.gid",
                "nfsd.fh",
                "nfsd.export",
                NULL
        };
+       now = time(0);
        if (force ||
-           stat(_PATH_ETAB, &stb) != 0)
+           stat(_PATH_ETAB, &stb) != 0 ||
+           stb.st_mtime > now)
                stb.st_mtime = time(0);
        
        sprintf(stime, "%ld\n", stb.st_mtime);