diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index 0944194c..0d1e014a 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -284,12 +284,10 @@ ssize_t AbstractDiskWriter::readDataInternal(unsigned char* data, size_t len, int64_t offset) { if(mapaddr_) { - ssize_t readlen; - if(offset > maplen_) { - readlen = 0; - } else { - readlen = std::min(static_cast(maplen_ - offset), len); + if (offset >= maplen_) { + return 0; } + auto readlen = std::min(maplen_ - offset, static_cast(len)); memcpy(data, mapaddr_ + offset, readlen); return readlen; } else { @@ -355,6 +353,14 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset) } } else { int64_t filesize = size(); + + if (filesize == 0) { + // mapping 0 length file is useless. Also munmap with size == + // 0 will fail with EINVAL. + enableMmap_ = false; + return; + } + int errNum = 0; if(static_cast(len + offset) <= filesize) { #ifdef __MINGW32__ diff --git a/src/BtFileAllocationEntry.cc b/src/BtFileAllocationEntry.cc index 44553354..89a4c7c4 100644 --- a/src/BtFileAllocationEntry.cc +++ b/src/BtFileAllocationEntry.cc @@ -58,9 +58,11 @@ BtFileAllocationEntry::~BtFileAllocationEntry() {} void BtFileAllocationEntry::prepareForNextAction (std::vector>& commands, DownloadEngine* e) { - BtSetup().setup(commands, getRequestGroup(), e, - getRequestGroup()->getOption().get()); - if(getRequestGroup()->getOption()->getAsBool(PREF_ENABLE_MMAP)) { + auto &option = getRequestGroup()->getOption(); + + BtSetup().setup(commands, getRequestGroup(), e, option.get()); + if(option->getAsBool(PREF_ENABLE_MMAP) && + option->get(PREF_FILE_ALLOCATION) != V_NONE) { getRequestGroup()->getPieceStorage()->getDiskAdaptor()->enableMmap(); } if(!getRequestGroup()->downloadFinished()) { diff --git a/src/StreamFileAllocationEntry.cc b/src/StreamFileAllocationEntry.cc index dfe1f679..de851da6 100644 --- a/src/StreamFileAllocationEntry.cc +++ b/src/StreamFileAllocationEntry.cc @@ -60,10 +60,13 @@ void StreamFileAllocationEntry::prepareForNextAction (std::vector>& commands, DownloadEngine* e) { + auto &option = getRequestGroup()->getOption(); + // For DownloadContext::resetDownloadStartTime(), see also // RequestGroup::createInitialCommand() getRequestGroup()->getDownloadContext()->resetDownloadStartTime(); - if(getRequestGroup()->getOption()->getAsBool(PREF_ENABLE_MMAP)) { + if(option->getAsBool(PREF_ENABLE_MMAP) && + option->get(PREF_FILE_ALLOCATION) != V_NONE) { getRequestGroup()->getPieceStorage()->getDiskAdaptor()->enableMmap(); } if(getNextCommand()) {