Line data Source code
1 : //////////////////////////////////////////////////////////////////////////////
2 : //
3 : // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
4 : // Software License, Version 1.0. (See accompanying file
5 : // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 : //
7 : // See http://www.boost.org/libs/interprocess for documentation.
8 : //
9 : //////////////////////////////////////////////////////////////////////////////
10 :
11 : #ifndef BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP
12 : #define BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP
13 :
14 : #ifndef BOOST_CONFIG_HPP
15 : # include <boost/config.hpp>
16 : #endif
17 : #
18 : #if defined(BOOST_HAS_PRAGMA_ONCE)
19 : # pragma once
20 : #endif
21 :
22 : #include <boost/interprocess/detail/config_begin.hpp>
23 : #include <boost/interprocess/detail/workaround.hpp>
24 : #include <boost/interprocess/errors.hpp>
25 : #include <boost/interprocess/permissions.hpp>
26 :
27 : #include <string>
28 : #include <limits>
29 : #include <climits>
30 : #include <boost/move/detail/type_traits.hpp> //make_unsigned
31 :
32 : #if defined (BOOST_INTERPROCESS_WINDOWS)
33 : # include <boost/interprocess/detail/win32_api.hpp>
34 : #else
35 : # ifdef BOOST_HAS_UNISTD_H
36 : # include <fcntl.h>
37 : # include <unistd.h>
38 : # include <sys/types.h>
39 : # include <sys/stat.h>
40 : # include <errno.h>
41 : # include <cstdio>
42 : # include <dirent.h>
43 : # if 0
44 : # include <sys/file.h>
45 : # endif
46 : # else
47 : # error Unknown platform
48 : # endif
49 : #endif
50 :
51 : #include <cstring>
52 : #include <cstdlib>
53 :
54 : namespace boost {
55 : namespace interprocess {
56 :
57 : #if defined (BOOST_INTERPROCESS_WINDOWS)
58 :
59 : typedef void * file_handle_t;
60 : typedef __int64 offset_t;
61 : typedef struct mapping_handle_impl_t{
62 : void * handle;
63 : bool is_shm;
64 : } mapping_handle_t;
65 :
66 : typedef enum { read_only = winapi::generic_read
67 : , read_write = winapi::generic_read | winapi::generic_write
68 : , copy_on_write
69 : , read_private
70 : , invalid_mode = 0xffff
71 : } mode_t;
72 :
73 : typedef enum { file_begin = winapi::file_begin
74 : , file_end = winapi::file_end
75 : , file_current = winapi::file_current
76 : } file_pos_t;
77 :
78 : typedef unsigned long map_options_t;
79 : static const map_options_t default_map_options = map_options_t(-1);
80 :
81 : namespace ipcdetail{
82 :
83 : inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
84 : {
85 : mapping_handle_t ret;
86 : ret.handle = hnd;
87 : ret.is_shm = false;
88 : return ret;
89 : }
90 :
91 : inline mapping_handle_t mapping_handle_from_shm_handle(file_handle_t hnd)
92 : {
93 : mapping_handle_t ret;
94 : ret.handle = hnd;
95 : ret.is_shm = true;
96 : return ret;
97 : }
98 :
99 : inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
100 : { return hnd.handle; }
101 :
102 : inline bool create_directory(const char *path)
103 : { return winapi::create_directory(path); }
104 :
105 : inline bool remove_directory(const char *path)
106 : { return winapi::remove_directory(path); }
107 :
108 : inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
109 : {
110 : required_len = 0;
111 : //std::size_t is always bigger or equal than unsigned long in Windows systems
112 : //In case std::size_t is bigger than unsigned long
113 : unsigned long buf = buf_len;
114 : if(buf_len != buf){ //maybe overflowed
115 : return false;
116 : }
117 : required_len = winapi::get_temp_path(buf_len, buffer);
118 : const bool ret = !(buf_len < required_len);
119 : if(ret && buffer[required_len-1] == '\\'){
120 : buffer[required_len-1] = 0;
121 : }
122 : return ret;
123 : }
124 :
125 : inline file_handle_t create_new_file
126 : (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
127 : {
128 : unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
129 : return winapi::create_file
130 : ( name, (unsigned int)mode, winapi::create_new, attr
131 : , (winapi::interprocess_security_attributes*)perm.get_permissions());
132 : }
133 :
134 : inline file_handle_t create_or_open_file
135 : (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
136 : {
137 : unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
138 : return winapi::create_file
139 : ( name, (unsigned int)mode, winapi::open_always, attr
140 : , (winapi::interprocess_security_attributes*)perm.get_permissions());
141 : }
142 :
143 : inline file_handle_t open_existing_file
144 : (const char *name, mode_t mode, bool temporary = false)
145 : {
146 : unsigned long attr = temporary ? winapi::file_attribute_temporary : 0;
147 : return winapi::create_file
148 : (name, (unsigned int)mode, winapi::open_existing, attr, 0);
149 : }
150 :
151 : inline bool delete_file(const char *name)
152 : { return winapi::unlink_file(name); }
153 :
154 : inline bool truncate_file (file_handle_t hnd, std::size_t size)
155 : {
156 : offset_t filesize;
157 : if(!winapi::get_file_size(hnd, filesize))
158 : return false;
159 :
160 : typedef ::boost::move_detail::make_unsigned<offset_t>::type uoffset_t;
161 : const uoffset_t max_filesize = uoffset_t((std::numeric_limits<offset_t>::max)());
162 : const uoffset_t uoff_size = uoffset_t(size);
163 : //Avoid unused variable warnings in 32 bit systems
164 : if(uoff_size > max_filesize){
165 : winapi::set_last_error(winapi::error_file_too_large);
166 : return false;
167 : }
168 :
169 : if(offset_t(size) > filesize){
170 : if(!winapi::set_file_pointer_ex(hnd, filesize, 0, winapi::file_begin)){
171 : return false;
172 : }
173 : //We will write zeros in the end of the file
174 : //since set_end_of_file does not guarantee this
175 : for(std::size_t remaining = size - filesize, write_size = 0
176 : ;remaining > 0
177 : ;remaining -= write_size){
178 : const std::size_t DataSize = 512;
179 : static char data [DataSize];
180 : write_size = DataSize < remaining ? DataSize : remaining;
181 : unsigned long written;
182 : winapi::write_file(hnd, data, (unsigned long)write_size, &written, 0);
183 : if(written != write_size){
184 : return false;
185 : }
186 : }
187 : }
188 : else{
189 : if(!winapi::set_file_pointer_ex(hnd, size, 0, winapi::file_begin)){
190 : return false;
191 : }
192 : if(!winapi::set_end_of_file(hnd)){
193 : return false;
194 : }
195 : }
196 : return true;
197 : }
198 :
199 : inline bool get_file_size(file_handle_t hnd, offset_t &size)
200 : { return winapi::get_file_size(hnd, size); }
201 :
202 : inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
203 : { return winapi::set_file_pointer_ex(hnd, off, 0, (unsigned long) pos); }
204 :
205 : inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
206 : { return winapi::set_file_pointer_ex(hnd, 0, &off, winapi::file_current); }
207 :
208 : inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
209 : {
210 : unsigned long written;
211 : return 0 != winapi::write_file(hnd, data, (unsigned long)numdata, &written, 0);
212 : }
213 :
214 : inline file_handle_t invalid_file()
215 : { return winapi::invalid_handle_value; }
216 :
217 : inline bool close_file(file_handle_t hnd)
218 : { return 0 != winapi::close_handle(hnd); }
219 :
220 : inline bool acquire_file_lock(file_handle_t hnd)
221 : {
222 : static winapi::interprocess_overlapped overlapped;
223 : const unsigned long len = ((unsigned long)-1);
224 : // winapi::interprocess_overlapped overlapped;
225 : // std::memset(&overlapped, 0, sizeof(overlapped));
226 : return winapi::lock_file_ex
227 : (hnd, winapi::lockfile_exclusive_lock, 0, len, len, &overlapped);
228 : }
229 :
230 : inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
231 : {
232 : const unsigned long len = ((unsigned long)-1);
233 : winapi::interprocess_overlapped overlapped;
234 : std::memset(&overlapped, 0, sizeof(overlapped));
235 : if(!winapi::lock_file_ex
236 : (hnd, winapi::lockfile_exclusive_lock | winapi::lockfile_fail_immediately,
237 : 0, len, len, &overlapped)){
238 : return winapi::get_last_error() == winapi::error_lock_violation ?
239 : acquired = false, true : false;
240 :
241 : }
242 : return (acquired = true);
243 : }
244 :
245 : inline bool release_file_lock(file_handle_t hnd)
246 : {
247 : const unsigned long len = ((unsigned long)-1);
248 : winapi::interprocess_overlapped overlapped;
249 : std::memset(&overlapped, 0, sizeof(overlapped));
250 : return winapi::unlock_file_ex(hnd, 0, len, len, &overlapped);
251 : }
252 :
253 : inline bool acquire_file_lock_sharable(file_handle_t hnd)
254 : {
255 : const unsigned long len = ((unsigned long)-1);
256 : winapi::interprocess_overlapped overlapped;
257 : std::memset(&overlapped, 0, sizeof(overlapped));
258 : return winapi::lock_file_ex(hnd, 0, 0, len, len, &overlapped);
259 : }
260 :
261 : inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
262 : {
263 : const unsigned long len = ((unsigned long)-1);
264 : winapi::interprocess_overlapped overlapped;
265 : std::memset(&overlapped, 0, sizeof(overlapped));
266 : if(!winapi::lock_file_ex
267 : (hnd, winapi::lockfile_fail_immediately, 0, len, len, &overlapped)){
268 : return winapi::get_last_error() == winapi::error_lock_violation ?
269 : acquired = false, true : false;
270 : }
271 : return (acquired = true);
272 : }
273 :
274 : inline bool release_file_lock_sharable(file_handle_t hnd)
275 : { return release_file_lock(hnd); }
276 :
277 : inline bool delete_subdirectories_recursive
278 : (const std::string &refcstrRootDirectory, const char *dont_delete_this, unsigned int count)
279 : {
280 : bool bSubdirectory = false; // Flag, indicating whether
281 : // subdirectories have been found
282 : void * hFile; // Handle to directory
283 : std::string strFilePath; // Filepath
284 : std::string strPattern; // Pattern
285 : winapi::win32_find_data FileInformation; // File information
286 :
287 : //Find all files and directories
288 : strPattern = refcstrRootDirectory + "\\*.*";
289 : hFile = winapi::find_first_file(strPattern.c_str(), &FileInformation);
290 : if(hFile != winapi::invalid_handle_value){
291 : do{
292 : //If it's not "." or ".." or the pointed root_level dont_delete_this erase it
293 : if(FileInformation.cFileName[0] != '.' &&
294 : !(dont_delete_this && count == 0 && std::strcmp(dont_delete_this, FileInformation.cFileName) == 0)){
295 : strFilePath.erase();
296 : strFilePath = refcstrRootDirectory + "\\" + FileInformation.cFileName;
297 :
298 : //If it's a directory, go recursive
299 : if(FileInformation.dwFileAttributes & winapi::file_attribute_directory){
300 : // Delete subdirectory
301 : if(!delete_subdirectories_recursive(strFilePath, dont_delete_this, count+1)){
302 : winapi::find_close(hFile);
303 : return false;
304 : }
305 : }
306 : //If it's a file, just delete it
307 : else{
308 : // Set file attributes
309 : //if(::SetFileAttributes(strFilePath.c_str(), winapi::file_attribute_normal) == 0)
310 : //return winapi::get_last_error();
311 : // Delete file
312 : winapi::unlink_file(strFilePath.c_str());
313 : }
314 : }
315 : //Go to the next file
316 : } while(winapi::find_next_file(hFile, &FileInformation) == 1);
317 :
318 : // Close handle
319 : winapi::find_close(hFile);
320 :
321 : //See if the loop has ended with an error or just because we've traversed all the files
322 : if(winapi::get_last_error() != winapi::error_no_more_files){
323 : return false;
324 : }
325 : else
326 : {
327 : //Erase empty subdirectories or original refcstrRootDirectory
328 : if(!bSubdirectory && count)
329 : {
330 : // Set directory attributes
331 : //if(::SetFileAttributes(refcstrRootDirectory.c_str(), FILE_ATTRIBUTE_NORMAL) == 0)
332 : //return ::GetLastError();
333 : // Delete directory
334 : if(winapi::remove_directory(refcstrRootDirectory.c_str()) == 0)
335 : return false;
336 : }
337 : }
338 : }
339 : return true;
340 : }
341 :
342 : //This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
343 : inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this)
344 : {
345 : return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this, 0u);
346 : }
347 :
348 :
349 : template<class Function>
350 : inline bool for_each_file_in_dir(const char *dir, Function f)
351 : {
352 : void * hFile; // Handle to directory
353 : winapi::win32_find_data FileInformation; // File information
354 :
355 : //Get base directory
356 : std::string str(dir);
357 : const std::size_t base_root_dir_len = str.size();
358 :
359 : //Find all files and directories
360 : str += "\\*.*";
361 : hFile = winapi::find_first_file(str.c_str(), &FileInformation);
362 : if(hFile != winapi::invalid_handle_value){
363 : do{ //Now loop every file
364 : str.erase(base_root_dir_len);
365 : //If it's not "." or ".." skip it
366 : if(FileInformation.cFileName[0] != '.'){
367 : str += "\\"; str += FileInformation.cFileName;
368 : //If it's a file, apply erase logic
369 : if(!(FileInformation.dwFileAttributes & winapi::file_attribute_directory)){
370 : f(str.c_str(), FileInformation.cFileName);
371 : }
372 : }
373 : //Go to the next file
374 : } while(winapi::find_next_file(hFile, &FileInformation) == 1);
375 :
376 : // Close handle and see if the loop has ended with an error
377 : winapi::find_close(hFile);
378 : if(winapi::get_last_error() != winapi::error_no_more_files){
379 : return false;
380 : }
381 : }
382 : return true;
383 : }
384 :
385 :
386 : #else //#if defined (BOOST_INTERPROCESS_WINDOWS)
387 :
388 : typedef int file_handle_t;
389 : typedef off_t offset_t;
390 :
391 : typedef struct mapping_handle_impl_t
392 : {
393 : file_handle_t handle;
394 : bool is_xsi;
395 : } mapping_handle_t;
396 :
397 : typedef enum { read_only = O_RDONLY
398 : , read_write = O_RDWR
399 : , copy_on_write
400 : , read_private
401 : , invalid_mode = 0xffff
402 : } mode_t;
403 :
404 : typedef enum { file_begin = SEEK_SET
405 : , file_end = SEEK_END
406 : , file_current = SEEK_CUR
407 : } file_pos_t;
408 :
409 : typedef int map_options_t;
410 : static const map_options_t default_map_options = map_options_t(-1);
411 :
412 : namespace ipcdetail{
413 :
414 : inline mapping_handle_t mapping_handle_from_file_handle(file_handle_t hnd)
415 : {
416 : mapping_handle_t ret;
417 : ret.handle = hnd;
418 : ret.is_xsi = false;
419 : return ret;
420 : }
421 :
422 : inline file_handle_t file_handle_from_mapping_handle(mapping_handle_t hnd)
423 : { return hnd.handle; }
424 :
425 : inline bool create_directory(const char *path)
426 : { return ::mkdir(path, 0777) == 0 && ::chmod(path, 0777) == 0; }
427 :
428 : inline bool remove_directory(const char *path)
429 : { return ::rmdir(path) == 0; }
430 :
431 : inline bool get_temporary_path(char *buffer, std::size_t buf_len, std::size_t &required_len)
432 : {
433 : required_len = 5u;
434 : if(buf_len < required_len)
435 : return false;
436 : else{
437 : std::strcpy(buffer, "/tmp");
438 : }
439 : return true;
440 : }
441 :
442 : inline file_handle_t create_new_file
443 : (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
444 : {
445 : (void)temporary;
446 : int ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
447 : if(ret >= 0){
448 : ::fchmod(ret, perm.get_permissions());
449 : }
450 : return ret;
451 : }
452 :
453 : inline file_handle_t create_or_open_file
454 : (const char *name, mode_t mode, const permissions & perm = permissions(), bool temporary = false)
455 : {
456 : (void)temporary;
457 : int ret = -1;
458 : //We need a loop to change permissions correctly using fchmod, since
459 : //with "O_CREAT only" ::open we don't know if we've created or opened the file.
460 : while(1){
461 : ret = ::open(name, ((int)mode) | O_EXCL | O_CREAT, perm.get_permissions());
462 : if(ret >= 0){
463 : ::fchmod(ret, perm.get_permissions());
464 : break;
465 : }
466 : else if(errno == EEXIST){
467 : if((ret = ::open(name, (int)mode)) >= 0 || errno != ENOENT){
468 : break;
469 : }
470 : }
471 : else{
472 : break;
473 : }
474 : }
475 : return ret;
476 : }
477 :
478 0 : inline file_handle_t open_existing_file
479 : (const char *name, mode_t mode, bool temporary = false)
480 : {
481 0 : (void)temporary;
482 0 : return ::open(name, (int)mode);
483 : }
484 :
485 : inline bool delete_file(const char *name)
486 : { return ::unlink(name) == 0; }
487 :
488 : inline bool truncate_file (file_handle_t hnd, std::size_t size)
489 : {
490 : typedef boost::move_detail::make_unsigned<off_t>::type uoff_t;
491 : if(uoff_t((std::numeric_limits<off_t>::max)()) < size){
492 : errno = EINVAL;
493 : return false;
494 : }
495 : return 0 == ::ftruncate(hnd, off_t(size));
496 : }
497 :
498 : inline bool get_file_size(file_handle_t hnd, offset_t &size)
499 : {
500 : struct stat data;
501 : bool ret = 0 == ::fstat(hnd, &data);
502 : if(ret){
503 : size = data.st_size;
504 : }
505 : return ret;
506 : }
507 :
508 : inline bool set_file_pointer(file_handle_t hnd, offset_t off, file_pos_t pos)
509 : { return ((off_t)(-1)) != ::lseek(hnd, off, (int)pos); }
510 :
511 : inline bool get_file_pointer(file_handle_t hnd, offset_t &off)
512 : {
513 : off = ::lseek(hnd, 0, SEEK_CUR);
514 : return off != ((off_t)-1);
515 : }
516 :
517 : inline bool write_file(file_handle_t hnd, const void *data, std::size_t numdata)
518 : { return (ssize_t(numdata)) == ::write(hnd, data, numdata); }
519 :
520 0 : inline file_handle_t invalid_file()
521 0 : { return -1; }
522 :
523 0 : inline bool close_file(file_handle_t hnd)
524 0 : { return ::close(hnd) == 0; }
525 :
526 0 : inline bool acquire_file_lock(file_handle_t hnd)
527 : {
528 0 : struct ::flock lock;
529 0 : lock.l_type = F_WRLCK;
530 0 : lock.l_whence = SEEK_SET;
531 0 : lock.l_start = 0;
532 0 : lock.l_len = 0;
533 0 : return -1 != ::fcntl(hnd, F_SETLKW, &lock);
534 : }
535 :
536 : inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
537 : {
538 : struct ::flock lock;
539 : lock.l_type = F_WRLCK;
540 : lock.l_whence = SEEK_SET;
541 : lock.l_start = 0;
542 : lock.l_len = 0;
543 : int ret = ::fcntl(hnd, F_SETLK, &lock);
544 : if(ret == -1){
545 : return (errno == EAGAIN || errno == EACCES) ?
546 : (acquired = false, true) : false;
547 : }
548 : return (acquired = true);
549 : }
550 :
551 0 : inline bool release_file_lock(file_handle_t hnd)
552 : {
553 0 : struct ::flock lock;
554 0 : lock.l_type = F_UNLCK;
555 0 : lock.l_whence = SEEK_SET;
556 0 : lock.l_start = 0;
557 0 : lock.l_len = 0;
558 0 : return -1 != ::fcntl(hnd, F_SETLK, &lock);
559 : }
560 :
561 : inline bool acquire_file_lock_sharable(file_handle_t hnd)
562 : {
563 : struct ::flock lock;
564 : lock.l_type = F_RDLCK;
565 : lock.l_whence = SEEK_SET;
566 : lock.l_start = 0;
567 : lock.l_len = 0;
568 : return -1 != ::fcntl(hnd, F_SETLKW, &lock);
569 : }
570 :
571 : inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
572 : {
573 : struct flock lock;
574 : lock.l_type = F_RDLCK;
575 : lock.l_whence = SEEK_SET;
576 : lock.l_start = 0;
577 : lock.l_len = 0;
578 : int ret = ::fcntl(hnd, F_SETLK, &lock);
579 : if(ret == -1){
580 : return (errno == EAGAIN || errno == EACCES) ?
581 : (acquired = false, true) : false;
582 : }
583 : return (acquired = true);
584 : }
585 :
586 : inline bool release_file_lock_sharable(file_handle_t hnd)
587 : { return release_file_lock(hnd); }
588 :
589 : #if 0
590 : inline bool acquire_file_lock(file_handle_t hnd)
591 : { return 0 == ::flock(hnd, LOCK_EX); }
592 :
593 : inline bool try_acquire_file_lock(file_handle_t hnd, bool &acquired)
594 : {
595 : int ret = ::flock(hnd, LOCK_EX | LOCK_NB);
596 : acquired = ret == 0;
597 : return (acquired || errno == EWOULDBLOCK);
598 : }
599 :
600 : inline bool release_file_lock(file_handle_t hnd)
601 : { return 0 == ::flock(hnd, LOCK_UN); }
602 :
603 : inline bool acquire_file_lock_sharable(file_handle_t hnd)
604 : { return 0 == ::flock(hnd, LOCK_SH); }
605 :
606 : inline bool try_acquire_file_lock_sharable(file_handle_t hnd, bool &acquired)
607 : {
608 : int ret = ::flock(hnd, LOCK_SH | LOCK_NB);
609 : acquired = ret == 0;
610 : return (acquired || errno == EWOULDBLOCK);
611 : }
612 :
613 : inline bool release_file_lock_sharable(file_handle_t hnd)
614 : { return 0 == ::flock(hnd, LOCK_UN); }
615 : #endif
616 :
617 : inline bool delete_subdirectories_recursive
618 : (const std::string &refcstrRootDirectory, const char *dont_delete_this)
619 : {
620 : DIR *d = opendir(refcstrRootDirectory.c_str());
621 : if(!d) {
622 : return false;
623 : }
624 :
625 : struct dir_close
626 : {
627 : DIR *d_;
628 : dir_close(DIR *d) : d_(d) {}
629 : ~dir_close() { ::closedir(d_); }
630 : } dc(d); (void)dc;
631 :
632 : struct ::dirent *de;
633 : struct ::stat st;
634 : std::string fn;
635 :
636 : while((de=::readdir(d))) {
637 : if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
638 : || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
639 : continue;
640 : }
641 : if(dont_delete_this && std::strcmp(dont_delete_this, de->d_name) == 0){
642 : continue;
643 : }
644 : fn = refcstrRootDirectory;
645 : fn += '/';
646 : fn += de->d_name;
647 :
648 : if(std::remove(fn.c_str())) {
649 : if(::stat(fn.c_str(), & st)) {
650 : return false;
651 : }
652 : if(S_ISDIR(st.st_mode)) {
653 : if(!delete_subdirectories_recursive(fn, 0) ){
654 : return false;
655 : }
656 : } else {
657 : return false;
658 : }
659 : }
660 : }
661 : return std::remove(refcstrRootDirectory.c_str()) ? false : true;
662 : }
663 :
664 : template<class Function>
665 : inline bool for_each_file_in_dir(const char *dir, Function f)
666 : {
667 : std::string refcstrRootDirectory(dir);
668 :
669 : DIR *d = opendir(refcstrRootDirectory.c_str());
670 : if(!d) {
671 : return false;
672 : }
673 :
674 : struct dir_close
675 : {
676 : DIR *d_;
677 : dir_close(DIR *d) : d_(d) {}
678 : ~dir_close() { ::closedir(d_); }
679 : } dc(d); (void)dc;
680 :
681 : struct ::dirent *de;
682 : struct ::stat st;
683 : std::string fn;
684 :
685 : while((de=::readdir(d))) {
686 : if( de->d_name[0] == '.' && ( de->d_name[1] == '\0'
687 : || (de->d_name[1] == '.' && de->d_name[2] == '\0' )) ){
688 : continue;
689 : }
690 : fn = refcstrRootDirectory;
691 : fn += '/';
692 : fn += de->d_name;
693 :
694 : if(::stat(fn.c_str(), & st)) {
695 : return false;
696 : }
697 : //If it's a file, apply erase logic
698 : if(!S_ISDIR(st.st_mode)) {
699 : f(fn.c_str(), de->d_name);
700 : }
701 : }
702 : return true;
703 : }
704 :
705 :
706 : //This function erases all the subdirectories of a directory except the one pointed by "dont_delete_this"
707 : inline bool delete_subdirectories(const std::string &refcstrRootDirectory, const char *dont_delete_this)
708 : {
709 : return delete_subdirectories_recursive(refcstrRootDirectory, dont_delete_this );
710 : }
711 :
712 : #endif //#if defined (BOOST_INTERPROCESS_WINDOWS)
713 :
714 : inline bool open_or_create_directory(const char *dir_name)
715 : {
716 : //If fails, check that it's because it already exists
717 : if(!create_directory(dir_name)){
718 : error_info info(system_error_code());
719 : if(info.get_error_code() != already_exists_error){
720 : return false;
721 : }
722 : }
723 : return true;
724 : }
725 :
726 : inline std::string get_temporary_path()
727 : {
728 : std::size_t required_len = 0;
729 : get_temporary_path(0, 0, required_len);
730 : std::string ret_str(required_len, char(0));
731 : get_temporary_path(&ret_str[0], ret_str.size(), required_len);
732 : while(!ret_str.empty() && !ret_str[ret_str.size()-1]){
733 : ret_str.erase(ret_str.size()-1);
734 : }
735 :
736 : return ret_str;
737 : }
738 :
739 : } //namespace ipcdetail{
740 : } //namespace interprocess {
741 : } //namespace boost {
742 :
743 : #include <boost/interprocess/detail/config_end.hpp>
744 :
745 : #endif //BOOST_INTERPROCESS_DETAIL_OS_FILE_FUNCTIONS_HPP
|