X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/f1828e6b0adb87bf0b99d3cfeeafbb76cbc6aab7..bbd8308cc01941e51e2cbcf88168a5560abe6042:/apt-pkg/contrib/fileutl.cc diff --git a/apt-pkg/contrib/fileutl.cc b/apt-pkg/contrib/fileutl.cc index 8c50874dc..fa0930dff 100644 --- a/apt-pkg/contrib/fileutl.cc +++ b/apt-pkg/contrib/fileutl.cc @@ -694,6 +694,25 @@ string flAbsPath(string File) 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 /*{{{*/ // --------------------------------------------------------------------- /* */ @@ -916,9 +935,12 @@ bool ChangeOwnerAndPermissionOfFile(char const * const requester, char const * c // ensure the file is owned by root and has good permissions struct passwd const * const pw = getpwnam(user); struct group const * const gr = getgrnam(group); - if (pw != NULL && gr != NULL && chown(file, pw->pw_uid, gr->gr_gid) != 0) + if (pw != NULL && gr != NULL && lchown(file, pw->pw_uid, gr->gr_gid) != 0) Res &= _error->WarningE(requester, "chown to %s:%s of file %s failed", user, group, file); } + struct stat Buf; + if (lstat(file, &Buf) != 0 || S_ISLNK(Buf.st_mode)) + return Res; if (chmod(file, mode) != 0) Res &= _error->WarningE(requester, "chmod 0%o of file %s failed", mode, file); return Res; @@ -1054,7 +1076,7 @@ public: { buffer.reset(); unsigned long long actualread = 0; - if (filefd->Read(buffer.get(), buffer.buffersize_max, &actualread) == false) + if (filefd->Read(buffer.getend(), buffer.free(), &actualread) == false) return nullptr; buffer.bufferend = actualread; if (buffer.size() == 0) @@ -1119,6 +1141,7 @@ public: return filefd->FileFdError("Seek on file %s because it couldn't be reopened", filefd->FileName.c_str()); buffer.reset(); + set_seekpos(0); if (To != 0) return filefd->Skip(To); @@ -1175,7 +1198,7 @@ public: virtual ~FileFdPrivate() {} }; /*}}}*/ -class APT_HIDDEN BufferedWriteFileFdPrivate : public FileFdPrivate { /*{{{*/ +class APT_HIDDEN BufferedWriteFileFdPrivate : public FileFdPrivate { /*{{{*/ protected: FileFdPrivate *wrapped; simple_buffer writebuffer; @@ -1185,63 +1208,63 @@ public: explicit BufferedWriteFileFdPrivate(FileFdPrivate *Priv) : FileFdPrivate(Priv->filefd), wrapped(Priv) {}; - virtual APT::Configuration::Compressor get_compressor() const override + virtual APT::Configuration::Compressor get_compressor() const APT_OVERRIDE { return wrapped->get_compressor(); } - virtual void set_compressor(APT::Configuration::Compressor const &compressor) override + virtual void set_compressor(APT::Configuration::Compressor const &compressor) APT_OVERRIDE { return wrapped->set_compressor(compressor); } - virtual unsigned int get_openmode() const override + virtual unsigned int get_openmode() const APT_OVERRIDE { return wrapped->get_openmode(); } - virtual void set_openmode(unsigned int openmode) override + virtual void set_openmode(unsigned int openmode) APT_OVERRIDE { return wrapped->set_openmode(openmode); } - virtual bool get_is_pipe() const override + virtual bool get_is_pipe() const APT_OVERRIDE { return wrapped->get_is_pipe(); } - virtual void set_is_pipe(bool is_pipe) override + virtual void set_is_pipe(bool is_pipe) APT_OVERRIDE { FileFdPrivate::set_is_pipe(is_pipe); wrapped->set_is_pipe(is_pipe); } - virtual unsigned long long get_seekpos() const override + virtual unsigned long long get_seekpos() const APT_OVERRIDE { return wrapped->get_seekpos(); } - virtual void set_seekpos(unsigned long long seekpos) override + virtual void set_seekpos(unsigned long long seekpos) APT_OVERRIDE { return wrapped->set_seekpos(seekpos); } - virtual bool InternalOpen(int const iFd, unsigned int const Mode) override + virtual bool InternalOpen(int const iFd, unsigned int const Mode) APT_OVERRIDE { if (InternalFlush() == false) return false; return wrapped->InternalOpen(iFd, Mode); } - virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) override + virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) APT_OVERRIDE { if (InternalFlush() == false) return -1; return wrapped->InternalUnbufferedRead(To, Size); } - virtual bool InternalReadError() override + virtual bool InternalReadError() APT_OVERRIDE { return wrapped->InternalReadError(); } - virtual char * InternalReadLine(char * To, unsigned long long Size) override + virtual char * InternalReadLine(char * To, unsigned long long Size) APT_OVERRIDE { if (InternalFlush() == false) return nullptr; return wrapped->InternalReadLine(To, Size); } - virtual bool InternalFlush() override + virtual bool InternalFlush() APT_OVERRIDE { while (writebuffer.empty() == false) { auto written = wrapped->InternalWrite(writebuffer.get(), @@ -1250,7 +1273,7 @@ public: if (written < 0 && errno == EINTR) continue; if (written < 0) - return false; + return wrapped->InternalWriteError(); writebuffer.bufferstart += written; } @@ -1258,7 +1281,7 @@ public: writebuffer.reset(); return true; } - virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override + virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE { // Optimisation: If the buffer is empty and we have more to write than // would fit in the buffer (or equal number of bytes), write directly. @@ -1273,45 +1296,45 @@ public: return written; } - virtual bool InternalWriteError() + virtual bool InternalWriteError() APT_OVERRIDE { return wrapped->InternalWriteError(); } - virtual bool InternalSeek(unsigned long long const To) + virtual bool InternalSeek(unsigned long long const To) APT_OVERRIDE { if (InternalFlush() == false) return false; return wrapped->InternalSeek(To); } - virtual bool InternalSkip(unsigned long long Over) + virtual bool InternalSkip(unsigned long long Over) APT_OVERRIDE { if (InternalFlush() == false) return false; return wrapped->InternalSkip(Over); } - virtual bool InternalTruncate(unsigned long long const Size) + virtual bool InternalTruncate(unsigned long long const Size) APT_OVERRIDE { if (InternalFlush() == false) return false; return wrapped->InternalTruncate(Size); } - virtual unsigned long long InternalTell() + virtual unsigned long long InternalTell() APT_OVERRIDE { if (InternalFlush() == false) return -1; return wrapped->InternalTell(); } - virtual unsigned long long InternalSize() + virtual unsigned long long InternalSize() APT_OVERRIDE { if (InternalFlush() == false) return -1; return wrapped->InternalSize(); } - virtual bool InternalClose(std::string const &FileName) + virtual bool InternalClose(std::string const &FileName) APT_OVERRIDE { return wrapped->InternalClose(FileName); } - virtual bool InternalAlwaysAutoClose() const + virtual bool InternalAlwaysAutoClose() const APT_OVERRIDE { return wrapped->InternalAlwaysAutoClose(); } @@ -1325,7 +1348,7 @@ class APT_HIDDEN GzipFileFdPrivate: public FileFdPrivate { /*{{{*/ #ifdef HAVE_ZLIB public: gzFile gz; - virtual bool InternalOpen(int const iFd, unsigned int const Mode) override + virtual bool InternalOpen(int const iFd, unsigned int const Mode) APT_OVERRIDE { if ((Mode & FileFd::ReadWrite) == FileFd::ReadWrite) gz = gzdopen(iFd, "r+"); @@ -1336,11 +1359,11 @@ public: filefd->Flags |= FileFd::Compressed; return gz != nullptr; } - virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) override + virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) APT_OVERRIDE { return gzread(gz, To, Size); } - virtual bool InternalReadError() override + virtual bool InternalReadError() APT_OVERRIDE { int err; char const * const errmsg = gzerror(gz, &err); @@ -1348,15 +1371,15 @@ public: return filefd->FileFdError("gzread: %s (%d: %s)", _("Read error"), err, errmsg); return FileFdPrivate::InternalReadError(); } - virtual char * InternalReadLine(char * To, unsigned long long Size) override + virtual char * InternalReadLine(char * To, unsigned long long Size) APT_OVERRIDE { return gzgets(gz, To, Size); } - virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override + virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE { return gzwrite(gz,From,Size); } - virtual bool InternalWriteError() override + virtual bool InternalWriteError() APT_OVERRIDE { int err; char const * const errmsg = gzerror(gz, &err); @@ -1364,7 +1387,7 @@ public: return filefd->FileFdError("gzwrite: %s (%d: %s)", _("Write error"), err, errmsg); return FileFdPrivate::InternalWriteError(); } - virtual bool InternalSeek(unsigned long long const To) override + virtual bool InternalSeek(unsigned long long const To) APT_OVERRIDE { off_t const res = gzseek(gz, To, SEEK_SET); if (res != (off_t)To) @@ -1373,7 +1396,7 @@ public: buffer.reset(); return true; } - virtual bool InternalSkip(unsigned long long Over) override + virtual bool InternalSkip(unsigned long long Over) APT_OVERRIDE { if (Over >= buffer.size()) { @@ -1393,11 +1416,11 @@ public: seekpos = res; return true; } - virtual unsigned long long InternalTell() override + virtual unsigned long long InternalTell() APT_OVERRIDE { return gztell(gz) - buffer.size(); } - virtual unsigned long long InternalSize() override + virtual unsigned long long InternalSize() APT_OVERRIDE { unsigned long long filesize = FileFdPrivate::InternalSize(); // only check gzsize if we are actually a gzip file, just checking for @@ -1431,7 +1454,7 @@ public: } return size; } - virtual bool InternalClose(std::string const &FileName) override + virtual bool InternalClose(std::string const &FileName) APT_OVERRIDE { if (gz == nullptr) return true; @@ -1452,7 +1475,7 @@ class APT_HIDDEN Bz2FileFdPrivate: public FileFdPrivate { /*{{{*/ #ifdef HAVE_BZ2 BZFILE* bz2; public: - virtual bool InternalOpen(int const iFd, unsigned int const Mode) override + virtual bool InternalOpen(int const iFd, unsigned int const Mode) APT_OVERRIDE { if ((Mode & FileFd::ReadWrite) == FileFd::ReadWrite) bz2 = BZ2_bzdopen(iFd, "r+"); @@ -1463,11 +1486,11 @@ public: filefd->Flags |= FileFd::Compressed; return bz2 != nullptr; } - virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) override + virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) APT_OVERRIDE { return BZ2_bzread(bz2, To, Size); } - virtual bool InternalReadError() override + virtual bool InternalReadError() APT_OVERRIDE { int err; char const * const errmsg = BZ2_bzerror(bz2, &err); @@ -1475,11 +1498,11 @@ public: return filefd->FileFdError("BZ2_bzread: %s %s (%d: %s)", filefd->FileName.c_str(), _("Read error"), err, errmsg); return FileFdPrivate::InternalReadError(); } - virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override + virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE { return BZ2_bzwrite(bz2, (void*)From, Size); } - virtual bool InternalWriteError() override + virtual bool InternalWriteError() APT_OVERRIDE { int err; char const * const errmsg = BZ2_bzerror(bz2, &err); @@ -1487,8 +1510,8 @@ public: return filefd->FileFdError("BZ2_bzwrite: %s %s (%d: %s)", filefd->FileName.c_str(), _("Write error"), err, errmsg); return FileFdPrivate::InternalWriteError(); } - virtual bool InternalStream() const override { return true; } - virtual bool InternalClose(std::string const &) override + virtual bool InternalStream() const APT_OVERRIDE { return true; } + virtual bool InternalClose(std::string const &) APT_OVERRIDE { if (bz2 == nullptr) return true; @@ -1514,7 +1537,7 @@ class APT_HIDDEN Lz4FileFdPrivate: public FileFdPrivate { /*{{{*/ // Count of bytes that the decompressor expects to read next, or buffer size. size_t next_to_load = APT_BUFFER_SIZE; public: - virtual bool InternalOpen(int const iFd, unsigned int const Mode) override + virtual bool InternalOpen(int const iFd, unsigned int const Mode) APT_OVERRIDE { if ((Mode & FileFd::ReadWrite) == FileFd::ReadWrite) return _error->Error("lz4 only supports write or read mode"); @@ -1534,7 +1557,7 @@ public: return false; unsigned int flags = (Mode & (FileFd::WriteOnly|FileFd::ReadOnly)); - if (backend.OpenDescriptor(iFd, flags) == false) + if (backend.OpenDescriptor(iFd, flags, FileFd::None, true) == false) return false; // Write the file header @@ -1547,7 +1570,7 @@ public: return true; } - virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) override + virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) APT_OVERRIDE { /* Keep reading as long as the compressor still wants to read */ while (next_to_load) { @@ -1585,13 +1608,13 @@ public: return 0; } - virtual bool InternalReadError() override + virtual bool InternalReadError() APT_OVERRIDE { char const * const errmsg = LZ4F_getErrorName(res); return filefd->FileFdError("LZ4F: %s %s (%zu: %s)", filefd->FileName.c_str(), _("Read error"), res, errmsg); } - virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override + virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE { unsigned long long const towrite = std::min(APT_BUFFER_SIZE, Size); @@ -1604,20 +1627,20 @@ public: return towrite; } - virtual bool InternalWriteError() override + virtual bool InternalWriteError() APT_OVERRIDE { char const * const errmsg = LZ4F_getErrorName(res); return filefd->FileFdError("LZ4F: %s %s (%zu: %s)", filefd->FileName.c_str(), _("Write error"), res, errmsg); } - virtual bool InternalStream() const override { return true; } + virtual bool InternalStream() const APT_OVERRIDE { return true; } - virtual bool InternalFlush() override + virtual bool InternalFlush() APT_OVERRIDE { return backend.Flush(); } - virtual bool InternalClose(std::string const &) override + virtual bool InternalClose(std::string const &) APT_OVERRIDE { /* Reset variables */ res = 0; @@ -1625,11 +1648,14 @@ public: if (cctx != nullptr) { - res = LZ4F_compressEnd(cctx, lz4_buffer.buffer, lz4_buffer.buffersize_max, nullptr); - if (LZ4F_isError(res) || backend.Write(lz4_buffer.buffer, res) == false) - return false; - if (!backend.Flush()) - return false; + if (filefd->Failed() == false) + { + res = LZ4F_compressEnd(cctx, lz4_buffer.buffer, lz4_buffer.buffersize_max, nullptr); + if (LZ4F_isError(res) || backend.Write(lz4_buffer.buffer, res) == false) + return false; + if (!backend.Flush()) + return false; + } if (!backend.Close()) return false; @@ -1642,6 +1668,11 @@ public: res = LZ4F_freeDecompressionContext(dctx); dctx = nullptr; } + if (backend.IsOpen()) + { + backend.Close(); + filefd->iFd = -1; + } return LZ4F_isError(res) == false; } @@ -1657,16 +1688,17 @@ class APT_HIDDEN LzmaFileFdPrivate: public FileFdPrivate { /*{{{*/ #ifdef HAVE_LZMA struct LZMAFILE { FILE* file; + FileFd * const filefd; uint8_t buffer[4096]; lzma_stream stream; lzma_ret err; bool eof; bool compressing; - LZMAFILE() : file(nullptr), eof(false), compressing(false) { buffer[0] = '\0'; } + LZMAFILE(FileFd * const fd) : file(nullptr), filefd(fd), eof(false), compressing(false) { buffer[0] = '\0'; } ~LZMAFILE() { - if (compressing == true) + if (compressing == true && filefd->Failed() == false) { size_t constexpr buffersize = sizeof(buffer)/sizeof(buffer[0]); while(true) @@ -1721,13 +1753,13 @@ class APT_HIDDEN LzmaFileFdPrivate: public FileFdPrivate { /*{{{*/ return 6; } public: - virtual bool InternalOpen(int const iFd, unsigned int const Mode) override + virtual bool InternalOpen(int const iFd, unsigned int const Mode) APT_OVERRIDE { if ((Mode & FileFd::ReadWrite) == FileFd::ReadWrite) return filefd->FileFdError("ReadWrite mode is not supported for lzma/xz files %s", filefd->FileName.c_str()); if (lzma == nullptr) - lzma = new LzmaFileFdPrivate::LZMAFILE; + lzma = new LzmaFileFdPrivate::LZMAFILE(filefd); if ((Mode & FileFd::WriteOnly) == FileFd::WriteOnly) lzma->file = fdopen(iFd, "w"); else @@ -1773,7 +1805,7 @@ public: } return true; } - virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) override + virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) APT_OVERRIDE { ssize_t Res; if (lzma->eof == true) @@ -1809,12 +1841,13 @@ public: } return Res; } - virtual bool InternalReadError() override + virtual bool InternalReadError() APT_OVERRIDE { return filefd->FileFdError("lzma_read: %s (%d)", _("Read error"), lzma->err); } - virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override + virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE { + ssize_t Res; lzma->stream.next_in = (uint8_t *)From; lzma->stream.avail_in = Size; lzma->stream.next_out = lzma->buffer; @@ -1825,16 +1858,28 @@ public: size_t const n = sizeof(lzma->buffer)/sizeof(lzma->buffer[0]) - lzma->stream.avail_out; size_t const m = (n == 0) ? 0 : fwrite(lzma->buffer, 1, n, lzma->file); if (m != n) - return -1; + { + Res = -1; + errno = 0; + } else - return Size - lzma->stream.avail_in; + { + Res = Size - lzma->stream.avail_in; + if (Res == 0) + { + // lzma run was okay, but produced no output… + Res = -1; + errno = EINTR; + } + } + return Res; } - virtual bool InternalWriteError() override + virtual bool InternalWriteError() APT_OVERRIDE { return filefd->FileFdError("lzma_write: %s (%d)", _("Write error"), lzma->err); } - virtual bool InternalStream() const override { return true; } - virtual bool InternalClose(std::string const &) override + virtual bool InternalStream() const APT_OVERRIDE { return true; } + virtual bool InternalClose(std::string const &) APT_OVERRIDE { delete lzma; lzma = nullptr; @@ -1851,7 +1896,7 @@ class APT_HIDDEN PipedFileFdPrivate: public FileFdPrivate /*{{{*/ by executing a specified binary and pipe in/out what we need */ { public: - virtual bool InternalOpen(int const, unsigned int const Mode) override + virtual bool InternalOpen(int const, unsigned int const Mode) APT_OVERRIDE { // collect zombies here in case we reopen if (compressor_pid > 0) @@ -1859,6 +1904,9 @@ public: if ((Mode & FileFd::ReadWrite) == FileFd::ReadWrite) return filefd->FileFdError("ReadWrite mode is not supported for file %s", filefd->FileName.c_str()); + if (compressor.Binary == "false") + return filefd->FileFdError("libapt has inbuilt support for the %s compression," + " 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) @@ -1949,17 +1997,22 @@ public: return true; } - virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) override + virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) APT_OVERRIDE { return read(filefd->iFd, To, Size); } - virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override + virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE { return write(filefd->iFd, From, Size); } - virtual bool InternalClose(std::string const &) override + virtual bool InternalClose(std::string const &) APT_OVERRIDE { bool Ret = true; + if (filefd->iFd != -1) + { + close(filefd->iFd); + filefd->iFd = -1; + } if (compressor_pid > 0) Ret &= ExecWait(compressor_pid, "FileFdCompressor", true); compressor_pid = -1; @@ -1972,12 +2025,12 @@ public: class APT_HIDDEN DirectFileFdPrivate: public FileFdPrivate /*{{{*/ { public: - virtual bool InternalOpen(int const, unsigned int const) override { return true; } - virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) override + virtual bool InternalOpen(int const, unsigned int const) APT_OVERRIDE { return true; } + virtual ssize_t InternalUnbufferedRead(void * const To, unsigned long long const Size) APT_OVERRIDE { return read(filefd->iFd, To, Size); } - virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) override + virtual ssize_t InternalWrite(void const * const From, unsigned long long const Size) APT_OVERRIDE { // files opened read+write are strange and only really "supported" for direct files if (buffer.size() != 0) @@ -1987,7 +2040,7 @@ public: } return write(filefd->iFd, From, Size); } - virtual bool InternalSeek(unsigned long long const To) override + virtual bool InternalSeek(unsigned long long const To) APT_OVERRIDE { off_t const res = lseek(filefd->iFd, To, SEEK_SET); if (res != (off_t)To) @@ -1996,7 +2049,7 @@ public: buffer.reset(); return true; } - virtual bool InternalSkip(unsigned long long Over) override + virtual bool InternalSkip(unsigned long long Over) APT_OVERRIDE { if (Over >= buffer.size()) { @@ -2016,7 +2069,7 @@ public: seekpos = res; return true; } - virtual bool InternalTruncate(unsigned long long const To) override + virtual bool InternalTruncate(unsigned long long const To) APT_OVERRIDE { if (buffer.size() != 0) { @@ -2032,16 +2085,16 @@ public: return filefd->FileFdError("Unable to truncate to %llu",To); return true; } - virtual unsigned long long InternalTell() override + virtual unsigned long long InternalTell() APT_OVERRIDE { return lseek(filefd->iFd,0,SEEK_CUR) - buffer.size(); } - virtual unsigned long long InternalSize() override + virtual unsigned long long InternalSize() APT_OVERRIDE { return filefd->FileSize(); } - virtual bool InternalClose(std::string const &) override { return true; } - virtual bool InternalAlwaysAutoClose() const override { return false; } + virtual bool InternalClose(std::string const &) APT_OVERRIDE { return true; } + virtual bool InternalAlwaysAutoClose() const APT_OVERRIDE { return false; } explicit DirectFileFdPrivate(FileFd * const filefd) : FileFdPrivate(filefd) {} virtual ~DirectFileFdPrivate() { InternalClose(""); } @@ -2424,10 +2477,18 @@ bool FileFd::Write(const void *From,unsigned long long Size) while (Res > 0 && Size > 0) { Res = d->InternalWrite(From, Size); - if (Res < 0 && errno == EINTR) - continue; + if (Res < 0) + { + if (errno == EINTR) + { + // trick the while-loop into running again + Res = 1; + errno = 0; + continue; + } return d->InternalWriteError(); + } From = (char const *)From + Res; Size -= Res; @@ -2567,7 +2628,7 @@ unsigned long long FileFd::Size() /* */ bool FileFd::Close() { - if (Flush() == false) + if (Failed() == false && Flush() == false) return false; if (iFd == -1) return true; @@ -2587,7 +2648,7 @@ bool FileFd::Close() } if ((Flags & Replace) == Replace) { - if (rename(TemporaryFileName.c_str(), FileName.c_str()) != 0) + if (Failed() == false && rename(TemporaryFileName.c_str(), FileName.c_str()) != 0) Res &= _error->Errno("rename",_("Problem renaming the file %s to %s"), TemporaryFileName.c_str(), FileName.c_str()); FileName = TemporaryFileName; // for the unlink() below.