#if defined(HAVE_MMAP) && !defined(NO_MMAP)
void *chunk;
+ size_t off;
+
+#define BLOCKSIZE (1024 * 1024 * 10)
#ifndef MAP_FAILED
#define MAP_FAILED (-1)
*/
if (st.st_size == 0)
return 0;
- chunk = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fileno (from), 0);
- if (chunk != (void *) MAP_FAILED) {
- int res;
-
- res = sec_write (fileno (to), chunk, st.st_size);
+ off = 0;
+ while (off != st.st_size) {
+ size_t len;
+ ssize_t res;
+
+ len = st.st_size - off;
+ if (len > BLOCKSIZE)
+ len = BLOCKSIZE;
+
+ chunk = mmap (0, len, PROT_READ, MAP_SHARED, fileno (from), off);
+ if (chunk == (void *) MAP_FAILED) {
+ if (off == 0) /* try read if mmap doesn't work */
+ goto try_read;
+ break;
+ }
+
+ res = sec_write (fileno (to), chunk, len);
if (munmap (chunk, st.st_size) < 0)
warn ("munmap");
sec_fflush (to);
- return res;
+ if (res != len)
+ return off;
+ off += len;
}
+ return off;
}
+try_read:
#endif
buf = alloc_buffer (buf, &bufsize,