summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBill Hoffman <bill.hoffman@kitware.com>2009-11-09 01:54:13 (GMT)
committerBill Hoffman <bill.hoffman@kitware.com>2009-11-09 01:54:13 (GMT)
commit4fd75f959aa363d940ba699a57bf96036ecf1d02 (patch)
treeedec0448b70b95d65a661cdcdac8454954e6f515
parent79b8d61ae93cb75a9f45a96ccc769ccb3807da0e (diff)
downloadCMake-4fd75f959aa363d940ba699a57bf96036ecf1d02.zip
CMake-4fd75f959aa363d940ba699a57bf96036ecf1d02.tar.gz
CMake-4fd75f959aa363d940ba699a57bf96036ecf1d02.tar.bz2
add better error checking and support for symlinks to cpack's use of libarchive
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx77
1 files changed, 49 insertions, 28 deletions
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index c9432ec..86c6148 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -170,6 +170,15 @@ int cmCPackArchiveGenerator::InitializeInternal()
int cmCPackArchiveGenerator::CompressFiles(const char* outFileName,
const char* toplevel, const std::vector<std::string>& files)
{
+ int res = ARCHIVE_OK;
+#define CHECK_ARCHIVE_ERROR(res, msg) \
+ if(res != ARCHIVE_OK)\
+ {\
+ cmCPackLogger(cmCPackLog::LOG_ERROR, msg \
+ << archive_error_string(a) \
+ << "\n"); \
+ return 0; \
+ }
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: "
<< (toplevel ? toplevel : "(NULL)") << std::endl);
// create a new archive
@@ -181,14 +190,16 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName,
gf->Open(outFileName, false, true);
StreamData data(gf, this);
// pass callbacks to archive_write_open to handle stream
- archive_write_open(a,
- &data,
- OpenArchive,
- WriteArchive,
- CloseArchive);
+ res = archive_write_open(a,
+ &data,
+ OpenArchive,
+ WriteArchive,
+ CloseArchive);
+ CHECK_ARCHIVE_ERROR(res, "archive_write_open:");
// create a new disk struct
struct archive* disk = archive_read_disk_new();
- archive_read_disk_set_standard_lookup(disk);
+ res = archive_read_disk_set_standard_lookup(disk);
+ CHECK_ARCHIVE_ERROR(res, "archive_read_disk_set_standard_lookup:");
std::vector<std::string>::const_iterator fileIt;
for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt )
{
@@ -198,31 +209,41 @@ int cmCPackArchiveGenerator::CompressFiles(const char* outFileName,
std::string rp = cmSystemTools::RelativePath(toplevel, fileIt->c_str());
// Set the name of the entry to the file name
archive_entry_set_pathname(entry, rp.c_str());
- // get the information about the file from stat
- struct stat s;
- stat(fileIt->c_str(), &s);
- archive_read_disk_entry_from_file(disk, entry, -1, &s);
+ res = archive_read_disk_entry_from_file(disk, entry, -1, 0);
+ CHECK_ARCHIVE_ERROR(res, "archive_read_disk_entry_from_file:");
// write entry header
- archive_write_header(a, entry);
- // now copy contents of file into archive a
- FILE* file = fopen(fileIt->c_str(), "rb");
- if(!file)
- {
- cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with fopen(): "
- << fileIt->c_str()
- << strerror(errno)
- << std::endl);
- return 0;
- }
- char buff[cmCPackTGZ_Data_BlockSize];
- int len = fread(buff, 1, sizeof(buff), file);
- while (len > 0)
+ res = archive_write_header(a, entry);
+ CHECK_ARCHIVE_ERROR(res, "archive_write_header:");
+ // the entry size can be 0 if it is a symlink
+ if(archive_entry_size(entry) > 0)
{
- archive_write_data(a, buff, len);
- len = fread(buff, 1, sizeof(buff), file);
+ // now copy contents of file into archive a
+ FILE* file = fopen(fileIt->c_str(), "rb");
+ if(!file)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with fopen(): "
+ << fileIt->c_str()
+ << strerror(errno)
+ << std::endl);
+ return 0;
+ }
+ char buff[cmCPackTGZ_Data_BlockSize];
+ size_t len = fread(buff, 1, sizeof(buff), file);
+ while (len > 0)
+ {
+ size_t wlen = archive_write_data(a, buff, len);
+ if(wlen != len)
+ {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "archive_write_data(): "
+ << "tried to write " << len << "\n"
+ << "write " << wlen << "\n");
+ return 0;
+ }
+ len = fread(buff, 1, sizeof(buff), file);
+ }
+ // close the file and free the entry
+ fclose(file);
}
- // close the file and free the entry
- fclose(file);
archive_entry_free(entry);
}
// close the archive and finish the write