Imported Upstream version 5.3.21
[platform/upstream/libdb.git] / dist / aclocal / mmap.m4
1 # Copyright (c) 2011, 2012 Oracle and/or its affiliates.  All rights reserved.
2
3 # Detect mmap capability: If the file underlying an mmap is extended,
4 # does the addressable memory grow too?
5 AC_DEFUN(AM_MMAP_EXTEND, [
6
7     AH_TEMPLATE(HAVE_MMAP_EXTEND, [Define to 1 where mmap() incrementally extends the accessible mapping as the underlying file grows.])
8
9
10 if test "$mmap_ok" = "yes" ; then 
11     AC_MSG_CHECKING([for growing a file under an mmap region])
12
13     db_cv_mmap_extend="no"
14
15     AC_TRY_RUN([
16     /*
17      *  Most mmap() implemenations allow you to map in a region which is much
18      *  larger than the underlying file. Only the second less than the actual
19      *  file size is accessible -- a SIGSEV typically results when attemping
20      *  a memory reference between EOF and the end of the mapped region.
21      *  One can extend the file to allow references into higher-addressed
22      *  sections of the region. However this automatic extension of the
23      *  addressible memory is beyond what POSIX requires. This function detects
24      *  whether mmap supports this automatic extension. If not (e.g. cygwin)
25      *  then the entire (hopefully sparse) file will need to be written before
26      *  the first mmap.
27      */
28     /* Not all these includes are needed, but the minimal set varies from
29      * system to system.
30      */
31     #include <stdio.h>
32     #include <string.h>
33     #include <sys/types.h>
34     #include <sys/stat.h>
35     #include <fcntl.h>
36     #include <sys/mman.h>
37     #include <signal.h>
38
39     #define TEST_MMAP_BUFSIZE   (16 * 1024)
40     #define TEST_MMAP_EXTENDSIZE        (16 * 1024 * 1024)
41     #ifndef MAP_FAILED
42     #define MAP_FAILED (-1)
43     #endif
44
45     int catch_sig(sig)
46             int sig;
47     {
48             exit(1);
49     }
50
51     main() {
52             const char *underlying;
53             unsigned gapsize;
54             char *base;
55             int count, fd, i, mode, open_flags, ret, total_size;
56             char buf[TEST_MMAP_BUFSIZE];
57
58             gapsize = 1024;
59             underlying = ".mmap_config";
60             (void) unlink(underlying);
61
62             open_flags = O_CREAT | O_TRUNC | O_RDWR;
63             mode = S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH;
64
65             if ((fd = open(underlying, open_flags, mode)) < 0) {
66                     perror("open");
67                     return (1);
68             }
69
70             total_size = TEST_MMAP_EXTENDSIZE;
71
72             memset(buf, 0, sizeof(buf));
73             if ((count = write(fd, buf, sizeof(buf))) != sizeof(buf)) {
74                     perror("initial write");
75                     return (2);
76             }
77
78             if ((base = mmap(NULL, total_size,
79                 PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) {
80                     perror("mmap");
81                     return (3);
82             }
83
84             /* Extend the file with just 1 byte */
85             if (lseek(fd, total_size - 1, SEEK_SET) < 0 ||
86                 (count = write(fd, buf, 1)) != 1) {
87                     perror("extending write");
88                     return (4);
89             }
90
91             (void) signal(SIGSEGV, catch_sig);
92             (void) signal(SIGBUS, catch_sig);
93
94             for (i = sizeof(buf); i < total_size; i += gapsize)
95                     base[i] = 'A';
96
97             close(fd);
98             (void) unlink(underlying);
99             return (0);
100     }], [db_cv_mmap_extend="yes"],[db_cv_mmap_extend="no"],[db_cv_mmap_extend="no"])
101
102
103     if test "$db_cv_mmap_extend" = yes; then
104             AC_DEFINE(HAVE_MMAP_EXTEND)
105     fi
106     AC_MSG_RESULT($db_cv_mmap_extend)
107 fi
108 ])
109