+ this->FileName = "";
+ if (OpenInternDescriptor(Mode, compressor) == false)
+ {
+ if (AutoClose)
+ close (iFd);
+ return _error->Errno("gzdopen",_("Could not open file descriptor %d"), Fd);
+ }
+ return true;
+}
+bool FileFd::OpenInternDescriptor(unsigned int const Mode, APT::Configuration::Compressor const &compressor)
+{
+ d->compressor = compressor;
+ if (compressor.Name == "." || compressor.Binary.empty() == true)
+ return true;
+#if APT_USE_ZLIB
+ else if (compressor.Name == "gzip")
+ {
+ if ((Mode & ReadWrite) == ReadWrite)
+ d->gz = gzdopen(iFd, "r+");
+ else if ((Mode & WriteOnly) == WriteOnly)
+ d->gz = gzdopen(iFd, "w");
+ else
+ d->gz = gzdopen (iFd, "r");
+ if (d->gz == NULL)
+ return false;
+ Flags |= Compressed;
+ return true;
+ }
+#endif
+
+ if ((Mode & ReadWrite) == ReadWrite)
+ return _error->Error("ReadWrite mode is not supported for file %s", FileName.c_str());
+
+ bool const Comp = (Mode & WriteOnly) == WriteOnly;
+ // Handle 'decompression' of empty files
+ if (Comp == false)
+ {
+ struct stat Buf;
+ fstat(iFd, &Buf);
+ if (Buf.st_size == 0 && S_ISFIFO(Buf.st_mode) == false)
+ return true;
+
+ // We don't need the file open - instead let the compressor open it
+ // as he properly knows better how to efficiently read from 'his' file
+ if (FileName.empty() == false)
+ close(iFd);
+ }
+
+ // Create a data pipe
+ int Pipe[2] = {-1,-1};
+ if (pipe(Pipe) != 0)
+ return _error->Errno("pipe",_("Failed to create subprocess IPC"));
+ for (int J = 0; J != 2; J++)
+ SetCloseExec(Pipe[J],true);
+
+ d->compressed_fd = iFd;
+ d->pipe = true;
+
+ if (Comp == true)
+ iFd = Pipe[1];
+ else
+ iFd = Pipe[0];
+
+ // The child..
+ d->compressor_pid = ExecFork();
+ if (d->compressor_pid == 0)
+ {
+ if (Comp == true)
+ {
+ dup2(d->compressed_fd,STDOUT_FILENO);
+ dup2(Pipe[0],STDIN_FILENO);