return AbsPath;
}
/*}}}*/
+std::string flNormalize(std::string file) /*{{{*/
+{
+ if (file.empty())
+ return file;
+ // do some normalisation by removing // and /./ from the path
+ size_t found = string::npos;
+ while ((found = file.find("/./")) != string::npos)
+ file.replace(found, 3, "/");
+ while ((found = file.find("//")) != string::npos)
+ file.replace(found, 2, "/");
+
+ if (APT::String::Startswith(file, "/dev/null"))
+ {
+ file.erase(strlen("/dev/null"));
+ return file;
+ }
+ return file;
+}
+ /*}}}*/
// SetCloseExec - Set the close on exec flag /*{{{*/
// ---------------------------------------------------------------------
/* */
writebuffer.bufferstart += written;
}
-
writebuffer.reset();
- return true;
+ return wrapped->InternalFlush();
}
virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE
{
" but was forced to ignore it in favor of an external binary – which isn't installed.", compressor.Name.c_str());
bool const Comp = (Mode & FileFd::WriteOnly) == FileFd::WriteOnly;
- if (Comp == false)
+ if (Comp == false && filefd->iFd != -1)
{
// Handle 'decompression' of empty files
struct stat Buf;
- fstat(filefd->iFd, &Buf);
+ if (fstat(filefd->iFd, &Buf) != 0)
+ return filefd->FileFdErrno("fstat", "Could not stat fd %d for file %s", filefd->iFd, filefd->FileName.c_str());
if (Buf.st_size == 0 && S_ISFIFO(Buf.st_mode) == false)
return true;
gracefully. */
bool FileFd::Read(void *To,unsigned long long Size,unsigned long long *Actual)
{
- if (d == nullptr)
+ if (d == nullptr || Failed())
return false;
ssize_t Res = 1;
errno = 0;
}
return FileFdError(_("read, still have %llu to read but none left"), Size);
+}
+bool FileFd::Read(int const Fd, void *To, unsigned long long Size, unsigned long long * const Actual)
+{
+ ssize_t Res = 1;
+ errno = 0;
+ if (Actual != nullptr)
+ *Actual = 0;
+ *static_cast<char *>(To) = '\0';
+ while (Res > 0 && Size > 0)
+ {
+ Res = read(Fd, To, Size);
+ if (Res < 0)
+ {
+ if (errno == EINTR)
+ {
+ Res = 1;
+ errno = 0;
+ continue;
+ }
+ return _error->Errno("read", _("Read error"));
+ }
+ To = static_cast<char *>(To) + Res;
+ Size -= Res;
+ if (Actual != 0)
+ *Actual += Res;
+ }
+ if (Size == 0)
+ return true;
+ if (Actual != nullptr)
+ return true;
+ return _error->Error(_("read, still have %llu to read but none left"), Size);
}
/*}}}*/
// FileFd::ReadLine - Read a complete line from the file /*{{{*/
char* FileFd::ReadLine(char *To, unsigned long long const Size)
{
*To = '\0';
- if (d == nullptr)
+ if (d == nullptr || Failed())
return nullptr;
return d->InternalReadLine(To, Size);
}
// FileFd::Flush - Flush the file /*{{{*/
bool FileFd::Flush()
{
+ if (Failed())
+ return false;
if (d == nullptr)
return true;
// FileFd::Write - Write to the file /*{{{*/
bool FileFd::Write(const void *From,unsigned long long Size)
{
- if (d == nullptr)
+ if (d == nullptr || Failed())
return false;
ssize_t Res = 1;
errno = 0;
// FileFd::Seek - Seek in the file /*{{{*/
bool FileFd::Seek(unsigned long long To)
{
- if (d == nullptr)
+ if (d == nullptr || Failed())
return false;
Flags &= ~HitEof;
return d->InternalSeek(To);
// FileFd::Skip - Skip over data in the file /*{{{*/
bool FileFd::Skip(unsigned long long Over)
{
- if (d == nullptr)
+ if (d == nullptr || Failed())
return false;
return d->InternalSkip(Over);
}
// FileFd::Truncate - Truncate the file /*{{{*/
bool FileFd::Truncate(unsigned long long To)
{
- if (d == nullptr)
+ if (d == nullptr || Failed())
return false;
// truncating /dev/null is always successful - as we get an error otherwise
if (To == 0 && FileName == "/dev/null")
/* */
unsigned long long FileFd::Tell()
{
- if (d == nullptr)
+ if (d == nullptr || Failed())
return false;
off_t const Res = d->InternalTell();
if (Res == (off_t)-1)
unsigned long long FileFd::Size()
{
if (d == nullptr)
- return false;
+ return 0;
return d->InternalSize();
}
/*}}}*/
va_list args;
size_t msgSize = 400;
int const errsv = errno;
- while (true)
- {
+ bool retry;
+ do {
va_start(args,Description);
- if (_error->InsertErrno(GlobalError::ERROR, Function, Description, args, errsv, msgSize) == false)
- break;
+ retry = _error->InsertErrno(GlobalError::ERROR, Function, Description, args, errsv, msgSize);
va_end(args);
- }
+ } while (retry);
return false;
}
/*}}}*/
Flags |= Fail;
va_list args;
size_t msgSize = 400;
- while (true)
- {
+ bool retry;
+ do {
va_start(args,Description);
- if (_error->Insert(GlobalError::ERROR, Description, args, msgSize) == false)
- break;
+ retry = _error->Insert(GlobalError::ERROR, Description, args, msgSize);
va_end(args);
- }
+ } while (retry);
return false;
}
/*}}}*/