active handling for cygwin

greg andruk gja at meowing.net
Mon Sep 2 07:35:16 UTC 2002



Here's the torture needed to add/remove active lines under Windows.
nnrpd already skips active lines that begin with ".\0", and I told
storage/expire.c to do pretty much the same.  The dot-nul padding
compensates for a teensy race.

(ctlinnd already prevents groups beginning with dots from being created.)


--- innd/icd.c.orig	2002-09-01 23:38:41.000000000 -0400
+++ innd/icd.c	2002-09-02 03:16:03.000000000 -0400
@@ -11,6 +11,12 @@
 #include "innd.h"
 #include "ov.h"
 
+/* If we fork and exec under Cygwin, children hold onto the mmap */
+/* of active, and Windows won't let us resize or replace it.     */
+#ifdef __CYGWIN__
+# undef HAVE_MMAP
+#endif
+
 static char		*ICDactpath = NULL;
 static char		*ICDactpointer;
 static int		ICDactfd;
@@ -154,6 +160,12 @@
     static char		WHEN[] = "backup active";
     int	                fd;
     int			oerrno;
+#ifdef __CYGWIN__
+    size_t		newactsize, padactsize, wrote;
+    struct iovec	*newvp;
+    char		*filler;
+    int			i;
+#endif
 
     if (BACKUP == NULL)
 	BACKUP = concatpath(innconf->pathdb, _PATH_OLDACTIVE);
@@ -182,6 +194,57 @@
 	IOError(WHEN, oerrno);
     }
 
+#ifdef __CYGWIN__
+    /* If we are shrinking active, junk will be at the end between the */
+    /* writev and ftruncate.  Clobber it with values that overview and */
+    /* nnrpd can ignore. */
+    for (newactsize = 0, i = 0; i < vpcount; i++)
+	 newactsize += vp[i].iov_len;
+    if (newactsize < ICDactsize) {
+	 padactsize = ICDactsize - newactsize;
+	 newvp = NEW(struct iovec, vpcount + 1);
+	 for (i = 0; i < vpcount; i++)
+	      newvp[i] = vp[i];
+	 filler = NEW(char, padactsize);
+	 memset(filler, '\0', padactsize);
+	 *filler = '.';
+	 filler[padactsize - 1] = '\n';
+	 newvp[vpcount].iov_base = filler;
+	 newvp[vpcount].iov_len = padactsize;
+	 vpcount++;
+    }
+    else {
+	 padactsize = 0;
+	 newvp = vp;
+    }
+    oerrno = 0;
+    if (lseek(ICDactfd, 0, SEEK_SET) == -1) {
+        oerrno = errno;
+	syslog(L_ERROR, "%s cant rewind %s %m", LogName, ICDactpath);
+	IOError(WHEN, oerrno);
+	goto bailout;
+    }
+    if (xwritev(ICDactfd, newvp, vpcount) < 0) {
+	oerrno = errno;
+	syslog(L_ERROR, "%s cant write %s %m", LogName, ICDactpath);
+	IOError(WHEN, oerrno);
+	goto bailout;
+    }
+    if (newactsize < ICDactsize && ftruncate(ICDactfd, newactsize) != 0) {
+	oerrno = errno;
+	syslog(L_ERROR, "%s cant truncate %s", LogName, ICDactpath);
+    }
+
+bailout:
+    if (padactsize != 0) {
+	 DISPOSE(filler);
+	 DISPOSE(newvp);
+    }
+    if (oerrno != 0)
+	 return FALSE;
+
+#else /* !__CYGWIN__, do it the Unix way. */
+
     /* Open the active file. */
     fd = open(NEWACT, O_WRONLY | O_TRUNC | O_CREAT, ARTFILE_MODE);
     if (fd < 0) {
@@ -212,6 +275,8 @@
 	return FALSE;
     }
 
+#endif /* __CYGWIN__ */
+
     /* Invalidate in-core pointers. */
     ICDcloseactive();
 
--- storage/expire.c.orig	2002-08-10 14:51:29.000000000 -0400
+++ storage/expire.c	2002-09-02 01:38:59.000000000 -0400
@@ -219,6 +219,8 @@
             (void)fprintf(stderr, "%s: line %d missing newline\n", ACTIVE, lines);
             exit(1);
         }
+	if (*p == '.')
+	     continue;
         *q = '\0';
         if (EXPsplit(p, ' ', fields, SIZEOF(fields)) != 4) {
             (void)fprintf(stderr, "%s: line %d wrong number of fields\n", ACTIVE, lines);



More information about the inn-patches mailing list