cvs-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Cvs-cvs] ccvs/src ChangeLog rcs.c [cvs1-11-x-branch]


From: Larry Jones
Subject: [Cvs-cvs] ccvs/src ChangeLog rcs.c [cvs1-11-x-branch]
Date: Mon, 17 Dec 2007 01:32:21 +0000

CVSROOT:        /cvsroot/cvs
Module name:    ccvs
Branch:         cvs1-11-x-branch
Changes by:     Larry Jones <scjones>   07/12/17 01:32:20

Modified files:
        src            : ChangeLog rcs.c 

Log message:
        * rcs.c (HAVE_MMAP): Fall back to stdio if mmap fails.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/ccvs/src/ChangeLog?cvsroot=cvs&only_with_tag=cvs1-11-x-branch&r1=1.2336.2.494&r2=1.2336.2.495
http://cvs.savannah.gnu.org/viewcvs/ccvs/src/rcs.c?cvsroot=cvs&only_with_tag=cvs1-11-x-branch&r1=1.262.4.62&r2=1.262.4.63

Patches:
Index: ChangeLog
===================================================================
RCS file: /cvsroot/cvs/ccvs/src/ChangeLog,v
retrieving revision 1.2336.2.494
retrieving revision 1.2336.2.495
diff -u -b -r1.2336.2.494 -r1.2336.2.495
--- ChangeLog   13 Dec 2007 16:54:07 -0000      1.2336.2.494
+++ ChangeLog   17 Dec 2007 01:32:19 -0000      1.2336.2.495
@@ -1,3 +1,7 @@
+2007-12-16  Larry Jones  <address@hidden>
+
+       * rcs.c (HAVE_MMAP): Fall back to stdio if mmap fails.
+
 2007-12-13  Larry Jones  <address@hidden>
 
        * rcs.c (rcsbuf_ftell): Avoid potential overflow.

Index: rcs.c
===================================================================
RCS file: /cvsroot/cvs/ccvs/src/rcs.c,v
retrieving revision 1.262.4.62
retrieving revision 1.262.4.63
diff -u -b -r1.262.4.62 -r1.262.4.63
--- rcs.c       13 Dec 2007 16:54:08 -0000      1.262.4.62
+++ rcs.c       17 Dec 2007 01:32:20 -0000      1.262.4.63
@@ -30,6 +30,15 @@
 # endif
 #endif
 
+#ifdef MMAP_FALLBACK_TEST
+void *my_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t 
offset)
+{
+   if (rand() & 1) return mmap(addr, len, prot, flags, fd, offset);
+   return NULL;
+}
+#define mmap my_mmap
+#endif
+
 int preserve_perms = 0;
 
 /* The RCS -k options, and a set of enums that must match the array.
@@ -65,6 +74,8 @@
        this is non-zero, we must search the string for pairs of '@'
        and convert them to a single '@'.  */
     int embedded_at;
+    /* Whether the buffer has been mmap'ed or not.  */
+    int mmapped;
 };
 
 static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile));
@@ -76,10 +87,8 @@
 static int rcsbuf_getkey PROTO ((struct rcsbuffer *, char **keyp,
                                 char **valp));
 static int rcsbuf_getrevnum PROTO ((struct rcsbuffer *, char **revp));
-#ifndef HAVE_MMAP
 static char *rcsbuf_fill PROTO ((struct rcsbuffer *, char *ptr, char **keyp,
                                 char **valp));
-#endif
 static int rcsbuf_valcmp PROTO ((struct rcsbuffer *));
 static char *rcsbuf_valcopy PROTO ((struct rcsbuffer *, char *val, int polish,
                                    size_t *lenp));
