mirror of https://github.com/aria2/aria2
2007-09-02 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Now *.aria2 contorol file is first saved to *.aria2__temp and if it is successful, then renamed to *.aria2. This prevents *.aria2 file from being truncated or corrupted when file system becomes out of space. * src/DefaultBtProgressInfoFile.cc (save) * src/SegmentMan.cc (save) * test/DefaultBtProgressInfoFileTest.cc (testSave): Implemented.pull/1/head
parent
2bea8759c4
commit
57471aac9c
10
ChangeLog
10
ChangeLog
|
@ -1,3 +1,13 @@
|
|||
2007-09-02 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Now *.aria2 contorol file is first saved to *.aria2__temp and if
|
||||
it is successful, then renamed to *.aria2.
|
||||
This prevents *.aria2 file from being truncated or corrupted when
|
||||
file system becomes out of space.
|
||||
* src/DefaultBtProgressInfoFile.cc (save)
|
||||
* src/SegmentMan.cc (save)
|
||||
* test/DefaultBtProgressInfoFileTest.cc (testSave): Implemented.
|
||||
|
||||
2007-09-01 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
|
||||
|
||||
Reduced the fragmentation of bitfield in http/ftp download.
|
||||
|
|
|
@ -60,7 +60,8 @@ DefaultBtProgressInfoFile::~DefaultBtProgressInfoFile() {}
|
|||
|
||||
void DefaultBtProgressInfoFile::save() {
|
||||
logger->info(MSG_SAVING_SEGMENT_FILE, filename.c_str());
|
||||
FILE* file = openFile(filename, "wb");
|
||||
string filenameTemp = filename+"__temp";
|
||||
FILE* file = openFile(filenameTemp, "wb");
|
||||
try {
|
||||
if(fwrite(btContext->getInfoHash(),
|
||||
btContext->getInfoHashLength(), 1, file) < 1) {
|
||||
|
@ -90,6 +91,11 @@ void DefaultBtProgressInfoFile::save() {
|
|||
throw new DlAbortEx(EX_SEGMENT_FILE_WRITE,
|
||||
filename.c_str(), strerror(errno));
|
||||
}
|
||||
|
||||
if(rename(filenameTemp.c_str(), filename.c_str()) == -1) {
|
||||
throw new DlAbortEx(EX_SEGMENT_FILE_WRITE,
|
||||
filename.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
void DefaultBtProgressInfoFile::load() {
|
||||
|
|
|
@ -99,7 +99,9 @@ void SegmentMan::save() const {
|
|||
}
|
||||
string segFilename = getSegmentFilePath();
|
||||
logger->info(MSG_SAVING_SEGMENT_FILE, segFilename.c_str());
|
||||
FILE* segFile = openSegFile(segFilename, "wb");
|
||||
|
||||
string segFilenameTemp = segFilename+"__temp";
|
||||
FILE* segFile = openSegFile(segFilenameTemp, "wb");
|
||||
try {
|
||||
if(fwrite(&totalSize, sizeof(totalSize), 1, segFile) < 1) {
|
||||
throw string("writeError");
|
||||
|
@ -140,6 +142,11 @@ void SegmentMan::save() const {
|
|||
throw new DlAbortEx(EX_SEGMENT_FILE_WRITE,
|
||||
segFilename.c_str(), strerror(errno));
|
||||
}
|
||||
|
||||
if(rename(segFilenameTemp.c_str(), segFilename.c_str()) == -1) {
|
||||
throw new DlAbortEx(EX_SEGMENT_FILE_WRITE,
|
||||
segFilename.c_str(), strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
FILE* SegmentMan::openSegFile(const string& segFilename, const string& mode) const {
|
||||
|
|
|
@ -3,6 +3,10 @@
|
|||
#include "Option.h"
|
||||
#include "Util.h"
|
||||
#include "Exception.h"
|
||||
#include "MockBtContext.h"
|
||||
#include "MockPeerStorage.h"
|
||||
#include "MockPieceStorage.h"
|
||||
#include "prefs.h"
|
||||
#include <cppunit/extensions/HelperMacros.h>
|
||||
|
||||
using namespace std;
|
||||
|
@ -31,4 +35,59 @@ public:
|
|||
CPPUNIT_TEST_SUITE_REGISTRATION(DefaultBtProgressInfoFileTest);
|
||||
|
||||
void DefaultBtProgressInfoFileTest::testSave() {
|
||||
unsigned char infoHash[] = {
|
||||
0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa,
|
||||
0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff,
|
||||
};
|
||||
|
||||
Option option;
|
||||
option.put(PREF_DIR, ".");
|
||||
|
||||
MockBtContextHandle btContext = new MockBtContext();
|
||||
btContext->setInfoHash(infoHash);
|
||||
btContext->setName("save-temp");
|
||||
|
||||
BitfieldMan bitfield(1024, 80*1024);
|
||||
bitfield.setAllBit();
|
||||
bitfield.unsetBit(79);
|
||||
MockPieceStorageHandle pieceStorage = new MockPieceStorage();
|
||||
pieceStorage->setBitfield(&bitfield);
|
||||
pieceStorage->setCompletedLength(80896);
|
||||
|
||||
MockPeerStorageHandle peerStorage = new MockPeerStorage();
|
||||
TransferStat stat;
|
||||
stat.sessionUploadLength = 1024;
|
||||
peerStorage->setStat(stat);
|
||||
|
||||
BtRuntimeHandle btRuntime = new BtRuntime();
|
||||
|
||||
DefaultBtProgressInfoFile infoFile(btContext, &option);
|
||||
infoFile.setPieceStorage(pieceStorage);
|
||||
infoFile.setPeerStorage(peerStorage);
|
||||
infoFile.setBtRuntime(btRuntime);
|
||||
|
||||
infoFile.save();
|
||||
|
||||
// read and validate
|
||||
ifstream in(string(option.get(PREF_DIR)+"/"+btContext->getName()+".aria2").c_str());
|
||||
unsigned char infoHashRead[20];
|
||||
in.read((char*)infoHashRead, sizeof(infoHashRead));
|
||||
CPPUNIT_ASSERT_EQUAL(string("112233445566778899aabbccddeeff00ffffffff"),
|
||||
Util::toHex(infoHashRead, sizeof(infoHashRead)));
|
||||
unsigned char bitfieldRead[10];
|
||||
in.read((char*)bitfieldRead, sizeof(bitfieldRead));
|
||||
CPPUNIT_ASSERT_EQUAL(string("fffffffffffffffffffe"),
|
||||
Util::toHex(bitfieldRead, sizeof(bitfieldRead)));
|
||||
int64_t allTimeDownloadLengthRead = 0;
|
||||
in.read((char*)&allTimeDownloadLengthRead, sizeof(allTimeDownloadLengthRead));
|
||||
CPPUNIT_ASSERT_EQUAL((int64_t)80896, allTimeDownloadLengthRead);
|
||||
|
||||
int64_t allTimeUploadLengthRead = 0;
|
||||
in.read((char*)&allTimeUploadLengthRead, sizeof(allTimeUploadLengthRead));
|
||||
CPPUNIT_ASSERT_EQUAL((int64_t)1024, allTimeUploadLengthRead);
|
||||
|
||||
string temp;
|
||||
getline(in, temp);
|
||||
CPPUNIT_ASSERT_EQUAL(string(""), temp);
|
||||
CPPUNIT_ASSERT(in.eof());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
TESTS = aria2c
|
||||
check_PROGRAMS = $(TESTS)
|
||||
aria2c_SOURCES = AllTest.cc\
|
||||
DefaultBtProgressInfoFileTest.cc\
|
||||
RequestGroupTest.cc\
|
||||
PStringBuildVisitorTest.cc\
|
||||
ParameterizedStringParserTest.cc\
|
||||
|
|
|
@ -110,12 +110,13 @@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
|||
CONFIG_HEADER = $(top_builddir)/config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
am__EXEEXT_1 = aria2c$(EXEEXT)
|
||||
am__aria2c_SOURCES_DIST = AllTest.cc RequestGroupTest.cc \
|
||||
PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
|
||||
UtilTest.cc AlphaNumberDecoratorTest.cc \
|
||||
FileUriListParserTest.cc StreamUriListParserTest.cc \
|
||||
HttpHeaderProcessorTest.cc CookieBoxTest.cc RequestTest.cc \
|
||||
CookieParserTest.cc HttpRequestTest.cc CookieBoxFactoryTest.cc \
|
||||
am__aria2c_SOURCES_DIST = AllTest.cc DefaultBtProgressInfoFileTest.cc \
|
||||
RequestGroupTest.cc PStringBuildVisitorTest.cc \
|
||||
ParameterizedStringParserTest.cc UtilTest.cc \
|
||||
AlphaNumberDecoratorTest.cc FileUriListParserTest.cc \
|
||||
StreamUriListParserTest.cc HttpHeaderProcessorTest.cc \
|
||||
CookieBoxTest.cc RequestTest.cc CookieParserTest.cc \
|
||||
HttpRequestTest.cc CookieBoxFactoryTest.cc \
|
||||
RequestGroupManTest.cc RequestFactoryTest.cc \
|
||||
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
|
||||
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
|
||||
|
@ -195,8 +196,9 @@ am__aria2c_SOURCES_DIST = AllTest.cc RequestGroupTest.cc \
|
|||
@ENABLE_METALINK_TRUE@am__objects_3 = MetalinkerTest.$(OBJEXT) \
|
||||
@ENABLE_METALINK_TRUE@ MetalinkEntryTest.$(OBJEXT) \
|
||||
@ENABLE_METALINK_TRUE@ Xml2MetalinkProcessorTest.$(OBJEXT)
|
||||
am_aria2c_OBJECTS = AllTest.$(OBJEXT) RequestGroupTest.$(OBJEXT) \
|
||||
PStringBuildVisitorTest.$(OBJEXT) \
|
||||
am_aria2c_OBJECTS = AllTest.$(OBJEXT) \
|
||||
DefaultBtProgressInfoFileTest.$(OBJEXT) \
|
||||
RequestGroupTest.$(OBJEXT) PStringBuildVisitorTest.$(OBJEXT) \
|
||||
ParameterizedStringParserTest.$(OBJEXT) UtilTest.$(OBJEXT) \
|
||||
AlphaNumberDecoratorTest.$(OBJEXT) \
|
||||
FileUriListParserTest.$(OBJEXT) \
|
||||
|
@ -403,12 +405,13 @@ target_cpu = @target_cpu@
|
|||
target_os = @target_os@
|
||||
target_vendor = @target_vendor@
|
||||
TESTS = aria2c
|
||||
aria2c_SOURCES = AllTest.cc RequestGroupTest.cc \
|
||||
PStringBuildVisitorTest.cc ParameterizedStringParserTest.cc \
|
||||
UtilTest.cc AlphaNumberDecoratorTest.cc \
|
||||
FileUriListParserTest.cc StreamUriListParserTest.cc \
|
||||
HttpHeaderProcessorTest.cc CookieBoxTest.cc RequestTest.cc \
|
||||
CookieParserTest.cc HttpRequestTest.cc CookieBoxFactoryTest.cc \
|
||||
aria2c_SOURCES = AllTest.cc DefaultBtProgressInfoFileTest.cc \
|
||||
RequestGroupTest.cc PStringBuildVisitorTest.cc \
|
||||
ParameterizedStringParserTest.cc UtilTest.cc \
|
||||
AlphaNumberDecoratorTest.cc FileUriListParserTest.cc \
|
||||
StreamUriListParserTest.cc HttpHeaderProcessorTest.cc \
|
||||
CookieBoxTest.cc RequestTest.cc CookieParserTest.cc \
|
||||
HttpRequestTest.cc CookieBoxFactoryTest.cc \
|
||||
RequestGroupManTest.cc RequestFactoryTest.cc \
|
||||
NetrcAuthResolverTest.cc DefaultAuthResolverTest.cc \
|
||||
OptionHandlerTest.cc SegmentManTest.cc BitfieldManTest.cc \
|
||||
|
@ -516,6 +519,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtAnnounceTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtContextTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtMessageDispatcherTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtProgressInfoFileTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultBtRequestFactoryTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultDiskWriterTest.Po@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/DefaultPeerListProcessorTest.Po@am__quote@
|
||||
|
|
Loading…
Reference in New Issue