[Top][All Lists]
[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