@@ -1029,17 +1038,20 @@
     const char *filename;
     unsigned long pos;
 {
+#ifdef HAVE_MMAP
+    void *p;
+    struct stat fs;
+    size_t mmap_off = 0;
+#endif
+
     if (rcsbuf_inuse)
        error (1, 0, "rcsbuf_open: internal error");
     rcsbuf_inuse = 1;
 
 #ifdef HAVE_MMAP
-    {
        /* When we have mmap, it is much more efficient to let the system do the
         * buffering and caching for us
         */
-       struct stat fs;
-       size_t mmap_off = 0;
 
        if ( fstat (fileno(fp), &fs) < 0 )
            error ( 1, errno, "Could not stat RCS archive %s for mapping", 
filename );
@@ -1051,24 +1063,33 @@
        }
 
        /* Map private here since this particular buffer is read only */
-       rcsbuf_buffer = mmap ( NULL, fs.st_size - mmap_off,
-                               PROT_READ | PROT_WRITE,
+    p = mmap ( NULL, fs.st_size - mmap_off, PROT_READ | PROT_WRITE,
                                MAP_PRIVATE, fileno(fp), mmap_off );
-       if ( rcsbuf_buffer == NULL || rcsbuf_buffer == MAP_FAILED )
-           error ( 1, errno, "Could not map memory to RCS archive %s", 
filename );
-
+    if (p != NULL && p != MAP_FAILED)
+    {
+       if (rcsbuf_buffer) free (rcsbuf_buffer);
+       rcsbuf_buffer = p;
        rcsbuf_buffer_size = fs.st_size - mmap_off;
+       rcsbuf->mmapped = 1;
        rcsbuf->ptr = rcsbuf_buffer + pos - mmap_off;
        rcsbuf->ptrend = rcsbuf_buffer + fs.st_size - mmap_off;
        rcsbuf->pos = mmap_off;
     }
-#else /* HAVE_MMAP */
+    else
+    {
+#ifndef MMAP_FALLBACK_TEST
+       error (0, errno, "Could not map memory to RCS archive %s", filename);
+#endif
+#endif /* HAVE_MMAP */
     if (rcsbuf_buffer_size < RCSBUF_BUFSIZE)
        expand_string (&rcsbuf_buffer, &rcsbuf_buffer_size, RCSBUF_BUFSIZE);
 
+       rcsbuf->mmapped = 0;
     rcsbuf->ptr = rcsbuf_buffer;
     rcsbuf->ptrend = rcsbuf_buffer;
     rcsbuf->pos = pos;
+#ifdef HAVE_MMAP
+    }
 #endif /* HAVE_MMAP */
     rcsbuf->fp = fp;
     rcsbuf->filename = filename;
@@ -1086,7 +1107,12 @@
     if (! rcsbuf_inuse)
        error (1, 0, "rcsbuf_close: internal error");
 #ifdef HAVE_MMAP
+    if (rcsbuf->mmapped)
+    {
     munmap ( rcsbuf_buffer, rcsbuf_buffer_size );
+       rcsbuf_buffer = NULL;
+       rcsbuf_buffer_size = 0;
+    }
 #endif
     rcsbuf_inuse = 0;
 }
@@ -1131,11 +1157,10 @@
     assert (ptr >= rcsbuf_buffer && ptr <= rcsbuf_buffer + rcsbuf_buffer_size);
     assert (ptrend >= rcsbuf_buffer && ptrend <= rcsbuf_buffer + 
rcsbuf_buffer_size);
 
-#ifndef HAVE_MMAP
     /* If the pointer is more than RCSBUF_BUFSIZE bytes into the
        buffer, move back to the start of the buffer.  This keeps the
        buffer from growing indefinitely.  */
-    if (ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
+    if (!rcsbuf->mmapped && ptr - rcsbuf_buffer >= RCSBUF_BUFSIZE)
     {
        int len;
 
@@ -1154,23 +1179,18 @@
        ptrend = ptr + len;
        rcsbuf->ptrend = ptrend;
     }
-#endif /* ndef HAVE_MMAP */
 
     /* Skip leading whitespace.  */
 
     while (1)
     {
        if (ptr >= ptrend)
-#ifndef HAVE_MMAP
        {
            ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
            if (ptr == NULL)
-#endif
                return 0;
-#ifndef HAVE_MMAP
            ptrend = rcsbuf->ptrend;
        }
-#endif
 
        c = *ptr;
        if (! my_whitespace (c))
@@ -1189,17 +1209,13 @@
        {
            ++ptr;
            if (ptr >= ptrend)
-#ifndef HAVE_MMAP
            {
                ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL);
                if (ptr == NULL)
-#endif
                    error (1, 0, "EOF in key in RCS file %s",
                           rcsbuf->filename);
-#ifndef HAVE_MMAP
                ptrend = rcsbuf->ptrend;
            }
-#endif
            c = *ptr;
            if (c == ';' || my_whitespace (c))
                break;
@@ -1228,17 +1244,13 @@
     while (1)
     {
        if (ptr >= ptrend)
-#ifndef HAVE_MMAP
        {
            ptr = rcsbuf_fill (rcsbuf, ptr, keyp, (char **) NULL);
            if (ptr == NULL)
-#endif
                error (1, 0, "EOF while looking for value in RCS file %s",
                       rcsbuf->filename);
-#ifndef HAVE_MMAP
            ptrend = rcsbuf->ptrend;
        }
-#endif
        c = *ptr;
        if (c == ';')
        {
@@ -1273,7 +1285,6 @@
        while (1)
        {
            while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
-#ifndef HAVE_MMAP
            {
                /* Note that we pass PTREND as the PTR value to
                    rcsbuf_fill, so that we will wind up setting PTR to
@@ -1281,31 +1292,25 @@
                    that we don't search the same bytes again.  */
                ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
                if (ptr == NULL)
-#endif
                    error (1, 0,
                           "EOF while looking for end of string in RCS file %s",
                           rcsbuf->filename);
-#ifndef HAVE_MMAP
                ptrend = rcsbuf->ptrend;
            }
-#endif
 
            /* Handle the special case of an '@' right at the end of
                the known bytes.  */
            if (pat + 1 >= ptrend)
-#ifndef HAVE_MMAP
            {
                /* Note that we pass PAT, not PTR, here.  */
                pat = rcsbuf_fill (rcsbuf, pat, keyp, valp);
                if (pat == NULL)
                {
-#endif
                    /* EOF here is OK; it just means that the last
                       character of the file was an '@' terminating a
                       value for a key type which does not require a
                       trailing ';'.  */
                    pat = rcsbuf->ptrend - 1;
-#ifndef HAVE_MMAP
 
                }
                ptrend = rcsbuf->ptrend;
@@ -1313,7 +1318,6 @@
                /* Note that the value of PTR is bogus here.  This is
                   OK, because we don't use it.  */
            }
-#endif
 
            if (pat + 1 >= ptrend || pat[1] != '@')
                break;
@@ -1363,17 +1367,13 @@
            char n;
 
            if (ptr >= ptrend)
-#ifndef HAVE_MMAP
            {
                ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp);
                if (ptr == NULL)
-#endif
                    error (1, 0, "EOF in value in RCS file %s",
                           rcsbuf->filename);
-#ifndef HAVE_MMAP
                ptrend = rcsbuf->ptrend;
            }
-#endif
            n = *ptr;
            if (n == ';')
            {
@@ -1408,7 +1408,6 @@
        /* Find the ';' which must end the value.  */
        start = ptr;
        while ((psemi = memchr (ptr, ';', ptrend - ptr)) == NULL)
-#ifndef HAVE_MMAP
        {
            int slen;
 
@@ -1419,13 +1418,10 @@
            slen = start - *valp;
            ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
            if (ptr == NULL)
-#endif
                error (1, 0, "EOF in value in RCS file %s", rcsbuf->filename);
-#ifndef HAVE_MMAP
            start = *valp + slen;
            ptrend = rcsbuf->ptrend;
        }
-#endif
 
        /* See if there are any '@' strings in the value.  */
        pat = memchr (start, '@', psemi - start);
@@ -1469,7 +1465,6 @@
        while (1)
        {
            while ((pat = memchr (ptr, '@', ptrend - ptr)) == NULL)
-#ifndef HAVE_MMAP
            {
                /* Note that we pass PTREND as the PTR value to
                    rcsbuff_fill, so that we will wind up setting PTR
@@ -1477,29 +1472,22 @@
                    that we don't search the same bytes again.  */
                ptr = rcsbuf_fill (rcsbuf, ptrend, keyp, valp);
                if (ptr == NULL)
-#endif
                    error (1, 0,
                           "EOF while looking for end of string in RCS file %s",
                           rcsbuf->filename);
-#ifndef HAVE_MMAP
                ptrend = rcsbuf->ptrend;
            }
-#endif
 
            /* Handle the special case of an '@' right at the end of
                the known bytes.  */
            if (pat + 1 >= ptrend)
-#ifndef HAVE_MMAP
            {
                ptr = rcsbuf_fill (rcsbuf, ptr, keyp, valp);
                if (ptr == NULL)
-#endif
                    error (1, 0, "EOF in value in RCS file %s",
                           rcsbuf->filename);
-#ifndef HAVE_MMAP
                ptrend = rcsbuf->ptrend;
            }
-#endif
 
            if (pat[1] != '@')
                break;
@@ -1542,16 +1530,12 @@
     while (1)
     {
        if (ptr >= ptrend)
-#ifndef HAVE_MMAP
        {
            ptr = rcsbuf_fill (rcsbuf, ptr, (char **) NULL, (char **) NULL);
            if (ptr == NULL)
-#endif
                return 0;
-#ifndef HAVE_MMAP
            ptrend = rcsbuf->ptrend;
        }
-#endif
 
        c = *ptr;
        if (! whitespace (c))
@@ -1572,18 +1556,14 @@
     {
        ++ptr;
        if (ptr >= ptrend)
-#ifndef HAVE_MMAP
        {
            ptr = rcsbuf_fill (rcsbuf, ptr, revp, (char **) NULL);
            if (ptr == NULL)
-#endif
                error (1, 0,
                       "unexpected EOF reading revision number in RCS file %s",
                       rcsbuf->filename);
-#ifndef HAVE_MMAP
            ptrend = rcsbuf->ptrend;
        }
-#endif
 
        c = *ptr;
     }
@@ -1601,7 +1581,6 @@
     return 1;
 }
 
-#ifndef HAVE_MMAP
 /* Fill RCSBUF_BUFFER with bytes from the file associated with RCSBUF,
    updating PTR and the PTREND field.  If KEYP and *KEYP are not NULL,
    then *KEYP points into the buffer, and must be adjusted if the
@@ -1617,6 +1596,9 @@
 {
     int got;
 
+    if (rcsbuf->mmapped)
+       return NULL;
+
     if (rcsbuf->ptrend - rcsbuf_buffer + RCSBUF_BUFSIZE > rcsbuf_buffer_size)
     {
        int poff, peoff, koff, voff;
@@ -1649,7 +1631,6 @@
 
     return ptr;
 }
-#endif /* HAVE_MMAP */
 
 /* Test whether the last value returned by rcsbuf_getkey is a composite
    value or not. */
@@ -2027,8 +2008,7 @@
     FILE **pfp;
     struct rcsbuffer *prcsbuf;
 {
-#ifndef HAVE_MMAP
-    if (cached_rcs == rcs)
+    if (cached_rcs == rcs && !cached_rcsbuf.mmapped)
     {
        if (rcsbuf_ftell (&cached_rcsbuf) != pos)
        {
@@ -2058,7 +2038,6 @@
     }
     else
     {
-#endif /* ifndef HAVE_MMAP */
        /* FIXME:  If these routines can be rewritten to not write to the
         * rcs file buffer, there would be a considerably larger memory savings
         * from using mmap since the shared file would never need be copied to
@@ -2073,17 +2052,13 @@
        *pfp = CVS_FOPEN (rcs->path, FOPEN_BINARY_READ);
        if (*pfp == NULL)
            error (1, 0, "unable to reopen `%s'", rcs->path);
-#ifndef HAVE_MMAP
        if (pos != 0)
        {
            if (fseek (*pfp, pos, SEEK_SET) != 0)
                error (1, 0, "cannot fseek RCS file %s", rcs->path);
        }
-#endif /* ifndef HAVE_MMAP */
        rcsbuf_open (prcsbuf, *pfp, rcs->path, pos);
-#ifndef HAVE_MMAP
     }
-#endif /* ifndef HAVE_MMAP */
 }
 
 
@@ -8432,10 +8407,8 @@
     char *bufrest;
     int nls;
     size_t buflen;
-#ifndef HAVE_MMAP
     char buf[8192];
     int got;
-#endif
 
     /* Count the number of versions for which we have to do some
        special operation.  */
@@ -8549,7 +8522,8 @@
 
        fwrite (bufrest, 1, buflen, fout);
     }
-#ifndef HAVE_MMAP
+    if (!rcsbufin->mmapped)
+    {
     /* This bit isn't necessary when using mmap since the entire file
      * will already be available via the RCS buffer.  Besides, the
      * mmap code doesn't always keep the file pointer up to date, so
@@ -8571,7 +8545,7 @@
 
        nls = 0;
     }
-#endif /* HAVE_MMAP */
+    }
 }
 
 /* A helper procedure for RCS_copydeltas.  This is called via walklist




reply via email to

[Prev in Thread] Current Thread [Next in Thread]