2002-08-22 Roland McGrath <roland@redhat.com>
+ * locale/loadarchive.c (_nl_load_locale_from_archive): Check max file
+ position indicated by locrectab against file bounds before rounding to
+ page size. In mapping loop, always set TO before breaking out of
+ contiguous range coalescing loop.
+
+ * locale/loadarchive.c (_nl_load_locale_from_archive): Use MAP_PRIVATE
+ (or MAP_COPY if available) instead of MAP_SHARED.
+
* scripts/firstversions.awk: When encountering a version newer than
the specified earliest version, be sure to emit the specified earliest
version first if any renaming of an older version to that has been.
cover the header plus the initial locale. */
#define ARCHIVE_MAPPING_WINDOW (2 * 1024 * 1024)
+#ifndef MAP_COPY
+/* This is not quite as good as MAP_COPY since unexamined pages
+ can change out from under us and give us inconsistent data.
+ But we rely on the user not to diddle the system's live archive.
+ Even though we only ever use PROT_READ, using MAP_SHARED would
+ not give the system sufficient freedom to e.g. let the on disk
+ file go away because it doesn't know we won't call mprotect later. */
+# define MAP_COPY MAP_PRIVATE
+#endif
+#ifndef MAP_FILE
+ /* Some systems do not have this flag; it is superfluous. */
+# define MAP_FILE 0
+#endif
/* Record of contiguous pages already mapped from the locale archive. */
struct archmapped
mapsize = (sizeof (void *) > 4 ? archive_stat.st_size
: MIN (archive_stat.st_size, ARCHIVE_MAPPING_WINDOW));
- result = __mmap64 (NULL, mapsize, PROT_READ, MAP_SHARED, fd, 0);
+ result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY, fd, 0);
if (result == MAP_FAILED)
goto close_and_out;
/* Freakishly long header. */
/* XXX could use mremap when available */
mapsize = (headsize + ps - 1) & ~(ps - 1);
- result = __mmap64 (NULL, mapsize, PROT_READ, MAP_SHARED, fd, 0);
+ result = __mmap64 (NULL, mapsize, PROT_READ, MAP_FILE|MAP_COPY,
+ fd, 0);
if (result == MAP_FAILED)
goto close_and_out;
}
upper = cnt;
do
{
+ to = ranges[upper].from + ranges[upper].len;
+ if (to > archive_stat.st_size)
+ /* The archive locrectab contains bogus offsets. */
+ return NULL;
+ to = (to + ps - 1) & ~(ps - 1);
+
/* If a range is already mmaped in, stop. */
if (mapped != NULL && ranges[upper].from >= mapped->from)
break;
- to = ((ranges[upper].from + ranges[upper].len + ps - 1)
- & ~(ps - 1));
+
++upper;
}
/* Loop while still in contiguous pages. */
while (upper < nranges && ranges[upper].from < to + ps);
- if (to > archive_stat.st_size)
- /* The archive locrectab contains bogus offsets. */
- return NULL;
-
/* Open the file if it hasn't happened yet. */
if (fd == -1)
{
}
/* Map the range from the archive. */
- addr = __mmap64 (NULL, to - from, PROT_READ, MAP_SHARED, fd, from);
+ addr = __mmap64 (NULL, to - from, PROT_READ, MAP_FILE|MAP_COPY,
+ fd, from);
if (addr == MAP_FAILED)
return NULL;