From cd740cff7d9b2a126673ba9e30b2b33a9035dba0 Mon Sep 17 00:00:00 2001 From: Jack Pappas Date: Mon, 19 Oct 2020 13:03:01 -0400 Subject: [PATCH] Partial fix for #10. On non-Windows platforms, detect whether calls to pread()/pwrite() succeed; when those calls fail, follow the existing pattern we have for the Windows-based code to print an error message and return 0. (We may want to make additional improvements in this area, but at least Windows and Linux/Mac behavior are now consistent). --- src/SDSFile.cpp | 55 +++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/src/SDSFile.cpp b/src/SDSFile.cpp index 411a5af5..c78a5044 100644 --- a/src/SDSFile.cpp +++ b/src/SDSFile.cpp @@ -635,6 +635,8 @@ void SDSFileClose(SDS_FILE_HANDLE handle) { #else +#include + const char* GetLastErrorMessage() { return (const char*)strerror(errno); } @@ -649,12 +651,6 @@ void SDS_DESTROY_EVENTHANDLE(SDS_EVENT_HANDLE handle) { #include -ssize_t linux_pwrite(int fildes, const void* buf, size_t nbyte, off_t offset) { - // Try pwrite first - ssize_t result = pwrite(fildes, buf, nbyte, offset); - return result; -} - // returns < 0 if file does not exist or error INT64 SDSFileSize(const char* fileName) { struct stat statbuf; @@ -722,7 +718,7 @@ INT64 SDSFileReadChunk(SDS_EVENT_HANDLE eventHandle, SDS_FILE_HANDLE fileHandle, char* cbuffer = (char*)buffer; while (bufferSize > MAX_READSIZE_ALLOWED) { - totalRead += pread(fileHandle, cbuffer, MAX_READSIZE_ALLOWED, bufferPos); + totalRead += SDSFileReadChunk(eventHandle, fileHandle, cbuffer, MAX_READSIZE_ALLOWED, bufferPos); cbuffer += MAX_READSIZE_ALLOWED; bufferPos += MAX_READSIZE_ALLOWED; @@ -730,22 +726,30 @@ INT64 SDSFileReadChunk(SDS_EVENT_HANDLE eventHandle, SDS_FILE_HANDLE fileHandle, } if (bufferSize) { - totalRead += pread(fileHandle, cbuffer, (size_t)bufferSize, bufferPos); + totalRead += SDSFileReadChunk(eventHandle, fileHandle, cbuffer, bufferSize, bufferPos); } if (totalRead != origSize) { - printf("readchunk failed for fd %d -- %lld vs %lld\n", fileHandle, origSize, totalRead); + printf("!!readchunk failed for fd %d -- %lld vs %lld (errno %d)\n", fileHandle, origSize, totalRead, errno); + return 0; } return totalRead; } else { + ssize_t bytes_read = pread(fileHandle, buffer, (size_t)bufferSize, bufferPos); - INT64 result = pread(fileHandle, buffer, (size_t)bufferSize, bufferPos); + // pread() returns -1 on error; make sure the read actually succeeded. + if (bytes_read == -1) + { + printf("!!readchunk failed for fd %d -- %lld vs %lld (errno %d)\n", fileHandle, bufferSize, bytes_read, errno); + return 0; + } - if (result != bufferSize) { - printf("readchunk failed for fd %d -- %lld vs %lld\n", fileHandle, bufferSize, result); + if (bytes_read != bufferSize) { + printf("!!readchunk failed for fd %d -- %lld vs %lld (errno %d)\n", fileHandle, bufferSize, bytes_read, errno); + return 0; } - return result; + return bytes_read; } } @@ -759,7 +763,7 @@ INT64 SDSFileWriteChunk(SDS_EVENT_HANDLE eventHandle, SDS_FILE_HANDLE fileHandle char* cbuffer = (char*)buffer; while (bufferSize > MAX_READSIZE_ALLOWED) { - totalWritten += linux_pwrite(fileHandle, cbuffer, (size_t)MAX_READSIZE_ALLOWED, bufferPos); + totalWritten += SDSFileWriteChunk(eventHandle, fileHandle, cbuffer, MAX_READSIZE_ALLOWED, bufferPos); cbuffer += MAX_READSIZE_ALLOWED; bufferPos += MAX_READSIZE_ALLOWED; @@ -767,21 +771,32 @@ INT64 SDSFileWriteChunk(SDS_EVENT_HANDLE eventHandle, SDS_FILE_HANDLE fileHandle } if (bufferSize) { - totalWritten += linux_pwrite(fileHandle, cbuffer, (size_t)bufferSize, bufferPos); + totalWritten += SDSFileWriteChunk(eventHandle, fileHandle, cbuffer, bufferSize, bufferPos); } if (totalWritten != origSize) { - printf("writechunk failed for large fd %d -- %lld vs %lld offset:%lld\n", fileHandle, origSize, totalWritten, bufferPos); + printf("write chunk error buff:%p size:%lld pos:%lld errno:%d\n", buffer, bufferSize, bufferPos, errno); + return 0; } + return totalWritten; } else { - INT64 result = linux_pwrite(fileHandle, buffer, (size_t)bufferSize, bufferPos); - if (result != bufferSize) { - printf("writechunk failed for fd %d -- %lld vs %lld offset:%lld\n", fileHandle, bufferSize, result, bufferPos); + ssize_t bytes_written = pwrite(fileHandle, buffer, (size_t)bufferSize, bufferPos); + + // pwrite() returns -1 on error; make sure the write actually succeeded. + if (bytes_written == -1) + { + printf("!!Write failed done buff:%p size:%lld pos:%lld errno:%d\n", buffer, bufferSize, bufferPos, errno); + return 0; + } + + if (bytes_written != bufferSize) { + printf("!!Write failed small buff:%p size:%lld pos:%lld errno:%d\n", buffer, bufferSize, bufferPos, errno); + return 0; } - return result; + return bytes_written; } }