Ne.app NeANT
The Ne.app NeANT User module of the NeANT distribution.
mman.cpp
Go to the documentation of this file.
1
29#define _RWSTD_LIB_SRC
30#include <rw/_defs.h>
31
32#ifndef _MSC_VER
33 // <unistd.h> is included here because of PR #26255
34# include <unistd.h>
35#endif // _MSC_VER
36
37#include <sys/stat.h>
38
39#ifndef _RWSTD_NO_MMAP
40# include <sys/mman.h>
41#elif defined (_WIN32)
42# include <windows.h>
43# include <io.h>
44#endif // _MSC_VER
45
46#include <sys/types.h>
47#include <fcntl.h>
48
49
51
52
53// maps a named file into memory as shared, read-only, returns
54// the beginning address on success and fills `size' with the
55// size of the file; returns 0 on failure
56void* __rw_mmap (const char* fname, _RWSTD_SIZE_T *size)
57{
58 _RWSTD_ASSERT (0 != fname);
59 _RWSTD_ASSERT (0 != size);
60
61#if !defined (_MSC_VER)
62 struct stat sb;
63 if (stat (fname, &sb) == -1)
64#else
65 struct _stat sb;
66 if (_stat (fname, &sb) == -1)
67#endif
68 return 0;
69
70 *size = sb.st_size;
71
72
73#ifndef _WIN32
74 const int fd = open (fname, O_RDONLY);
75
76 if (-1 == fd)
77 return 0;
78
79#endif // _WIN32
80
81#ifndef _RWSTD_NO_MMAP
82
83 // On HPUX systems MAP_SHARED will prevent a second mapping of the same
84 // file if the regions are overlapping; one solution is to make the
85 // mapping private.
86#if defined(__hpux)
87 void *data = mmap (0, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
88#else
89 void *data = mmap (0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
90#endif // defined(__hpux__)
91
92 close (fd);
93
94#ifndef MAP_FAILED
95# define MAP_FAILED (void*)-1
96#endif
97
98 if (MAP_FAILED == data) // failure
99 return 0;
100
101#elif defined (_WIN32)
102
103 HANDLE mmf =
104 CreateFile (fname, GENERIC_READ, FILE_SHARE_READ, NULL,
105 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
106
107 if (mmf == INVALID_HANDLE_VALUE)
108 return 0;
109
110 HANDLE mmfv =
111 CreateFileMapping (mmf, NULL, PAGE_READONLY, 0, 0, NULL);
112 if (mmfv == INVALID_HANDLE_VALUE) {
113 CloseHandle (mmf);
114 return 0;
115 }
116
117 void * data =
118 MapViewOfFile (mmfv, FILE_MAP_READ, 0, 0, sb.st_size);
119
120 // The handles can be safely closed
121 CloseHandle (mmf);
122 CloseHandle (mmfv);
123
124#else // no mmap() or equivalent
125
126# ifndef _RWSTD_NO_MUNMAP
127# define _RWSTD_NO_MUNMAP
128# endif // _RWSTD_NO_MUNMAP
129
130 // read() takes a size_t argument, convert off_t to it
131 const size_t mapsize = size_t (sb.st_size);
132
133 void* data = operator new (mapsize);
134 const ssize_t nread = read (fd, data, mapsize);
135
136 if (size_t (nread) != mapsize) {
137 operator delete (data);
138 data = 0;
139 }
140
141#endif // _MSC_VER
142
143 return data;
144}
145
146
147void __rw_munmap (const void* pcv, _RWSTD_SIZE_T size)
148{
149 _RWSTD_ASSERT (pcv && size);
150
151 // cast first to void*
152 void* pv = _RWSTD_CONST_CAST (void*, pcv);
153
154 // POSIX munmap() takes a void*, but not all platforms conform
155#ifndef _RWSTD_NO_MUNMAP
156 munmap (_RWSTD_STATIC_CAST (_RWSTD_MUNMAP_ARG1_T, pv), size);
157#elif defined (_WIN32)
158 UnmapViewOfFile (pv);
159#else // no munmap()
160 operator delete (pv);
161#endif // _MSC_VER
162}
163
164
165} // namespace __rw
#define sb
Definition 17.names.cpp:542
const char *const data[]
#define open(f, m)
#define close(f)
#define NULL
#define _RWSTD_STATIC_CAST(T, x)
Definition _defs.h:534
#define _RWSTD_NAMESPACE(name)
Definition _defs.h:567
#define _RWSTD_ASSERT(ignore)
Definition _defs.h:1108
#define _RWSTD_CONST_CAST(T, x)
Definition _defs.h:536
#define MAP_PRIVATE
Definition alloc.cpp:166
#define MAP_FAILED