1 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
2 // (C) Copyright 2005-2007 Jonathan Turkanis
3 // (C) Copyright Jonathan Graehl 2004.
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 // See http://www.boost.org/libs/iostreams for documentation.
8 
9 // Used by mapped_file.cpp.
10 
11 #ifndef BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED
12 #define BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED
13 
14 #if defined(_MSC_VER)
15 # pragma once
16 #endif
17 
18 #include <cstring>
19 #include <string>
20 #include <boost/config.hpp>
21 #include <boost/throw_exception.hpp>
22 #include <boost/iostreams/detail/config/windows_posix.hpp>
23 #include <boost/iostreams/detail/ios.hpp>  // failure.
24 
25 #if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__)
26 namespace std { using ::strlen; }
27 #endif
28 
29 #ifdef BOOST_IOSTREAMS_WINDOWS
30 # define WIN32_LEAN_AND_MEAN  // Exclude rarely-used stuff from Windows headers
31 # include <windows.h>
32 #else
33 # include <errno.h>
34 # include <string.h>
35 #endif
36 
37 namespace boost { namespace iostreams { namespace detail {
38 
system_failure(const char * msg)39 inline BOOST_IOSTREAMS_FAILURE system_failure(const char* msg)
40 {
41     std::string result;
42 #ifdef BOOST_IOSTREAMS_WINDOWS
43     DWORD err;
44     LPVOID lpMsgBuf;
45     if ( (err = ::GetLastError()) != NO_ERROR &&
46          ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER |
47                            FORMAT_MESSAGE_FROM_SYSTEM,
48                            NULL,
49                            err,
50                            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
51                            (LPSTR) &lpMsgBuf,
52                            0,
53                            NULL ) != 0 )
54     {
55         result.reserve(std::strlen(msg) + 2 + std::strlen((LPSTR)lpMsgBuf));
56         result.append(msg);
57         result.append(": ");
58         result.append((LPSTR) lpMsgBuf);
59         ::LocalFree(lpMsgBuf);
60     } else {
61         result += msg;
62     }
63 #else
64     const char* system_msg = errno ? strerror(errno) : "";
65     result.reserve(std::strlen(msg) + 2 + std::strlen(system_msg));
66     result.append(msg);
67     result.append(": ");
68     result.append(system_msg);
69 #endif
70     return BOOST_IOSTREAMS_FAILURE(result);
71 }
72 
system_failure(const std::string & msg)73 inline BOOST_IOSTREAMS_FAILURE system_failure(const std::string& msg)
74 { return system_failure(msg.c_str()); }
75 
throw_system_failure(const char * msg)76 inline void throw_system_failure(const char* msg)
77 { boost::throw_exception(system_failure(msg)); }
78 
throw_system_failure(const std::string & msg)79 inline void throw_system_failure(const std::string& msg)
80 { boost::throw_exception(system_failure(msg)); }
81 
82 } } } // End namespaces detail, iostreams, boost.
83 
84 #endif // #ifndef BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED
85