1 // (C) Copyright 2010 Daniel James
2 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
3 // (C) Copyright 2003-2007 Jonathan Turkanis
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
6
7 // A few methods for getting and manipulating file handles.
8
9 #ifndef BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
10 #define BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
11
12 #include <boost/iostreams/detail/file_handle.hpp>
13 #include <boost/iostreams/detail/config/rtl.hpp>
14 #include <boost/test/test_tools.hpp>
15 #include <string>
16
17 #ifdef BOOST_IOSTREAMS_WINDOWS
18 # include <io.h> // low-level file i/o.
19 # define WINDOWS_LEAN_AND_MEAN
20 # include <windows.h>
21 #else
22 # include <sys/stat.h>
23 # include <fcntl.h>
24 #endif
25
26 namespace boost { namespace iostreams { namespace test {
27
28 #ifdef BOOST_IOSTREAMS_WINDOWS
29
30 // Windows implementation
31
open_file_handle(std::string const & name)32 boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
33 {
34 HANDLE handle =
35 ::CreateFileA( name.c_str(),
36 GENERIC_READ | GENERIC_WRITE,
37 FILE_SHARE_READ | FILE_SHARE_WRITE,
38 NULL, // lpSecurityAttributes
39 OPEN_EXISTING,
40 FILE_ATTRIBUTE_NORMAL,
41 NULL ); // hTemplateFile
42
43 BOOST_REQUIRE (handle != INVALID_HANDLE_VALUE);
44 return handle;
45 }
46
close_file_handle(boost::iostreams::detail::file_handle handle)47 void close_file_handle(boost::iostreams::detail::file_handle handle)
48 {
49 BOOST_REQUIRE(::CloseHandle(handle) == 1);
50 }
51
52 #define BOOST_CHECK_HANDLE_CLOSED(handle)
53 #define BOOST_CHECK_HANDLE_OPEN(handle)
54
55 #else // BOOST_IOSTREAMS_WINDOWS
56
57 // Non-windows implementation
58
59 boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
60 {
61 int oflag = O_RDWR;
62
63 #ifdef _LARGEFILE64_SOURCE
64 oflag |= O_LARGEFILE;
65 #endif
66
67 // Calculate pmode argument to open.
68
69 mode_t pmode = S_IRUSR | S_IWUSR |
70 S_IRGRP | S_IWGRP |
71 S_IROTH | S_IWOTH;
72
73 // Open file.
74
75 int fd = BOOST_IOSTREAMS_FD_OPEN(name.c_str(), oflag, pmode);
76 BOOST_REQUIRE (fd != -1);
77
78 return fd;
79 }
80
81 void close_file_handle(boost::iostreams::detail::file_handle handle)
82 {
83 BOOST_REQUIRE(BOOST_IOSTREAMS_FD_CLOSE(handle) != -1);
84 }
85
86 // This is pretty dubious. First you must make sure that no other
87 // operations that could open a descriptor are called before this
88 // check, otherwise it's quite likely that a closed descriptor
89 // could be used. Secondly, I'm not sure if it's guaranteed that
90 // fcntl will know that the descriptor is closed but this seems
91 // to work okay, and I can't see any other convenient way to check
92 // that a descripter has been closed.
93 bool is_handle_open(boost::iostreams::detail::file_handle handle)
94 {
95 return ::fcntl(handle, F_GETFD) != -1;
96 }
97
98 #define BOOST_CHECK_HANDLE_CLOSED(handle) \
99 BOOST_CHECK(!::boost::iostreams::test::is_handle_open(handle))
100 #define BOOST_CHECK_HANDLE_OPEN(handle) \
101 BOOST_CHECK(::boost::iostreams::test::is_handle_open(handle))
102
103
104 #endif // BOOST_IOSTREAMS_WINDOWS
105
106 }}}
107
108 #endif // BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
109