1 // Exception implementation file -------------------------------------------//
3 // < ----------------------------------------------------------------------- >
4 // < Copyright © 2002 Beman Dawes >
5 // < Copyright © 2001 Dietmar Kühl, All Rights Reserved >
7 // < Permission to use, copy, modify, distribute and sell this >
8 // < software for any purpose is hereby granted without fee, provided >
9 // < that the above copyright notice appears in all copies and that >
10 // < both that copyright notice and this permission notice appear in >
11 // < supporting documentation. The authors make no representations about >
12 // < the suitability of this software for any purpose. It is provided >
13 // < "as is" without express or implied warranty. >
14 // < ----------------------------------------------------------------------- >
16 // See http://www.boost.org/libs/filesystem for documentation.
18 //----------------------------------------------------------------------------//
20 #include <boost/config.hpp>
21 #include <boost/filesystem/exception.hpp>
23 namespace fs = boost::filesystem;
25 #include <cstring> // SGI MIPSpro compilers need this
28 # ifdef BOOST_NO_STDC_NAMESPACE
29 namespace std { using ::strerror; }
32 // BOOST_POSIX or BOOST_WINDOWS specify which API to use.
33 # if !defined( BOOST_WINDOWS ) && !defined( BOOST_POSIX )
34 # if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__CYGWIN__)
35 # define BOOST_WINDOWS
41 # if defined( BOOST_WINDOWS )
44 # include <errno.h> // for POSIX error codes
47 //----------------------------------------------------------------------------//
51 std::string system_message( int sys_err_code )
57 FORMAT_MESSAGE_ALLOCATE_BUFFER |
58 FORMAT_MESSAGE_FROM_SYSTEM |
59 FORMAT_MESSAGE_IGNORE_INSERTS,
62 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
67 str += static_cast<LPCSTR>(lpMsgBuf);
68 ::LocalFree( lpMsgBuf ); // free the buffer
70 && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') )
71 str.erase( str.size()-1 );
73 str += std::strerror( errno );
78 struct ec_xlate { int sys_ec; fs::error_code ec; };
79 const ec_xlate ec_table[] =
82 { ERROR_ACCESS_DENIED, fs::security_error },
83 { ERROR_INVALID_ACCESS, fs::security_error },
84 { ERROR_SHARING_VIOLATION, fs::security_error },
85 { ERROR_LOCK_VIOLATION, fs::security_error },
86 { ERROR_LOCKED, fs::security_error },
87 { ERROR_NOACCESS, fs::security_error },
88 { ERROR_WRITE_PROTECT, fs::read_only_error },
89 { ERROR_NOT_READY, fs::io_error },
90 { ERROR_SEEK, fs::io_error },
91 { ERROR_READ_FAULT, fs::io_error },
92 { ERROR_WRITE_FAULT, fs::io_error },
93 { ERROR_CANTOPEN, fs::io_error },
94 { ERROR_CANTREAD, fs::io_error },
95 { ERROR_CANTWRITE, fs::io_error },
96 { ERROR_DIRECTORY, fs::path_error },
97 { ERROR_INVALID_NAME, fs::path_error },
98 { ERROR_FILE_NOT_FOUND, fs::not_found_error },
99 { ERROR_PATH_NOT_FOUND, fs::not_found_error },
100 { ERROR_DEV_NOT_EXIST, fs::not_found_error },
101 { ERROR_DEVICE_IN_USE, fs::busy_error },
102 { ERROR_OPEN_FILES, fs::busy_error },
103 { ERROR_BUSY_DRIVE, fs::busy_error },
104 { ERROR_BUSY, fs::busy_error },
105 { ERROR_FILE_EXISTS, fs::already_exists_error },
106 { ERROR_ALREADY_EXISTS, fs::already_exists_error },
107 { ERROR_DIR_NOT_EMPTY, fs::not_empty_error },
108 { ERROR_HANDLE_DISK_FULL, fs::out_of_space_error },
109 { ERROR_DISK_FULL, fs::out_of_space_error },
110 { ERROR_OUTOFMEMORY, fs::out_of_memory_error },
111 { ERROR_NOT_ENOUGH_MEMORY, fs::out_of_memory_error },
112 { ERROR_TOO_MANY_OPEN_FILES, fs::out_of_resource_error }
114 { EACCES, fs::security_error },
115 { EROFS, fs::read_only_error },
116 { EIO, fs::io_error },
117 { ENAMETOOLONG, fs::path_error },
118 { ENOENT, fs::not_found_error },
119 { ENOTDIR, fs::not_directory_error },
120 { EAGAIN, fs::busy_error },
121 { EBUSY, fs::busy_error },
122 { ETXTBSY, fs::busy_error },
123 { EEXIST, fs::already_exists_error },
124 { ENOTEMPTY, fs::not_empty_error },
125 { EISDIR, fs::is_directory_error },
126 { ENOSPC, fs::out_of_space_error },
127 { ENOMEM, fs::out_of_memory_error },
128 { EMFILE, fs::out_of_resource_error }
132 fs::error_code lookup_error( int sys_err_code )
134 for ( const ec_xlate * cur = &ec_table[0];
136 + sizeof(ec_table)/sizeof(ec_xlate); ++cur )
138 if ( sys_err_code == cur->sys_ec ) return cur->ec;
140 return fs::system_error; // general system error code
143 // These helper functions work for POSIX and Windows. For systems where
144 // path->native_file_string() != path->native_directory_string(), more
145 // care would be required to get the right form for the function involved.
147 std::string other_error_prep(
148 const std::string & who,
149 const std::string & message )
151 return who + ": " + message;
154 std::string other_error_prep(
155 const std::string & who,
156 const fs::path & path1,
157 const std::string & message )
159 return who + ": \"" + path1.native_file_string() + "\": " + message;
162 std::string system_error_prep(
163 const std::string & who,
164 const fs::path & path1,
167 return who + ": \"" + path1.native_file_string() + "\": "
168 + system_message( sys_err_code );
171 std::string system_error_prep(
172 const std::string & who,
173 const fs::path & path1,
174 const fs::path & path2,
177 return who + ": \"" + path1.native_file_string()
178 + "\", \"" + path2.native_file_string() + "\": "
179 + system_message( sys_err_code );
182 } // unnamed namespace
189 // filesystem_error implementation -----------------------------------------//
191 filesystem_error::filesystem_error(
192 const std::string & who,
193 const std::string & message )
194 : std::runtime_error(
195 other_error_prep( who, message ).c_str() ),
196 m_sys_err(0), m_err(other_error), m_who(who)
199 filesystem_error::filesystem_error(
200 const std::string & who,
202 const std::string & message )
203 : std::runtime_error(
204 other_error_prep( who, path1, message ).c_str() ),
205 m_sys_err(0), m_err(other_error), m_who(who), m_path1(path1)
208 filesystem_error::filesystem_error(
209 const std::string & who,
212 : std::runtime_error(
213 system_error_prep( who, path1, sys_err_code ).c_str() ),
214 m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code)),
215 m_who(who), m_path1(path1)
218 filesystem_error::filesystem_error(
219 const std::string & who,
223 : std::runtime_error(
224 system_error_prep( who, path1, path2, sys_err_code ).c_str() ),
225 m_sys_err(sys_err_code), m_err(lookup_error(sys_err_code)),
226 m_who(who), m_path1(path1), m_path2(path2)
229 filesystem_error::~filesystem_error() throw()
235 int system_error_code() // artifact of POSIX and WINDOWS error reporting
237 # ifdef BOOST_WINDOWS
238 return ::GetLastError();
240 return errno; // GCC 3.1 won't accept ::errno
243 } // namespace detail
244 } // namespace filesystem