From cf8bd76213945cf8f1b5c7ffe7855e20407e7ff3 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 17 Nov 2007 17:39:05 +0000 Subject: [PATCH] 2007-11-18 Tatsuhiro Tsujikawa Removed. * src/PiecedSegment.{h, cc} (operator==)(operator!=) Use Segment::operator==() * src/HttpConnection.cc * src/Segment.h Updated usage * src/version_usage.cc Added EINTR treatment. * src/SocketCore.cc * src/AbstractDiskWriter.cc Rewritten. * src/Util.cc (rangedFileCopy) --- ChangeLog | 19 +++++++ src/AbstractDiskWriter.cc | 15 +++++- src/BtSetup.cc | 2 - src/ByteArrayDiskWriter.cc | 1 - src/DownloadCommand.cc | 1 - src/FileAllocationDispatcherCommand.cc | 1 - src/GrowSegment.cc | 1 - src/HttpConnection.cc | 4 +- src/PiecedSegment.cc | 10 ---- src/PiecedSegment.h | 5 -- src/Segment.h | 5 ++ src/SocketCore.cc | 24 +++++---- src/Util.cc | 72 ++++++++++---------------- src/version_usage.cc | 15 ++++-- 14 files changed, 91 insertions(+), 84 deletions(-) diff --git a/ChangeLog b/ChangeLog index 61d70630..0326d19b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2007-11-18 Tatsuhiro Tsujikawa + + Removed. + * src/PiecedSegment.{h, cc} (operator==)(operator!=) + + Use Segment::operator==() + * src/HttpConnection.cc + * src/Segment.h + + Updated usage + * src/version_usage.cc + + Added EINTR treatment. + * src/SocketCore.cc + * src/AbstractDiskWriter.cc + + Rewritten. + * src/Util.cc (rangedFileCopy) + 2007-11-17 Tatsuhiro Tsujikawa Fixed typo. diff --git a/src/AbstractDiskWriter.cc b/src/AbstractDiskWriter.cc index 0e6fa87e..d27c3cab 100644 --- a/src/AbstractDiskWriter.cc +++ b/src/AbstractDiskWriter.cc @@ -99,12 +99,23 @@ void AbstractDiskWriter::createFile(const string& filename, int32_t addFlags) int32_t AbstractDiskWriter::writeDataInternal(const unsigned char* data, int32_t len) { - return write(fd, data, len); + int32_t writtenLength = 0; + while(writtenLength < len) { + int32_t ret = 0; + while((ret = write(fd, data+writtenLength, len-writtenLength)) == -1 && errno == EINTR); + if(ret == -1) { + return -1; + } + writtenLength += ret; + } + return writtenLength; } int32_t AbstractDiskWriter::readDataInternal(unsigned char* data, int32_t len) { - return read(fd, data, len); + int32_t ret = 0; + while((ret = read(fd, data, len)) == -1 && errno == EINTR); + return ret; } void AbstractDiskWriter::seek(int64_t offset) diff --git a/src/BtSetup.cc b/src/BtSetup.cc index 845e1a49..6302c8b7 100644 --- a/src/BtSetup.cc +++ b/src/BtSetup.cc @@ -65,8 +65,6 @@ Commands BtSetup::setup(RequestGroup* requestGroup, if(btContext.isNull()) { return commands; } - // TODO following process is moved to BtSetup - // commands commands.push_back(new TrackerWatcherCommand(CUIDCounterSingletonHolder::instance()->newID(), requestGroup, diff --git a/src/ByteArrayDiskWriter.cc b/src/ByteArrayDiskWriter.cc index 864d167c..750e0437 100644 --- a/src/ByteArrayDiskWriter.cc +++ b/src/ByteArrayDiskWriter.cc @@ -82,7 +82,6 @@ int32_t ByteArrayDiskWriter::readData(unsigned char* data, int32_t len, int64_t { buf.seekg(position, ios::beg); buf.read(reinterpret_cast(data), len); - // TODO we have to call buf.clear() here? YES buf.clear(); return buf.gcount(); } diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc index 7042a3ed..cd2cf5e6 100644 --- a/src/DownloadCommand.cc +++ b/src/DownloadCommand.cc @@ -79,7 +79,6 @@ DownloadCommand::~DownloadCommand() { } bool DownloadCommand::executeInternal() { - // TODO we need to specify the sum of all segmentMan's download speed here. if(maxDownloadSpeedLimit > 0 && maxDownloadSpeedLimit < _requestGroup->getSegmentMan()->calculateDownloadSpeed()) { e->commands.push_back(this); diff --git a/src/FileAllocationDispatcherCommand.cc b/src/FileAllocationDispatcherCommand.cc index 146d33fc..21235ce4 100644 --- a/src/FileAllocationDispatcherCommand.cc +++ b/src/FileAllocationDispatcherCommand.cc @@ -57,7 +57,6 @@ bool FileAllocationDispatcherCommand::execute() if(!_e->_fileAllocationMan->isFileAllocationBeingExecuted() && _e->_fileAllocationMan->nextFileAllocationEntryExists()) { FileAllocationEntryHandle entry = _e->_fileAllocationMan->popNextFileAllocationEntry(); - // TODO we have to change message int32_t newCUID = CUIDCounterSingletonHolder::instance()->newID(); logger->info(MSG_FILE_ALLOCATION_DISPATCH, newCUID); FileAllocationCommand* command = diff --git a/src/GrowSegment.cc b/src/GrowSegment.cc index dc8f833b..59cf547b 100644 --- a/src/GrowSegment.cc +++ b/src/GrowSegment.cc @@ -57,4 +57,3 @@ PieceHandle GrowSegment::getPiece() const { return _piece; } - diff --git a/src/HttpConnection.cc b/src/HttpConnection.cc index a1f7c815..57ebbbaf 100644 --- a/src/HttpConnection.cc +++ b/src/HttpConnection.cc @@ -129,11 +129,9 @@ bool HttpConnection::isIssued(const SegmentHandle& segment) const for(HttpRequestEntries::const_iterator itr = outstandingHttpRequests.begin(); itr != outstandingHttpRequests.end(); ++itr) { HttpRequestHandle httpRequest = (*itr)->getHttpRequest(); - // TODO fix this using operator== - if(httpRequest->getSegment().get() == segment.get()) { + if(httpRequest->getSegment() == segment) { return true; } } return false; } - diff --git a/src/PiecedSegment.cc b/src/PiecedSegment.cc index c7de5c92..00c1f8af 100644 --- a/src/PiecedSegment.cc +++ b/src/PiecedSegment.cc @@ -95,13 +95,3 @@ PieceHandle PiecedSegment::getPiece() const { return _piece; } - -bool PiecedSegment::operator==(const PiecedSegment& segment) const -{ - return _piece == segment._piece; -} - -bool PiecedSegment::operator!=(const PiecedSegment& segment) const -{ - return !(*this == segment); -} diff --git a/src/PiecedSegment.h b/src/PiecedSegment.h index 5956e897..2fb7e5f1 100644 --- a/src/PiecedSegment.h +++ b/src/PiecedSegment.h @@ -83,11 +83,6 @@ public: virtual void clear(); virtual PieceHandle getPiece() const; - - bool operator==(const PiecedSegment& segment) const; - - bool operator!=(const PiecedSegment& segment) const; - }; typedef SharedHandle PiecedSegmentHandle; diff --git a/src/Segment.h b/src/Segment.h index c6df8957..de92686f 100644 --- a/src/Segment.h +++ b/src/Segment.h @@ -65,6 +65,11 @@ public: virtual void clear() = 0; virtual PieceHandle getPiece() const = 0; + + bool operator==(const Segment& segment) const + { + return getIndex() == segment.getIndex(); + } }; typedef SharedHandle SegmentHandle; diff --git a/src/SocketCore.cc b/src/SocketCore.cc index 829d67b6..403dc470 100644 --- a/src/SocketCore.cc +++ b/src/SocketCore.cc @@ -95,7 +95,7 @@ void SocketCore::beginListen(int32_t port) #ifdef __MINGW32__ ::closesocket(sockfd); #else - close(sockfd); + while(close(sockfd) == -1 && errno == EINTR); #endif // __MINGW32__ sockfd = -1; throw new DlAbortEx(EX_SOCKET_SET_OPT, errorMsg()); @@ -124,10 +124,10 @@ SocketCore* SocketCore::acceptConnection() const socklen_t len = sizeof(sockaddr); memset((char*)&sockaddr, 0, sizeof(sockaddr)); int32_t fd; - if((fd = accept(sockfd, (struct sockaddr*)&sockaddr, &len)) == -1) { + while((fd = accept(sockfd, (struct sockaddr*)&sockaddr, &len)) == -1 && errno == EINTR); + if(fd == -1) { throw new DlAbortEx(EX_SOCKET_ACCEPT, errorMsg()); } - SocketCore* s = new SocketCore(fd); return s; } @@ -165,7 +165,7 @@ void SocketCore::establishConnection(const string& host, int32_t port) } SOCKOPT_T sockopt = 1; if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(socklen_t)) < 0) { - close(sockfd); + while(close(sockfd) == -1 && errno == EINTR); sockfd = -1; throw new DlAbortEx(EX_SOCKET_SET_OPT, errorMsg()); } @@ -250,9 +250,9 @@ void SocketCore::closeConnection() #endif // HAVE_LIBGNUTLS if(sockfd != -1) { #ifdef __MINGW32__ - ::closesocket(sockfd); + ::closesocket(sockfd); #else - close(sockfd); + while(close(sockfd) == -1 && errno == EINTR); #endif // __MINGW32__ sockfd = -1; } @@ -331,7 +331,9 @@ void SocketCore::writeData(const char* data, int32_t len) int32_t ret = 0; if(!secure) { - if((ret = send(sockfd, data, (size_t)len, 0)) != len) { + while((ret = send(sockfd, data, (size_t)len, 0)) == -1 && errno == EINTR); + // TODO assuming Blocking mode. + if(ret != len) { throw new DlRetryEx(EX_SOCKET_SEND, errorMsg()); } } else { @@ -354,8 +356,9 @@ void SocketCore::readData(char* data, int32_t& len) { int32_t ret = 0; - if(!secure) { - if ((ret = recv(sockfd, data, (size_t)len, 0)) < 0) { + if(!secure) { + while((ret = recv(sockfd, data, (size_t)len, 0)) == -1 && errno == EINTR); + if(ret == -1) { throw new DlRetryEx(EX_SOCKET_RECV, errorMsg()); } } else { @@ -381,7 +384,8 @@ void SocketCore::peekData(char* data, int32_t& len) int32_t ret = 0; if(!secure) { - if ((ret = recv(sockfd, data, (size_t)len, MSG_PEEK)) < 0) { + while((ret = recv(sockfd, data, (size_t)len, MSG_PEEK)) == -1 && errno == EINTR); + if(ret == -1) { throw new DlRetryEx(EX_SOCKET_PEEK, errorMsg()); } } else { diff --git a/src/Util.cc b/src/Util.cc index 525fbdcf..d4060fe9 100644 --- a/src/Util.cc +++ b/src/Util.cc @@ -40,6 +40,7 @@ #include "a2time.h" #include "DlAbortEx.h" #include "BitfieldMan.h" +#include "DefaultDiskWriter.h" #include #include #include @@ -343,52 +344,35 @@ void Util::fileCopy(const string& dest, const string& src) { void Util::rangedFileCopy(const string& dest, const string& src, int64_t srcOffset, int64_t length) { int32_t bufSize = 4096; - char buf[bufSize]; - int32_t destFd = -1; - int32_t srcFd = -1; - try { - if((destFd = open(dest.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_BINARY, OPEN_MODE)) == -1) { - throw new DlAbortEx(EX_FILE_OPEN, dest.c_str(), strerror(errno)); + unsigned char buf[bufSize]; + DefaultDiskWriter srcdw; + DefaultDiskWriter destdw; + + srcdw.openExistingFile(src); + destdw.initAndOpenFile(dest); + + int32_t x = length/bufSize; + int32_t r = length%bufSize; + + int64_t initialOffset = srcOffset; + for(int32_t i = 0; i < x; ++i) { + int32_t readLength = 0; + while(readLength < bufSize) { + int32_t ret = srcdw.readData(buf, bufSize-readLength, srcOffset); + destdw.writeData(buf, ret, srcOffset-initialOffset); + srcOffset += ret; + readLength += ret; } - if((srcFd = open(src.c_str(), O_RDONLY|O_BINARY, OPEN_MODE)) == -1) { - throw new DlAbortEx(EX_FILE_OPEN, src.c_str(), strerror(errno)); - } - if(lseek(srcFd, srcOffset, SEEK_SET) != srcOffset) { - throw new DlAbortEx(EX_FILE_SEEK, src.c_str(), strerror(errno)); - } - int32_t x = length/bufSize; - int32_t r = length%bufSize; - for(int32_t i = 0; i < x; i++) { - int32_t readLength; - if((readLength = read(srcFd, buf, bufSize)) == -1 || readLength != bufSize) { - throw new DlAbortEx(EX_FILE_READ, src.c_str(), strerror(errno)); - } - if(write(destFd, buf, readLength) == -1) { - throw new DlAbortEx(EX_FILE_WRITE, dest.c_str(), strerror(errno)); - } - } - if(r > 0) { - int32_t readLength; - if((readLength = read(srcFd, buf, r)) == -1 || readLength != r) { - throw new DlAbortEx(EX_FILE_READ, src.c_str(), strerror(errno)); - } - if(write(destFd, buf, r) == -1) { - throw new DlAbortEx(EX_FILE_WRITE, dest.c_str(), strerror(errno)); - } - } - close(srcFd); - close(destFd); - srcFd = -1; - destFd = -1; - } catch(RecoverableException* e) { - if(srcFd != -1) { - close(srcFd); - } - if(destFd != -1) { - close(destFd); - } - throw; } + if(r > 0) { + int32_t readLength = 0; + while(readLength < r) { + int32_t ret = srcdw.readData(buf, r-readLength, srcOffset); + destdw.writeData(buf, ret, srcOffset-initialOffset); + srcOffset += ret; + readLength += ret; + } + } } bool Util::isPowerOf(int32_t num, int32_t base) { diff --git a/src/version_usage.cc b/src/version_usage.cc index c73554d9..5f5a34c6 100644 --- a/src/version_usage.cc +++ b/src/version_usage.cc @@ -210,7 +210,8 @@ void showUsage() { " the same used by Netscape and Mozilla.") << endl; #if defined ENABLE_BITTORRENT || ENABLE_METALINK cout << _(" -S, --show-files Print file listing of .torrent or .metalink file\n" - " and exit.") << endl; + " and exit. More detailed information will be listed\n" + " in case of torrent file.") << endl; cout << _(" --select-file=INDEX... Set file to download by specifing its index.\n" " You can find the file index using the\n" " --show-files option. Multiple indexes can be\n" @@ -270,8 +271,12 @@ void showUsage() { cout << _(" -h, --help Print this message and exit.") << endl; cout << endl; cout << "URL:" << endl; - cout << _(" You can specify multiple URLs. All URLs must point to the same file\n" - " or downloading will fail.") << endl; + cout << _(" You can specify multiple URLs. Unless you specify -Z option, all URLs must\n" + " point to the same file or downloading will fail.") << endl; + cout << _(" You can specify both torrent file with -T option and URLs. By doing this,\n" + " download a file from both torrent swarm and http/ftp server at the same time,\n" + " while the data from http/ftp are uploaded to the torrent swarm. Note that\n" + " only single file torrent can be integrated with http/ftp.") << endl; cout << endl; cout << _("Examples:") << endl; cout << _(" Download a file using 1 connection:") << endl; @@ -295,7 +300,9 @@ void showUsage() { cout << _(" Download only selected files:") << endl; cout << " aria2c -T test.torrent dir/file1.zip dir/file2.zip" << endl; cout << _(" Print file listing of .torrent file:") << endl; - cout << " aria2c -T test.torrent -S" << endl; + cout << " aria2c -T test.torrent -S" << endl; + cout << _(" Download a file using torrent and http/ftp server") << endl; + cout << " aria2c -T test.torrent http://host1/file ftp://host2/file" << endl; #endif // ENABLE_BITTORRENT #ifdef ENABLE_METALINK cout << endl;