diff --git a/src/file.cpp b/src/file.cpp index 00e870205..d17a37216 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -198,28 +198,42 @@ namespace } int ret = 0; + int num_waits = num_bufs; for (int i = 0; i < num_bufs; ++i) { DWORD num_read; - if (ReadFile(fd, bufs[i].iov_base, bufs[i].iov_len, &num_read, &ol[i]) == FALSE - && GetLastError() != ERROR_IO_PENDING -#ifdef ERROR_CANT_WAIT - && GetLastError() != ERROR_CANT_WAIT -#endif - ) + if (ReadFile(fd, bufs[i].iov_base, bufs[i].iov_len, &num_read, &ol[i]) == FALSE) { - ret = -1; - goto done; + DWORD const last_error = GetLastError(); + if (last_error == ERROR_HANDLE_EOF) + { + num_waits = i; + break; + } + else if (last_error != ERROR_IO_PENDING +#ifdef ERROR_CANT_WAIT + && last_error != ERROR_CANT_WAIT +#endif + ) + { + ret = -1; + goto done; + } } } - if (wait_for_multiple_objects(num_bufs, h) == WAIT_FAILED) + if (num_waits == 0) + { + goto done; + } + + if (wait_for_multiple_objects(num_waits, h) == WAIT_FAILED) { ret = -1; goto done; } - for (int i = 0; i < num_bufs; ++i) + for (int i = 0; i < num_waits; ++i) { if (WaitForSingleObject(ol[i].hEvent, INFINITE) == WAIT_FAILED) { @@ -229,11 +243,15 @@ namespace DWORD num_read; if (GetOverlappedResult(fd, &ol[i], &num_read, FALSE) == FALSE) { + DWORD const last_error = GetLastError(); + if (last_error != ERROR_HANDLE_EOF) + { #ifdef ERROR_CANT_WAIT - TORRENT_ASSERT(GetLastError() != ERROR_CANT_WAIT); + TORRENT_ASSERT(last_error != ERROR_CANT_WAIT); #endif - ret = -1; - break; + ret = -1; + break; + } } ret += num_read; } diff --git a/test/test_file.cpp b/test/test_file.cpp index a9b7695f4..08ca9d97b 100644 --- a/test/test_file.cpp +++ b/test/test_file.cpp @@ -302,6 +302,25 @@ TORRENT_TEST(file) TEST_EQUAL(ec, error_code()); TEST_CHECK(strcmp(test_buf, "test") == 0); f.close(); + + TEST_CHECK(f.open("test_file", file::read_only, ec)); + if (ec) + fprintf(stdout, "open failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + TEST_EQUAL(ec, error_code()); + file::iovec_t two_buffers[2]; + + std::memset(test_buf, 0, sizeof(test_buf)); + char test_buf2[5] = {0}; + two_buffers[0].iov_base = test_buf; + two_buffers[0].iov_len = 4; + two_buffers[1].iov_base = test_buf2; + two_buffers[1].iov_len = 4; + TEST_EQUAL(f.readv(0, two_buffers, 2, ec), 4); + if (ec) + fprintf(stdout, "readv failed: [%s] %s\n", ec.category().name(), ec.message().c_str()); + TEST_EQUAL(ec, error_code()); + TEST_CHECK(strcmp(test_buf, "test") == 0); + f.close(); } TORRENT_TEST(hard_link)