Back to index

glibc  2.9
tst-mmap.c
Go to the documentation of this file.
00001 #include <assert.h>
00002 #include <errno.h>
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <unistd.h>
00006 #include <sys/mman.h>
00007 
00008 
00009 int
00010 main (void)
00011 {
00012   int result = 0;
00013   FILE *fp;
00014   size_t c;
00015   char buf[1000];
00016   int fd;
00017   unsigned char *ptr;
00018   size_t ps = sysconf (_SC_PAGESIZE);
00019   void *mem;
00020 
00021   /* Create a file and put some data in it.  */
00022   fp = tmpfile ();
00023   if (fp == NULL)
00024     {
00025       printf ("Cannot create temporary file: %m\n");
00026       return 1;
00027     }
00028   fd = fileno (fp);
00029 
00030   for (c = 0; c < sizeof (buf); ++c)
00031     buf[c] = '0' + (c % 10);
00032 
00033   for (c = 0; c < (ps * 4) / sizeof (buf); ++c)
00034     if (fwrite (buf, 1, sizeof (buf), fp) != sizeof (buf))
00035       {
00036        printf ("`fwrite' failed: %m\n");
00037        return 1;
00038       }
00039   fflush (fp);
00040   assert (ps + 1000 < c * sizeof (buf));
00041 
00042   /* First try something which is not allowed: map at an offset which is
00043      not modulo the pagesize.  */
00044   ptr = mmap (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps - 1);
00045   if (ptr != MAP_FAILED)
00046     {
00047       puts ("mapping at offset with mod pagesize != 0 succeeded!");
00048       result = 1;
00049     }
00050   else if (errno != EINVAL && errno != ENOSYS)
00051     {
00052       puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
00053       result = 1;
00054     }
00055 
00056   /* Try the same for mmap64.  */
00057   ptr = mmap64 (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps - 1);
00058   if (ptr != MAP_FAILED)
00059     {
00060       puts ("mapping at offset with mod pagesize != 0 succeeded!");
00061       result = 1;
00062     }
00063   else if (errno != EINVAL && errno != ENOSYS)
00064     {
00065       puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
00066       result = 1;
00067     }
00068 
00069   /* And the same for private mapping.  */
00070   ptr = mmap (NULL, 1000, PROT_READ, MAP_PRIVATE, fd, ps - 1);
00071   if (ptr != MAP_FAILED)
00072     {
00073       puts ("mapping at offset with mod pagesize != 0 succeeded!");
00074       result = 1;
00075     }
00076   else if (errno != EINVAL && errno != ENOSYS)
00077     {
00078       puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
00079       result = 1;
00080     }
00081 
00082   /* Try the same for mmap64.  */
00083   ptr = mmap64 (NULL, 1000, PROT_READ, MAP_PRIVATE, fd, ps - 1);
00084   if (ptr != MAP_FAILED)
00085     {
00086       puts ("mapping at offset with mod pagesize != 0 succeeded!");
00087       result = 1;
00088     }
00089   else if (errno != EINVAL && errno != ENOSYS)
00090     {
00091       puts ("wrong error value for mapping at offset with mod pagesize != 0: %m (should be EINVAL)");
00092       result = 1;
00093     }
00094 
00095   /* Get a valid address.  */
00096   mem = malloc (2 * ps);
00097   if (mem != NULL)
00098     {
00099       /* Now we map at an address which is not mod pagesize.  */
00100       ptr = mmap (mem + 1, 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, ps);
00101       if (ptr != MAP_FAILED)
00102        {
00103          puts ("mapping at address with mod pagesize != 0 succeeded!");
00104          result = 1;
00105        }
00106       else  if (errno != EINVAL && errno != ENOSYS)
00107        {
00108          puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
00109          result = 1;
00110        }
00111 
00112       /* Try the same for mmap64.  */
00113       ptr = mmap64 (mem + 1, 1000, PROT_READ, MAP_SHARED | MAP_FIXED, fd, ps);
00114       if (ptr != MAP_FAILED)
00115        {
00116          puts ("mapping at address with mod pagesize != 0 succeeded!");
00117          result = 1;
00118        }
00119       else  if (errno != EINVAL && errno != ENOSYS)
00120        {
00121          puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
00122          result = 1;
00123        }
00124 
00125       /* And again for MAP_PRIVATE.  */
00126       ptr = mmap (mem + 1, 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ps);
00127       if (ptr != MAP_FAILED)
00128        {
00129          puts ("mapping at address with mod pagesize != 0 succeeded!");
00130          result = 1;
00131        }
00132       else  if (errno != EINVAL && errno != ENOSYS)
00133        {
00134          puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
00135          result = 1;
00136        }
00137 
00138       /* Try the same for mmap64.  */
00139       ptr = mmap64 (mem + 1, 1000, PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, ps);
00140       if (ptr != MAP_FAILED)
00141        {
00142          puts ("mapping at address with mod pagesize != 0 succeeded!");
00143          result = 1;
00144        }
00145       else  if (errno != EINVAL && errno != ENOSYS)
00146        {
00147          puts ("wrong error value for mapping at address with mod pagesize != 0: %m (should be EINVAL)");
00148          result = 1;
00149        }
00150 
00151       free (mem);
00152     }
00153 
00154   /* Now map the memory and see whether the content of the mapped area
00155      is correct.  */
00156   ptr = mmap (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps);
00157   if (ptr == MAP_FAILED)
00158     {
00159       if (errno != ENOSYS)
00160        {
00161          printf ("cannot mmap file: %m\n");
00162          result = 1;
00163        }
00164     }
00165   else
00166     {
00167       for (c = ps; c < ps + 1000; ++c)
00168        if (ptr[c - ps] != '0' + (c % 10))
00169          {
00170            printf ("wrong data mapped at offset %zd\n", c);
00171            result = 1;
00172          }
00173     }
00174 
00175   /* And for mmap64. */
00176   ptr = mmap64 (NULL, 1000, PROT_READ, MAP_SHARED, fd, ps);
00177   if (ptr == MAP_FAILED)
00178     {
00179       if (errno != ENOSYS)
00180        {
00181          printf ("cannot mmap file: %m\n");
00182          result = 1;
00183        }
00184     }
00185   else
00186     {
00187       for (c = ps; c < ps + 1000; ++c)
00188        if (ptr[c - ps] != '0' + (c % 10))
00189          {
00190            printf ("wrong data mapped at offset %zd\n", c);
00191            result = 1;
00192          }
00193     }
00194 
00195   /* That's it.  */
00196   return result;
00197 }