diff options
Diffstat (limited to 'apt-pkg/contrib/fileutl.cc')
-rw-r--r-- | apt-pkg/contrib/fileutl.cc | 220 |
1 files changed, 114 insertions, 106 deletions
diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 6e13b91d9..ac2879017 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -186,7 +186,8 @@ bool RunScripts(const char *Cnf) /* The caller is expected to set things so that failure causes erasure */ bool CopyFile(FileFd &From,FileFd &To) { - if (From.IsOpen() == false || To.IsOpen() == false) + if (From.IsOpen() == false || To.IsOpen() == false || + From.Failed() == true || To.Failed() == true) return false; // Buffered copy between fds @@ -245,17 +246,20 @@ int GetLock(string File,bool Errors) fl.l_len = 0; if (fcntl(FD,F_SETLK,&fl) == -1) { + // always close to not leak resources + int Tmp = errno; + close(FD); + errno = Tmp; + if (errno == ENOLCK) { _error->Warning(_("Not using locking for nfs mounted lock file %s"),File.c_str()); return dup(0); // Need something for the caller to close - } + } + if (Errors == true) _error->Errno("open",_("Could not get lock %s"),File.c_str()); - int Tmp = errno; - close(FD); - errno = Tmp; return -1; } @@ -883,7 +887,7 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, return Open(FileName, ReadOnly, Gzip, Perms); if (Compress == Auto && (Mode & WriteOnly) == WriteOnly) - return _error->Error("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str()); + return FileFdError("Autodetection on %s only works in ReadOnly openmode!", FileName.c_str()); std::vector<APT::Configuration::Compressor> const compressors = APT::Configuration::getCompressors(); std::vector<APT::Configuration::Compressor>::const_iterator compressor = compressors.begin(); @@ -936,17 +940,17 @@ bool FileFd::Open(string FileName,unsigned int const Mode,CompressMode Compress, case Auto: case Extension: // Unreachable - return _error->Error("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str()); + return FileFdError("Opening File %s in None, Auto or Extension should be already handled?!?", FileName.c_str()); } for (; compressor != compressors.end(); ++compressor) if (compressor->Name == name) break; if (compressor == compressors.end()) - return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str()); + return FileFdError("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str()); } if (compressor == compressors.end()) - return _error->Error("Can't find a match for specified compressor mode for file %s", FileName.c_str()); + return FileFdError("Can't find a match for specified compressor mode for file %s", FileName.c_str()); return Open(FileName, Mode, *compressor, Perms); } bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Compressor const &compressor, unsigned long const Perms) @@ -955,9 +959,9 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co Flags = AutoClose; if ((Mode & WriteOnly) != WriteOnly && (Mode & (Atomic | Create | Empty | Exclusive)) != 0) - return _error->Error("ReadOnly mode for %s doesn't accept additional flags!", FileName.c_str()); + return FileFdError("ReadOnly mode for %s doesn't accept additional flags!", FileName.c_str()); if ((Mode & ReadWrite) == 0) - return _error->Error("No openmode provided in FileFd::Open for %s", FileName.c_str()); + return FileFdError("No openmode provided in FileFd::Open for %s", FileName.c_str()); if ((Mode & Atomic) == Atomic) { @@ -1003,7 +1007,7 @@ bool FileFd::Open(string FileName,unsigned int const Mode,APT::Configuration::Co close (iFd); iFd = -1; } - return _error->Errno("open",_("Could not open file %s"), FileName.c_str()); + return FileFdErrno("open",_("Could not open file %s"), FileName.c_str()); } SetCloseExec(iFd,true); @@ -1032,14 +1036,19 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, CompressMode Compre case Xz: name = "xz"; break; case Auto: case Extension: - return _error->Error("Opening Fd %d in Auto or Extension compression mode is not supported", Fd); + if (AutoClose == true && Fd != -1) + close(Fd); + return FileFdError("Opening Fd %d in Auto or Extension compression mode is not supported", Fd); } for (; compressor != compressors.end(); ++compressor) if (compressor->Name == name) break; if (compressor == compressors.end()) - return _error->Error("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str()); - + { + if (AutoClose == true && Fd != -1) + close(Fd); + return FileFdError("Can't find a configured compressor %s for file %s", name.c_str(), FileName.c_str()); + } return OpenDescriptor(Fd, Mode, *compressor, AutoClose); } bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration::Compressor const &compressor, bool AutoClose) @@ -1061,11 +1070,21 @@ bool FileFd::OpenDescriptor(int Fd, unsigned int const Mode, APT::Configuration: else iFd = Fd; this->FileName = ""; - if (OpenInternDescriptor(Mode, compressor) == false) + if (Fd == -1 || OpenInternDescriptor(Mode, compressor) == false) { - if (AutoClose) + if (iFd != -1 && ( +#ifdef HAVE_ZLIB + compressor.Name == "gzip" || +#endif +#ifdef HAVE_BZ2 + compressor.Name == "bzip2" || +#endif + AutoClose == true)) + { close (iFd); - return _error->Errno("gzdopen",_("Could not open file descriptor %d"), Fd); + iFd = -1; + } + return FileFdError(_("Could not open file descriptor %d"), Fd); } return true; } @@ -1127,10 +1146,7 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C ExecWait(d->compressor_pid, "FileFdCompressor", true); if ((Mode & ReadWrite) == ReadWrite) - { - Flags |= Fail; - return _error->Error("ReadWrite mode is not supported for file %s", FileName.c_str()); - } + return FileFdError("ReadWrite mode is not supported for file %s", FileName.c_str()); bool const Comp = (Mode & WriteOnly) == WriteOnly; if (Comp == false) @@ -1153,10 +1169,7 @@ bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::C // Create a data pipe int Pipe[2] = {-1,-1}; if (pipe(Pipe) != 0) - { - Flags |= Fail; - return _error->Errno("pipe",_("Failed to create subprocess IPC")); - } + return FileFdErrno("pipe",_("Failed to create subprocess IPC")); for (int J = 0; J != 2; J++) SetCloseExec(Pipe[J],true); @@ -1230,11 +1243,9 @@ FileFd::~FileFd() { Close(); if (d != NULL) - { d->CloseDown(FileName); - delete d; - d = NULL; - } + delete d; + d = NULL; } /*}}}*/ // FileFd::Read - Read a bit of the file /*{{{*/ @@ -1266,14 +1277,13 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) { if (errno == EINTR) continue; - Flags |= Fail; #ifdef HAVE_ZLIB if (d != NULL && d->gz != NULL) { int err; char const * const errmsg = gzerror(d->gz, &err); if (err != Z_ERRNO) - return _error->Error("gzread: %s (%d: %s)", _("Read error"), err, errmsg); + return FileFdError("gzread: %s (%d: %s)", _("Read error"), err, errmsg); } #endif #ifdef HAVE_BZ2 @@ -1282,10 +1292,10 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) int err; char const * const errmsg = BZ2_bzerror(d->bz2, &err); if (err != BZ_IO_ERROR) - return _error->Error("BZ2_bzread: %s (%d: %s)", _("Read error"), err, errmsg); + return FileFdError("BZ2_bzread: %s (%d: %s)", _("Read error"), err, errmsg); } #endif - return _error->Errno("read",_("Read error")); + return FileFdErrno("read",_("Read error")); } To = (char *)To + Res; @@ -1306,9 +1316,8 @@ bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual) Flags |= HitEof; return true; } - - Flags |= Fail; - return _error->Error(_("read, still have %llu to read but none left"), Size); + + return FileFdError(_("read, still have %llu to read but none left"), Size); } /*}}}*/ // FileFd::ReadLine - Read a complete line from the file /*{{{*/ @@ -1364,14 +1373,13 @@ bool FileFd::Write(const void *From,unsigned long long Size) continue; if (Res < 0) { - Flags |= Fail; #ifdef HAVE_ZLIB if (d != NULL && d->gz != NULL) { int err; char const * const errmsg = gzerror(d->gz, &err); if (err != Z_ERRNO) - return _error->Error("gzwrite: %s (%d: %s)", _("Write error"), err, errmsg); + return FileFdError("gzwrite: %s (%d: %s)", _("Write error"), err, errmsg); } #endif #ifdef HAVE_BZ2 @@ -1380,10 +1388,10 @@ bool FileFd::Write(const void *From,unsigned long long Size) int err; char const * const errmsg = BZ2_bzerror(d->bz2, &err); if (err != BZ_IO_ERROR) - return _error->Error("BZ2_bzwrite: %s (%d: %s)", _("Write error"), err, errmsg); + return FileFdError("BZ2_bzwrite: %s (%d: %s)", _("Write error"), err, errmsg); } #endif - return _error->Errno("write",_("Write error")); + return FileFdErrno("write",_("Write error")); } From = (char *)From + Res; @@ -1395,9 +1403,8 @@ bool FileFd::Write(const void *From,unsigned long long Size) if (Size == 0) return true; - - Flags |= Fail; - return _error->Error(_("write, still have %llu to write but couldn't"), Size); + + return FileFdError(_("write, still have %llu to write but couldn't"), Size); } bool FileFd::Write(int Fd, const void *From, unsigned long long Size) { @@ -1441,13 +1448,13 @@ bool FileFd::Seek(unsigned long long To) return Skip(To - seekpos); if ((d->openmode & ReadOnly) != ReadOnly) - { - Flags |= Fail; - return _error->Error("Reopen is only implemented for read-only files!"); - } + return FileFdError("Reopen is only implemented for read-only files!"); #ifdef HAVE_BZ2 - if (d->bz2 != NULL) - BZ2_bzclose(d->bz2); + if (d->bz2 != NULL) + { + BZ2_bzclose(d->bz2); + d->bz2 = NULL; + } #endif if (iFd != -1) close(iFd); @@ -1462,17 +1469,11 @@ bool FileFd::Seek(unsigned long long To) if (lseek(d->compressed_fd, 0, SEEK_SET) != 0) iFd = d->compressed_fd; if (iFd < 0) - { - Flags |= Fail; - return _error->Error("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!"); - } + return FileFdError("Reopen is not implemented for pipes opened with FileFd::OpenDescriptor()!"); } if (OpenInternDescriptor(d->openmode, d->compressor) == false) - { - Flags |= Fail; - return _error->Error("Seek on file %s because it couldn't be reopened", FileName.c_str()); - } + return FileFdError("Seek on file %s because it couldn't be reopened", FileName.c_str()); if (To != 0) return Skip(To); @@ -1488,10 +1489,7 @@ bool FileFd::Seek(unsigned long long To) #endif res = lseek(iFd,To,SEEK_SET); if (res != (signed)To) - { - Flags |= Fail; - return _error->Error("Unable to seek to %llu", To); - } + return FileFdError("Unable to seek to %llu", To); if (d != NULL) d->seekpos = To; @@ -1515,10 +1513,7 @@ bool FileFd::Skip(unsigned long long Over) { unsigned long long toread = std::min((unsigned long long) sizeof(buffer), Over); if (Read(buffer, toread) == false) - { - Flags |= Fail; - return _error->Error("Unable to seek ahead %llu",Over); - } + return FileFdError("Unable to seek ahead %llu",Over); Over -= toread; } return true; @@ -1532,10 +1527,7 @@ bool FileFd::Skip(unsigned long long Over) #endif res = lseek(iFd,Over,SEEK_CUR); if (res < 0) - { - Flags |= Fail; - return _error->Error("Unable to seek ahead %llu",Over); - } + return FileFdError("Unable to seek ahead %llu",Over); if (d != NULL) d->seekpos = res; @@ -1549,17 +1541,11 @@ bool FileFd::Truncate(unsigned long long To) { #if defined HAVE_ZLIB || defined HAVE_BZ2 if (d != NULL && (d->gz != NULL || d->bz2 != NULL)) - { - Flags |= Fail; - return _error->Error("Truncating compressed files is not implemented (%s)", FileName.c_str()); - } + return FileFdError("Truncating compressed files is not implemented (%s)", FileName.c_str()); #endif if (ftruncate(iFd,To) != 0) - { - Flags |= Fail; - return _error->Error("Unable to truncate to %llu",To); - } - + return FileFdError("Unable to truncate to %llu",To); + return true; } /*}}}*/ @@ -1587,10 +1573,7 @@ unsigned long long FileFd::Tell() #endif Res = lseek(iFd,0,SEEK_CUR); if (Res == (off_t)-1) - { - Flags |= Fail; - _error->Errno("lseek","Failed to determine the current file position"); - } + FileFdErrno("lseek","Failed to determine the current file position"); if (d != NULL) d->seekpos = Res; return Res; @@ -1603,10 +1586,7 @@ unsigned long long FileFd::FileSize() { struct stat Buf; if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0) - { - Flags |= Fail; - return _error->Errno("fstat","Unable to determine the file size"); - } + return FileFdErrno("fstat","Unable to determine the file size"); // for compressor pipes st_size is undefined and at 'best' zero if ((d != NULL && d->pipe == true) || S_ISFIFO(Buf.st_mode)) @@ -1616,10 +1596,7 @@ unsigned long long FileFd::FileSize() if (d != NULL) d->pipe = true; if (stat(FileName.c_str(), &Buf) != 0) - { - Flags |= Fail; - return _error->Errno("stat","Unable to determine the file size"); - } + return FileFdErrno("stat","Unable to determine the file size"); } return Buf.st_size; @@ -1644,7 +1621,11 @@ unsigned long long FileFd::Size() char ignore[1000]; unsigned long long read = 0; do { - Read(ignore, sizeof(ignore), &read); + if (Read(ignore, sizeof(ignore), &read) == false) + { + Seek(oldSeek); + return 0; + } } while(read != 0); size = Tell(); Seek(oldSeek); @@ -1662,14 +1643,14 @@ unsigned long long FileFd::Size() // FIXME: Size for gz-files is limited by 32bit… no largefile support if (lseek(iFd, -4, SEEK_END) < 0) { - Flags |= Fail; - return _error->Errno("lseek","Unable to seek to end of gzipped file"); + FileFdErrno("lseek","Unable to seek to end of gzipped file"); + return 0; } - size = 0L; + size = 0; if (read(iFd, &size, 4) != 4) { - Flags |= Fail; - return _error->Errno("read","Unable to read original size of gzipped file"); + FileFdErrno("read","Unable to read original size of gzipped file"); + return 0; } #ifdef WORDS_BIGENDIAN @@ -1681,8 +1662,8 @@ unsigned long long FileFd::Size() if (lseek(iFd, oldPos, SEEK_SET) < 0) { - Flags |= Fail; - return _error->Errno("lseek","Unable to seek in gzipped file"); + FileFdErrno("lseek","Unable to seek in gzipped file"); + return 0; } return size; @@ -1700,8 +1681,7 @@ time_t FileFd::ModificationTime() struct stat Buf; if ((d == NULL || d->pipe == false) && fstat(iFd,&Buf) != 0) { - Flags |= Fail; - _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); + FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); return 0; } @@ -1714,8 +1694,7 @@ time_t FileFd::ModificationTime() d->pipe = true; if (stat(FileName.c_str(), &Buf) != 0) { - Flags |= Fail; - _error->Errno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); + FileFdErrno("fstat","Unable to determine the modification time of file %s", FileName.c_str()); return 0; } } @@ -1771,11 +1750,40 @@ bool FileFd::Close() bool FileFd::Sync() { if (fsync(iFd) != 0) + return FileFdErrno("sync",_("Problem syncing the file")); + return true; +} + /*}}}*/ +// FileFd::FileFdErrno - set Fail and call _error->Errno *{{{*/ +bool FileFd::FileFdErrno(const char *Function, const char *Description,...) +{ + Flags |= Fail; + va_list args; + size_t msgSize = 400; + int const errsv = errno; + while (true) { - Flags |= Fail; - return _error->Errno("sync",_("Problem syncing the file")); + va_start(args,Description); + if (_error->InsertErrno(GlobalError::ERROR, Function, Description, args, errsv, msgSize) == false) + break; + va_end(args); } - return true; + return false; +} + /*}}}*/ +// FileFd::FileFdError - set Fail and call _error->Error *{{{*/ +bool FileFd::FileFdError(const char *Description,...) { + Flags |= Fail; + va_list args; + size_t msgSize = 400; + while (true) + { + va_start(args,Description); + if (_error->Insert(GlobalError::ERROR, Description, args, msgSize) == false) + break; + va_end(args); + } + return false; } /*}}}*/ |