Changes to attempt to silence bcc64x
[ACE_TAO.git] / ACE / ace / Mem_Map.cpp
blob47ae0955ae9b90d81e8a804e775e887817ed7829
1 // Defines the member functions for the memory mapping facility.
3 #include "ace/Mem_Map.h"
5 #if !defined (__ACE_INLINE__)
6 #include "ace/Mem_Map.inl"
7 #endif /* __ACE_INLINE__ */
9 #include "ace/OS_NS_sys_stat.h"
10 #include "ace/OS_NS_fcntl.h"
11 #include "ace/OS_NS_string.h"
12 #include "ace/Log_Category.h"
13 #include "ace/Truncate.h"
14 #if defined (ACE_HAS_ALLOC_HOOKS)
15 # include "ace/Malloc_Base.h"
16 #endif /* ACE_HAS_ALLOC_HOOKS */
18 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
20 ACE_ALLOC_HOOK_DEFINE(ACE_Mem_Map)
22 void
23 ACE_Mem_Map::dump () const
25 #if defined (ACE_HAS_DUMP)
26 ACE_TRACE ("ACE_Mem_Map::dump");
28 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
29 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("base_addr_ = %x"), this->base_addr_));
30 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nfilename_ = %s"), this->filename_));
31 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nlength_ = %d"), this->length_));
32 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nhandle_ = %d"), this->handle_));
33 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nfile_mapping_ = %d"), this->file_mapping_));
34 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nclose_handle_ = %d"), this->close_handle_));
35 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
36 #endif /* ACE_HAS_DUMP */
39 int
40 ACE_Mem_Map::close ()
42 ACE_TRACE ("ACE_Mem_Map::close");
44 this->unmap ();
46 return this->close_handle ();
49 ACE_Mem_Map::~ACE_Mem_Map ()
51 ACE_TRACE ("ACE_Mem_Map::~ACE_Mem_Map");
53 this->close ();
56 // This function does the dirty work of actually calling ACE_OS::mmap
57 // to map the file into memory.
59 int
60 ACE_Mem_Map::map_it (ACE_HANDLE handle,
61 size_t length_request,
62 int prot,
63 int share,
64 void *addr,
65 ACE_OFF_T offset,
66 LPSECURITY_ATTRIBUTES sa)
68 ACE_TRACE ("ACE_Mem_Map::map_it");
70 #if defined (ACE_LACKS_AUTO_MMAP_REPLACEMENT)
71 // If the system does not replace any previous mappings, then
72 // unmap() before (potentially) mapping to the same location.
73 int const unmap_result = this->unmap ();
74 if (unmap_result != 0)
75 return unmap_result;
76 #endif /* ACE_LACKS_AUTO_MMAP_REPLACEMENT */
78 this->base_addr_ = addr;
79 this->handle_ = handle;
81 // mmap through character device doens't care about it's size
82 // So map with /dev/* is done with a special case.
83 ACE_stat current_file_type;
84 int result = ACE_OS::fstat (this->handle_, &current_file_type);
86 if (result == -1)
88 // Something wrong found, bail out.
89 return -1;
91 else if ((current_file_type.st_mode & S_IFMT) == S_IFCHR)
93 // Set length to length_request
94 this->length_ = length_request;
96 else if ((current_file_type.st_mode & S_IFMT) == S_IFREG)
98 // Get the current filesize
99 ACE_OFF_T const current_file_length = ACE_OS::filesize (this->handle_);
101 // Flag to indicate if we need to extend the back store
102 bool extend_backing_store = false;
104 // File length requested by user
105 ACE_OFF_T requested_file_length = 0;
107 // Check <length_request>
108 if (length_request == static_cast<size_t> (-1))
110 // Set length to file_request or size_t max.
111 this->length_ = ACE_Utils::truncate_cast<size_t> (current_file_length - offset);
112 #if defined (ACE_MMAP_NO_ZERO)
113 if (this->length_ == 0)
115 this->length_ = ACE_OS::getpagesize ();
117 #endif /* ACE_MMAP_NO_ZERO */
119 else
121 // Make sure that we have not been asked to do the impossible.
122 if (static_cast<ACE_UINT64> (length_request)
123 + static_cast<ACE_UINT64> (offset)
124 > static_cast<ACE_UINT64> (ACE_Numeric_Limits<ACE_OFF_T>::max ()))
125 return -1;
127 // File length implicitly requested by user
128 requested_file_length = static_cast<ACE_OFF_T> (length_request) + offset;
130 // Check to see if we need to extend the backing store
131 if (requested_file_length > current_file_length)
133 // If the length of the mapped region is less than the
134 // length of the file then we force a complete new remapping
135 // by setting the descriptor to ACE_INVALID_HANDLE (closing
136 // down the descriptor if necessary).
137 this->close_filemapping_handle ();
139 // Remember to extend the backing store
140 extend_backing_store = true;
143 // Set length to length_request
144 this->length_ = length_request;
147 // Check if we need to extend the backing store.
148 if (extend_backing_store)
150 // Remember than write increases the size by one.
151 ACE_OFF_T null_byte_position = 0;
152 if (requested_file_length > 0)
154 // This will make the file size <requested_file_length>
155 null_byte_position = requested_file_length - 1;
158 if (ACE_OS::pwrite (this->handle_,
161 null_byte_position) == -1)
162 return -1;
165 else
166 // Unmappable file type.
167 return -1;
169 this->base_addr_ = ACE_OS::mmap (this->base_addr_,
170 this->length_,
171 prot,
172 share,
173 this->handle_,
174 offset,
175 &this->file_mapping_,
176 sa);
178 return this->base_addr_ == MAP_FAILED ? -1 : 0;
182 ACE_Mem_Map::open (const ACE_TCHAR *file_name,
183 int flags,
184 mode_t perms,
185 LPSECURITY_ATTRIBUTES sa)
187 ACE_TRACE ("ACE_Mem_Map::open");
189 #if defined (INTEGRITY) || defined (__QNXNTO__) || defined (ACE_VXWORKS)
190 this->handle_ = ACE_OS::shm_open (file_name, flags, perms, sa);
191 #else
192 this->handle_ = ACE_OS::open (file_name, flags, perms, sa);
193 #endif /* INTEGRITY */
195 if (this->handle_ == ACE_INVALID_HANDLE)
196 return -1;
197 else
199 ACE_OS::strsncpy (this->filename_,
200 file_name,
201 MAXPATHLEN);
203 this->close_handle_ = true;
204 return 0;
209 ACE_Mem_Map::map (const ACE_TCHAR *file_name,
210 size_t len,
211 int flags,
212 mode_t mode,
213 int prot,
214 int share,
215 void *addr,
216 ACE_OFF_T offset,
217 LPSECURITY_ATTRIBUTES sa)
219 ACE_TRACE ("ACE_Mem_Map::map");
220 this->length_ = 0;
222 if (this->open (file_name,
223 flags,
224 mode,
225 sa) == -1)
226 return -1;
227 else
228 return this->map_it (this->handle (),
229 len,
230 prot,
231 share,
232 addr,
233 offset,
234 sa);
237 ACE_Mem_Map::ACE_Mem_Map ()
238 : base_addr_ (MAP_FAILED),
239 length_ (0),
240 handle_ (ACE_INVALID_HANDLE),
241 file_mapping_ (ACE_INVALID_HANDLE),
242 close_handle_ (false)
244 ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
245 ACE_OS::memset (this->filename_, 0, sizeof this->filename_);
248 // Map a file specified by FILE_NAME.
249 ACE_Mem_Map::ACE_Mem_Map (const ACE_TCHAR *file_name,
250 size_t len,
251 int flags,
252 mode_t mode,
253 int prot,
254 int share,
255 void *addr,
256 ACE_OFF_T offset,
257 LPSECURITY_ATTRIBUTES sa)
258 : base_addr_ (MAP_FAILED),
259 length_ (0),
260 handle_ (ACE_INVALID_HANDLE),
261 file_mapping_ (ACE_INVALID_HANDLE),
262 close_handle_ (false)
264 ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
265 if (this->map (file_name,
266 len,
267 flags,
268 mode,
269 prot,
270 share,
271 addr,
272 offset,
273 sa) < 0)
274 ACELIB_ERROR ((LM_ERROR,
275 ACE_TEXT ("%p\n"),
276 ACE_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
279 // Map a file from an open file descriptor HANDLE. This function will
280 // lookup the length of the file if it is not given.
281 ACE_Mem_Map::ACE_Mem_Map (ACE_HANDLE handle,
282 size_t len,
283 int prot,
284 int share,
285 void *addr,
286 ACE_OFF_T offset,
287 LPSECURITY_ATTRIBUTES sa)
288 : base_addr_ (MAP_FAILED),
289 length_ (0),
290 handle_ (ACE_INVALID_HANDLE),
291 file_mapping_ (ACE_INVALID_HANDLE),
292 close_handle_ (false)
294 ACE_TRACE ("ACE_Mem_Map::ACE_Mem_Map");
296 ACE_OS::memset (this->filename_,
298 sizeof this->filename_);
299 if (this->map (handle,
300 len,
301 prot,
302 share,
303 addr,
304 offset,
305 sa) < 0)
306 ACELIB_ERROR ((LM_ERROR,
307 ACE_TEXT ("%p\n"),
308 ACE_TEXT ("ACE_Mem_Map::ACE_Mem_Map")));
311 // Close down and remove the file from the file system.
314 ACE_Mem_Map::remove ()
316 ACE_TRACE ("ACE_Mem_Map::remove");
318 ACE_OS::ftruncate (this->handle_, 0);
319 this->close ();
321 if (this->filename_[0] != '\0')
322 #if defined (INTEGRITY) || defined (__QNXNTO__) || defined (ACE_VXWORKS)
323 return ACE_OS::shm_unlink (this->filename_);
324 #else
325 return ACE_OS::unlink (this->filename_);
326 #endif /* __QNXNTO__ */
328 else
329 return 0;
332 ACE_END_VERSIONED_NAMESPACE_DECL