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
26namespace boost { namespace iostreams { namespace test {
27
28#ifdef BOOST_IOSTREAMS_WINDOWS
29
30// Windows implementation
31
32boost::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
47void 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
59boost::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(file: name.c_str(), oflag: oflag, pmode);
76 BOOST_REQUIRE (fd != -1);
77
78 return fd;
79}
80
81void 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.
93bool is_handle_open(boost::iostreams::detail::file_handle handle)
94{
95 return ::fcntl(fd: 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

source code of boost/libs/iostreams/test/detail/file_handle.hpp