Skip to content

Commit a2aedd1

Browse files
committed
Fixing error reporting in Linux file streams.
For some reason the original implementation was just creating an exception with a hardcoded string error message. This is bad since it looses the underlying error code and doesn't follow the exception type used on other platforms std::system_error. I updated to check the errno and create a std::system_error exception with the error code included. This results in less OS specific code as well.
1 parent e5a9bc4 commit a2aedd1

File tree

2 files changed

+7
-18
lines changed

2 files changed

+7
-18
lines changed

Release/src/streams/linux/fileio_linux.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "cpprest/fileio.h"
3434

3535
using namespace boost::asio;
36+
using namespace Concurrency::streams::details;
3637

3738
namespace Concurrency { namespace streams { namespace details {
3839

@@ -124,7 +125,6 @@ std::shared_ptr<io_scheduler> get_scheduler()
124125
* =-=-=-
125126
****/
126127

127-
128128
/// <summary>
129129
/// The public parts of the file information record contain only what is implementation-
130130
/// independent. The actual allocated record is larger and has details that the implementation
@@ -165,8 +165,6 @@ struct _file_info_impl : _file_info
165165

166166
}}}
167167

168-
using namespace Concurrency::streams::details;
169-
170168
/// <summary>
171169
/// Perform post-CreateFile processing.
172170
/// </summary>
@@ -204,12 +202,7 @@ bool _finish_create(int fh, _filestream_callback *callback, std::ios_base::openm
204202
}
205203
else
206204
{
207-
#ifdef __APPLE__
208-
auto exptr = std::make_exception_ptr(std::ios_base::failure("failed to create file", std::make_error_code(std::errc::no_such_file_or_directory)));
209-
#else
210-
auto exptr = std::make_exception_ptr(std::ios_base::failure("failed to create file"));
211-
#endif
212-
callback->on_error(exptr);
205+
callback->on_error(std::make_exception_ptr(utility::details::create_system_error(errno)));
213206
return false;
214207
}
215208
}
@@ -326,8 +319,7 @@ bool _close_fsb_nolock(_file_info **info, Concurrency::streams::details::_filest
326319
}
327320
else
328321
{
329-
auto exptr = std::make_exception_ptr(std::ios_base::failure("failed to close file"));
330-
callback->on_error(exptr);
322+
callback->on_error(std::make_exception_ptr(utility::details::create_system_error(errno)));
331323
}
332324
});
333325

@@ -383,9 +375,7 @@ size_t _write_file_async(Concurrency::streams::details::_file_info_impl *fInfo,
383375
auto bytes_written = pwrite(fInfo->m_handle, ptr, count, abs_position);
384376
if (bytes_written == -1)
385377
{
386-
auto exptr = std::make_exception_ptr(std::ios_base::failure("failed to write file"));
387-
callback->on_error(exptr);
388-
perror("failed to write");
378+
callback->on_error(std::make_exception_ptr(utility::details::create_system_error(errno)));
389379
}
390380

391381
if(must_restore_pos)
@@ -437,8 +427,7 @@ size_t _read_file_async(Concurrency::streams::details::_file_info_impl *fInfo, C
437427
auto bytes_read = pread(fInfo->m_handle, ptr, count, offset);
438428
if (bytes_read < 0)
439429
{
440-
auto exptr = std::make_exception_ptr(std::ios_base::failure("failed to read file"));
441-
callback->on_error(exptr);
430+
callback->on_error(std::make_exception_ptr(utility::details::create_system_error(errno)));
442431
}
443432
else
444433
{

Release/tests/Functional/streams/fstreambuf_tests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ TEST(OpenForReadDoesntCreateFile1)
136136
{
137137
utility::string_t fname = U("OpenForReadDoesntCreateFile1.txt");
138138

139-
VERIFY_THROWS(OPEN_R<char>(fname).get(), std::system_error);
139+
VERIFY_THROWS_SYSTEM_ERROR(OPEN_R<char>(fname).get(), std::errc::no_such_file_or_directory);
140140

141141
std::ifstream is;
142142
VERIFY_IS_NULL(is.rdbuf()->open(fname.c_str(), std::ios::in));
@@ -146,7 +146,7 @@ TEST(OpenForReadDoesntCreateFile2)
146146
{
147147
utility::string_t fname = U("OpenForReadDoesntCreateFile2.txt");
148148

149-
VERIFY_THROWS(OPEN<char>(fname, std::ios_base::in | std::ios_base::binary ).get(), std::system_error);
149+
VERIFY_THROWS_SYSTEM_ERROR(OPEN<char>(fname, std::ios_base::in | std::ios_base::binary ).get(), std::errc::no_such_file_or_directory);
150150

151151
std::ifstream is;
152152
VERIFY_IS_NULL(is.rdbuf()->open(fname.c_str(), std::ios::in | std::ios_base::binary));

0 commit comments

Comments
 (0)