errno = 0; if (write(fd, lz4buf, header_size) != header_size)
{ /* If write didn't set errno, assume problem is no disk space */
wwmethod->lasterrno = errno ? errno : ENOSPC;
(void) LZ4F_freeCompressionContext(ctx);
pg_free(lz4buf);
close(fd); return NULL;
}
} #endif
/* Do pre-padding on non-compressed files */ if (pad_to_size && wwmethod->compression_algorithm == PG_COMPRESSION_NONE)
{
ssize_t rc;
if (LZ4F_isError(compressed))
{
f->wwmethod->lasterrstring = LZ4F_getErrorName(compressed); return -1;
}
errno = 0; if (write(df->fd, df->lz4buf, compressed) != compressed)
{ /* If write didn't set errno, assume problem is no disk space */
f->wwmethod->lasterrno = errno ? errno : ENOSPC; return -1;
}
inbuf = ((char *) inbuf) + chunk;
}
/* Our caller keeps track of the uncompressed size. */
r = (ssize_t) count;
} else #endif
{
errno = 0;
r = write(df->fd, buf, count); if (r != count)
{ /* If write didn't set errno, assume problem is no disk space */
f->wwmethod->lasterrno = errno ? errno : ENOSPC;
}
} if (r > 0)
df->base.currpos += r; return r;
}
#ifdef HAVE_LIBZ if (f->wwmethod->compression_algorithm == PG_COMPRESSION_GZIP)
{
errno = 0; /* in case gzclose() doesn't set it */
r = gzclose(df->gzfp);
} else #endif #ifdef USE_LZ4 if (f->wwmethod->compression_algorithm == PG_COMPRESSION_LZ4)
{
size_t compressed;
if (LZ4F_isError(compressed))
{
f->wwmethod->lasterrstring = LZ4F_getErrorName(compressed); return -1;
}
errno = 0; if (write(df->fd, df->lz4buf, compressed) != compressed)
{ /* If write didn't set errno, assume problem is no disk space */
f->wwmethod->lasterrno = errno ? errno : ENOSPC; return -1;
}
r = close(df->fd);
} else #endif
r = close(df->fd);
if (r == 0)
{ /* Build path to the current version of the file */ if (method == CLOSE_NORMAL && df->temp_suffix)
{ char *filename; char *filename2;
errno = 0; if (write(df->fd, df->lz4buf, compressed) != compressed)
{ /* If write didn't set errno, assume problem is no disk space */
f->wwmethod->lasterrno = errno ? errno : ENOSPC; return -1;
}
} #endif
r = fsync(((DirectoryMethodFile *) f)->fd); if (r < 0)
f->wwmethod->lasterrno = errno; return r;
}
typedefstruct TarMethodFile
{
Walfile base;
pgoff_t ofs_start; /* Where does the *header* for this file start */ char header[TAR_BLOCK_SIZE];
size_t pad_to_size;
} TarMethodFile;
r = deflate(tar_data->zp, flush ? Z_FINISH : Z_NO_FLUSH); if (r == Z_STREAM_ERROR)
{
tar_data->base.lasterrstring = _("could not compress data"); returnfalse;
}
if (tar_data->zp->avail_out < ZLIB_OUT_SIZE)
{
size_t len = ZLIB_OUT_SIZE - tar_data->zp->avail_out;
errno = 0; if (write(tar_data->fd, tar_data->zlibOut, len) != len)
{ /* If write didn't set errno, assume problem is no disk space */
tar_data->base.lasterrno = errno ? errno : ENOSPC; returnfalse;
}
if (flush)
{ /* Reset the stream for writing */ if (deflateReset(tar_data->zp) != Z_OK)
{
tar_data->base.lasterrstring = _("could not reset compression stream"); returnfalse;
}
}
/* Create a header with size set to 0 - we will fill out the size on close */ if (tarCreateHeader(tar_data->currentfile->header, tmppath, NULL, 0, S_IRUSR | S_IWUSR, 0, 0, time(NULL)) != TAR_OK)
{
pg_free(tar_data->currentfile);
pg_free(tmppath);
tar_data->currentfile = NULL;
wwmethod->lasterrstring = _("could not create tar header"); return NULL;
}
pg_free(tmppath);
#ifdef HAVE_LIBZ if (wwmethod->compression_algorithm == PG_COMPRESSION_GZIP)
{ /* Flush existing data */ if (!tar_write_compressed_data(tar_data, NULL, 0, true)) return NULL;
/* Turn off compression for header */ if (deflateParams(tar_data->zp, 0, Z_DEFAULT_STRATEGY) != Z_OK)
{
wwmethod->lasterrstring =
_("could not change compression parameters"); return NULL;
}
} #endif
if (wwmethod->compression_algorithm == PG_COMPRESSION_NONE)
{
errno = 0; if (write(tar_data->fd, tar_data->currentfile->header,
TAR_BLOCK_SIZE) != TAR_BLOCK_SIZE)
{ /* If write didn't set errno, assume problem is no disk space */
wwmethod->lasterrno = errno ? errno : ENOSPC;
pg_free(tar_data->currentfile);
tar_data->currentfile = NULL; return NULL;
}
} #ifdef HAVE_LIBZ elseif (wwmethod->compression_algorithm == PG_COMPRESSION_GZIP)
{ /* Write header through the zlib APIs but with no compression */ if (!tar_write_compressed_data(tar_data, tar_data->currentfile->header,
TAR_BLOCK_SIZE, true)) return NULL;
/* Re-enable compression for the rest of the file */ if (deflateParams(tar_data->zp, wwmethod->compression_level,
Z_DEFAULT_STRATEGY) != Z_OK)
{
wwmethod->lasterrstring = _("could not change compression parameters"); return NULL;
}
} #endif else
{ /* not reachable */
Assert(false);
}
if (method == CLOSE_UNLINK)
{ if (f->wwmethod->compression_algorithm != PG_COMPRESSION_NONE)
{
f->wwmethod->lasterrstring = _("unlink not supported with compression"); return -1;
}
print_tar_number(&(tf->header[TAR_OFFSET_CHECKSUM]), 8,
tarChecksum(((TarMethodFile *) f)->header)); if (lseek(tar_data->fd, tf->ofs_start, SEEK_SET) != ((TarMethodFile *) f)->ofs_start)
{
f->wwmethod->lasterrno = errno; return -1;
} if (f->wwmethod->compression_algorithm == PG_COMPRESSION_NONE)
{
errno = 0; if (write(tar_data->fd, tf->header, TAR_BLOCK_SIZE) != TAR_BLOCK_SIZE)
{ /* If write didn't set errno, assume problem is no disk space */
f->wwmethod->lasterrno = errno ? errno : ENOSPC; return -1;
}
} #ifdef HAVE_LIBZ elseif (f->wwmethod->compression_algorithm == PG_COMPRESSION_GZIP)
{ /* Turn off compression */ if (deflateParams(tar_data->zp, 0, Z_DEFAULT_STRATEGY) != Z_OK)
{
f->wwmethod->lasterrstring = _("could not change compression parameters"); return -1;
}
/* Overwrite the header, assuming the size will be the same */ if (!tar_write_compressed_data(tar_data, tar_data->currentfile->header,
TAR_BLOCK_SIZE, true)) return -1;
/* Turn compression back on */ if (deflateParams(tar_data->zp, f->wwmethod->compression_level,
Z_DEFAULT_STRATEGY) != Z_OK)
{
f->wwmethod->lasterrstring = _("could not change compression parameters"); return -1;
}
} #endif else
{ /* not reachable */
Assert(false);
}
/* Move file pointer back down to end, so we can write the next file */ if (lseek(tar_data->fd, 0, SEEK_END) < 0)
{
f->wwmethod->lasterrno = errno; return -1;
}
/* Always fsync on close, so the padding gets fsynced */ if (tar_sync(f) < 0)
{ /* XXX this seems pretty bogus; why is only this case fatal? */
pg_fatal("could not fsync file \"%s\": %s",
tf->base.pathname, GetLastWalMethodError(f->wwmethod));
}
/* Clean up and done */
pg_free(tf->base.pathname);
pg_free(tf);
tar_data->currentfile = NULL;
return0;
}
staticbool
tar_existsfile(WalWriteMethod *wwmethod, constchar *pathname)
{
clear_error(wwmethod); /* We only deal with new tarfiles, so nothing externally created exists */ returnfalse;
}
if (tar_data->currentfile)
{ if (tar_close(&tar_data->currentfile->base, CLOSE_NORMAL) != 0) returnfalse;
}
/* A tarfile always ends with two empty blocks */ if (wwmethod->compression_algorithm == PG_COMPRESSION_NONE)
{
errno = 0; if (write(tar_data->fd, zerobuf, sizeof(zerobuf)) != sizeof(zerobuf))
{ /* If write didn't set errno, assume problem is no disk space */
wwmethod->lasterrno = errno ? errno : ENOSPC; returnfalse;
}
} #ifdef HAVE_LIBZ elseif (wwmethod->compression_algorithm == PG_COMPRESSION_GZIP)
{ if (!tar_write_compressed_data(tar_data, zerobuf, sizeof(zerobuf), false)) returnfalse;
/* Also flush all data to make sure the gzip stream is finished */
tar_data->zp->next_in = NULL;
tar_data->zp->avail_in = 0; while (true)
{ int r;
r = deflate(tar_data->zp, Z_FINISH);
if (r == Z_STREAM_ERROR)
{
wwmethod->lasterrstring = _("could not compress data"); returnfalse;
} if (tar_data->zp->avail_out < ZLIB_OUT_SIZE)
{
size_t len = ZLIB_OUT_SIZE - tar_data->zp->avail_out;
if (deflateEnd(tar_data->zp) != Z_OK)
{
wwmethod->lasterrstring = _("could not close compression stream"); returnfalse;
}
} #endif else
{ /* not reachable */
Assert(false);
}
/* sync the empty blocks as well, since they're after the last file */ if (wwmethod->sync)
{ if (fsync(tar_data->fd) != 0)
{
wwmethod->lasterrno = errno; returnfalse;
}
}
if (close(tar_data->fd) != 0)
{
wwmethod->lasterrno = errno; returnfalse;
}
tar_data->fd = -1;
if (wwmethod->sync)
{ if (fsync_fname(tar_data->tarfilename, false) != 0 ||
fsync_parent_path(tar_data->tarfilename) != 0)
{
wwmethod->lasterrno = errno; returnfalse;
}
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.25Bemerkung:
(vorverarbeitet am 2026-08-06)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.