file_handle.hpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. // A few methods for getting and manipulating file handles.
  7. #ifndef BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
  8. #define BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED
  9. #include <boost/iostreams/detail/file_handle.hpp>
  10. #include <boost/iostreams/detail/config/rtl.hpp>
  11. #include <boost/test/test_tools.hpp>
  12. #include <string>
  13. #ifdef BOOST_IOSTREAMS_WINDOWS
  14. # include <io.h> // low-level file i/o.
  15. # define WINDOWS_LEAN_AND_MEAN
  16. # include <windows.h>
  17. #else
  18. # include <sys/stat.h>
  19. # include <fcntl.h>
  20. #endif
  21. namespace boost { namespace iostreams { namespace test {
  22. #ifdef BOOST_IOSTREAMS_WINDOWS
  23. // Windows implementation
  24. boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
  25. {
  26. HANDLE handle =
  27. ::CreateFileA( name.c_str(),
  28. GENERIC_READ | GENERIC_WRITE,
  29. FILE_SHARE_READ | FILE_SHARE_WRITE,
  30. NULL, // lpSecurityAttributes
  31. OPEN_EXISTING,
  32. FILE_ATTRIBUTE_NORMAL,
  33. NULL ); // hTemplateFile
  34. BOOST_REQUIRE (handle != INVALID_HANDLE_VALUE);
  35. return handle;
  36. }
  37. void close_file_handle(boost::iostreams::detail::file_handle handle)
  38. {
  39. BOOST_REQUIRE(::CloseHandle(handle) == 1);
  40. }
  41. #define BOOST_CHECK_HANDLE_CLOSED(handle)
  42. #define BOOST_CHECK_HANDLE_OPEN(handle)
  43. #else // BOOST_IOSTREAMS_WINDOWS
  44. // Non-windows implementation
  45. boost::iostreams::detail::file_handle open_file_handle(std::string const& name)
  46. {
  47. int oflag = O_RDWR;
  48. #ifdef _LARGEFILE64_SOURCE
  49. oflag |= O_LARGEFILE;
  50. #endif
  51. // Calculate pmode argument to open.
  52. mode_t pmode = S_IRUSR | S_IWUSR |
  53. S_IRGRP | S_IWGRP |
  54. S_IROTH | S_IWOTH;
  55. // Open file.
  56. int fd = BOOST_IOSTREAMS_FD_OPEN(name.c_str(), oflag, pmode);
  57. BOOST_REQUIRE (fd != -1);
  58. return fd;
  59. }
  60. void close_file_handle(boost::iostreams::detail::file_handle handle)
  61. {
  62. BOOST_REQUIRE(BOOST_IOSTREAMS_FD_CLOSE(handle) != -1);
  63. }
  64. // This is pretty dubious. First you must make sure that no other
  65. // operations that could open a descriptor are called before this
  66. // check, otherwise it's quite likely that a closed descriptor
  67. // could be used. Secondly, I'm not sure if it's guaranteed that
  68. // fcntl will know that the descriptor is closed but this seems
  69. // to work okay, and I can't see any other convenient way to check
  70. // that a descripter has been closed.
  71. bool is_handle_open(boost::iostreams::detail::file_handle handle)
  72. {
  73. return ::fcntl(handle, F_GETFD) != -1;
  74. }
  75. #define BOOST_CHECK_HANDLE_CLOSED(handle) \
  76. BOOST_CHECK(!::boost::iostreams::test::is_handle_open(handle))
  77. #define BOOST_CHECK_HANDLE_OPEN(handle) \
  78. BOOST_CHECK(::boost::iostreams::test::is_handle_open(handle))
  79. #endif // BOOST_IOSTREAMS_WINDOWS
  80. }}}
  81. #endif // BOOST_IOSTREAMS_FILE_HANDLE_HPP_INCLUDED