blob: a9bfed52c8180d4961e84bae184795dbd2dd6d15 [file] [log] [blame]
// (C) Copyright 2010 Daniel James
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
// (C) Copyright 2003-2007 Jonathan Turkanis
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
// A few methods for getting and manipulating file handles.
#ifndef BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
#define BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
#include <boost/iostreams/detail/file_handle.hpp>
#include <boost/iostreams/detail/config/rtl.hpp>
#include <boost/test/test_tools.hpp>
#include <string>
#ifdef BOOST_IOSTREAMS_WINDOWS
# include <io.h> // low-level file i/o.
# define WINDOWS_LEAN_AND_MEAN
# include <windows.h>
#else
# include <sys/stat.h>
# include <fcntl.h>
#endif
namespace boost { namespace iostreams { namespace test {
#ifdef BOOST_IOSTREAMS_WINDOWS
// Windows implementation
boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
{
HANDLE handle =
::CreateFileA( name.c_str(),
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, // lpSecurityAttributes
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // hTemplateFile
BOOST_REQUIRE (handle != INVALID_HANDLE_VALUE);
return handle;
}
void close_file_handle(boost::iostreams::detail::file_handle handle)
{
BOOST_REQUIRE(::CloseHandle(handle) == 1);
}
#define BOOST_CHECK_HANDLE_CLOSED(handle)
#define BOOST_CHECK_HANDLE_OPEN(handle)
#else // BOOST_IOSTREAMS_WINDOWS
// Non-windows implementation
boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
{
int oflag = O_RDWR;
#ifdef _LARGEFILE64_SOURCE
oflag |= O_LARGEFILE;
#endif
// Calculate pmode argument to open.
mode_t pmode = S_IRUSR | S_IWUSR |
S_IRGRP | S_IWGRP |
S_IROTH | S_IWOTH;
// Open file.
int fd = BOOST_IOSTREAMS_FD_OPEN(name.c_str(), oflag, pmode);
BOOST_REQUIRE (fd != -1);
return fd;
}
void close_file_handle(boost::iostreams::detail::file_handle handle)
{
BOOST_REQUIRE(BOOST_IOSTREAMS_FD_CLOSE(handle) != -1);
}
// This is pretty dubious. First you must make sure that no other
// operations that could open a descriptor are called before this
// check, otherwise it's quite likely that a closed descriptor
// could be used. Secondly, I'm not sure if it's guaranteed that
// fcntl will know that the descriptor is closed but this seems
// to work okay, and I can't see any other convenient way to check
// that a descripter has been closed.
bool is_handle_open(boost::iostreams::detail::file_handle handle)
{
return ::fcntl(handle, F_GETFD) != -1;
}
#define BOOST_CHECK_HANDLE_CLOSED(handle) \
BOOST_CHECK(!::boost::iostreams::test::is_handle_open(handle))
#define BOOST_CHECK_HANDLE_OPEN(handle) \
BOOST_CHECK(::boost::iostreams::test::is_handle_open(handle))
#endif // BOOST_IOSTREAMS_WINDOWS
}}}
#endif // BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED