Header And Logo

PostgreSQL
| The world's most advanced open source database.

Data Structures | Functions | Variables

pg_backup_custom.c File Reference

#include "compress_io.h"
#include "parallel.h"
#include "pg_backup_utils.h"
Include dependency graph for pg_backup_custom.c:

Go to the source code of this file.

Data Structures

struct  lclContext
struct  lclTocEntry

Functions

static void _ArchiveEntry (ArchiveHandle *AH, TocEntry *te)
static void _StartData (ArchiveHandle *AH, TocEntry *te)
static size_t _WriteData (ArchiveHandle *AH, const void *data, size_t dLen)
static void _EndData (ArchiveHandle *AH, TocEntry *te)
static int _WriteByte (ArchiveHandle *AH, const int i)
static int _ReadByte (ArchiveHandle *)
static size_t _WriteBuf (ArchiveHandle *AH, const void *buf, size_t len)
static size_t _ReadBuf (ArchiveHandle *AH, void *buf, size_t len)
static void _CloseArchive (ArchiveHandle *AH)
static void _ReopenArchive (ArchiveHandle *AH)
static void _PrintTocData (ArchiveHandle *AH, TocEntry *te, RestoreOptions *ropt)
static void _WriteExtraToc (ArchiveHandle *AH, TocEntry *te)
static void _ReadExtraToc (ArchiveHandle *AH, TocEntry *te)
static void _PrintExtraToc (ArchiveHandle *AH, TocEntry *te)
static void _PrintData (ArchiveHandle *AH)
static void _skipData (ArchiveHandle *AH)
static void _skipBlobs (ArchiveHandle *AH)
static void _StartBlobs (ArchiveHandle *AH, TocEntry *te)
static void _StartBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
static void _EndBlob (ArchiveHandle *AH, TocEntry *te, Oid oid)
static void _EndBlobs (ArchiveHandle *AH, TocEntry *te)
static void _LoadBlobs (ArchiveHandle *AH, bool drop)
static void _Clone (ArchiveHandle *AH)
static void _DeClone (ArchiveHandle *AH)
static char * _MasterStartParallelItem (ArchiveHandle *AH, TocEntry *te, T_Action act)
static int _MasterEndParallelItem (ArchiveHandle *AH, TocEntry *te, const char *str, T_Action act)
char * _WorkerJobRestoreCustom (ArchiveHandle *AH, TocEntry *te)
static void _readBlockHeader (ArchiveHandle *AH, int *type, int *id)
static pgoff_t _getFilePos (ArchiveHandle *AH, lclContext *ctx)
static size_t _CustomWriteFunc (ArchiveHandle *AH, const char *buf, size_t len)
static size_t _CustomReadFunc (ArchiveHandle *AH, char **buf, size_t *buflen)
void InitArchiveFmt_Custom (ArchiveHandle *AH)

Variables

static const char * modulename = gettext_noop("custom archiver")

Function Documentation

static void _ArchiveEntry ( ArchiveHandle AH,
TocEntry te 
) [static]

Definition at line 208 of file pg_backup_custom.c.

References _tocEntry::dataDumper, lclTocEntry::dataState, _tocEntry::formatData, and pg_malloc0().

{
    lclTocEntry *ctx;

    ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
    if (te->dataDumper)
        ctx->dataState = K_OFFSET_POS_NOT_SET;
    else
        ctx->dataState = K_OFFSET_NO_DATA;

    te->formatData = (void *) ctx;
}

static void _Clone ( ArchiveHandle AH  )  [static]

Definition at line 783 of file pg_backup_custom.c.

References lclContext::cs, exit_horribly(), _archiveHandle::formatData, modulename, NULL, and pg_malloc().

{
    lclContext *ctx = (lclContext *) AH->formatData;

    AH->formatData = (lclContext *) pg_malloc(sizeof(lclContext));
    memcpy(AH->formatData, ctx, sizeof(lclContext));
    ctx = (lclContext *) AH->formatData;

    /* sanity check, shouldn't happen */
    if (ctx->cs != NULL)
        exit_horribly(modulename, "compressor active\n");

    /*
     * Note: we do not make a local lo_buf because we expect at most one BLOBS
     * entry per archive, so no parallelism is possible.  Likewise,
     * TOC-entry-local state isn't an issue because any one TOC entry is
     * touched by just one worker child.
     */
}

static void _CloseArchive ( ArchiveHandle AH  )  [static]

Definition at line 702 of file pg_backup_custom.c.

References _getFilePos(), archModeWrite, lclContext::dataStart, exit_horribly(), _archiveHandle::FH, _archiveHandle::formatData, fseeko, ftello, lclContext::hasSeek, _archiveHandle::mode, modulename, NULL, pgoff_t, strerror(), WriteDataChunks(), WriteHead(), and WriteToc().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    pgoff_t     tpos;

    if (AH->mode == archModeWrite)
    {
        WriteHead(AH);
        tpos = ftello(AH->FH);
        WriteToc(AH);
        ctx->dataStart = _getFilePos(AH, ctx);
        WriteDataChunks(AH, NULL);

        /*
         * If possible, re-write the TOC in order to update the data offset
         * information.  This is not essential, as pg_restore can cope in most
         * cases without it; but it can make pg_restore significantly faster
         * in some situations (especially parallel restore).
         */
        if (ctx->hasSeek &&
            fseeko(AH->FH, tpos, SEEK_SET) == 0)
            WriteToc(AH);
    }

    if (fclose(AH->FH) != 0)
        exit_horribly(modulename, "could not close archive file: %s\n", strerror(errno));

    AH->FH = NULL;
}

static size_t _CustomReadFunc ( ArchiveHandle AH,
char **  buf,
size_t *  buflen 
) [static]

Definition at line 972 of file pg_backup_custom.c.

References _ReadBuf(), exit_horribly(), _archiveHandle::FH, free, modulename, pg_malloc(), ReadInt(), and strerror().

Referenced by _PrintData().

{
    size_t      blkLen;
    size_t      cnt;

    /* Read length */
    blkLen = ReadInt(AH);
    if (blkLen == 0)
        return 0;

    /* If the caller's buffer is not large enough, allocate a bigger one */
    if (blkLen > *buflen)
    {
        free(*buf);
        *buf = (char *) pg_malloc(blkLen);
        *buflen = blkLen;
    }

    cnt = _ReadBuf(AH, *buf, blkLen);
    if (cnt != blkLen)
    {
        if (feof(AH->FH))
            exit_horribly(modulename,
                          "could not read from input file: end of file\n");
        else
            exit_horribly(modulename,
                    "could not read from input file: %s\n", strerror(errno));
    }
    return cnt;
}

static size_t _CustomWriteFunc ( ArchiveHandle AH,
const char *  buf,
size_t  len 
) [static]

Definition at line 957 of file pg_backup_custom.c.

References _WriteBuf(), and WriteInt().

Referenced by _StartBlob(), and _StartData().

{
    /* never write 0-byte blocks (this should not happen) */
    if (len == 0)
        return 0;

    WriteInt(AH, len);
    return _WriteBuf(AH, buf, len);
}

static void _DeClone ( ArchiveHandle AH  )  [static]

Definition at line 804 of file pg_backup_custom.c.

References _archiveHandle::formatData, and free.

{
    lclContext *ctx = (lclContext *) AH->formatData;

    free(ctx);
}

static void _EndBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
) [static]

Definition at line 395 of file pg_backup_custom.c.

References lclContext::cs, EndCompressor(), _archiveHandle::formatData, and WriteInt().

{
    lclContext *ctx = (lclContext *) AH->formatData;

    EndCompressor(AH, ctx->cs);
    /* Send the end marker */
    WriteInt(AH, 0);
}

static void _EndBlobs ( ArchiveHandle AH,
TocEntry te 
) [static]

Definition at line 410 of file pg_backup_custom.c.

References WriteInt().

{
    /* Write out a fake zero OID to mark end-of-blobs. */
    WriteInt(AH, 0);
}

static void _EndData ( ArchiveHandle AH,
TocEntry te 
) [static]

Definition at line 338 of file pg_backup_custom.c.

References lclContext::cs, EndCompressor(), _archiveHandle::formatData, and WriteInt().

{
    lclContext *ctx = (lclContext *) AH->formatData;

    EndCompressor(AH, ctx->cs);
    /* Send the end marker */
    WriteInt(AH, 0);
}

static pgoff_t _getFilePos ( ArchiveHandle AH,
lclContext ctx 
) [static]

Definition at line 894 of file pg_backup_custom.c.

References _archiveHandle::FH, lclContext::filePos, ftello, lclContext::hasSeek, modulename, pgoff_t, and write_msg().

Referenced by _CloseArchive(), _StartBlobs(), _StartData(), and InitArchiveFmt_Custom().

{
    pgoff_t     pos;

    if (ctx->hasSeek)
    {
        pos = ftello(AH->FH);
        if (pos != ctx->filePos)
        {
            write_msg(modulename, "WARNING: ftell mismatch with expected position -- ftell used\n");

            /*
             * Prior to 1.7 (pg7.3) we relied on the internally maintained
             * pointer. Now we rely on ftello() always, unless the file has
             * been found to not support it.
             */
        }
    }
    else
        pos = ctx->filePos;
    return pos;
}

static void _LoadBlobs ( ArchiveHandle AH,
bool  drop 
) [static]

Definition at line 521 of file pg_backup_custom.c.

References _PrintData(), EndRestoreBlob(), EndRestoreBlobs(), ReadInt(), StartRestoreBlob(), and StartRestoreBlobs().

Referenced by _PrintTocData().

{
    Oid         oid;

    StartRestoreBlobs(AH);

    oid = ReadInt(AH);
    while (oid != 0)
    {
        StartRestoreBlob(AH, oid, drop);
        _PrintData(AH);
        EndRestoreBlob(AH, oid);
        oid = ReadInt(AH);
    }

    EndRestoreBlobs(AH);
}

static int _MasterEndParallelItem ( ArchiveHandle AH,
TocEntry te,
const char *  str,
T_Action  act 
) [static]

Definition at line 865 of file pg_backup_custom.c.

References ACT_RESTORE, Assert, _tocEntry::dumpId, Archive::n_errors, and _archiveHandle::public.

{
    DumpId      dumpId;
    int         nBytes,
                status,
                n_errors;

    /* no parallel dump in the custom archive */
    Assert(act == ACT_RESTORE);

    sscanf(str, "%u %u %u%n", &dumpId, &status, &n_errors, &nBytes);

    Assert(nBytes == strlen(str));
    Assert(dumpId == te->dumpId);

    AH->public.n_errors += n_errors;

    return status;
}

static char * _MasterStartParallelItem ( ArchiveHandle AH,
TocEntry te,
T_Action  act 
) [static]

Definition at line 844 of file pg_backup_custom.c.

References ACT_RESTORE, Assert, buf, _tocEntry::dumpId, and snprintf().

{
    /*
     * A static char is okay here, even on Windows because we call this
     * function only from one process (the master).
     */
    static char buf[64];        /* short fixed-size string + number */

    /* no parallel dump in the custom archive format */
    Assert(act == ACT_RESTORE);

    snprintf(buf, sizeof(buf), "RESTORE %d", te->dumpId);

    return buf;
}

static void _PrintData ( ArchiveHandle AH  )  [static]
static void _PrintExtraToc ( ArchiveHandle AH,
TocEntry te 
) [static]

Definition at line 275 of file pg_backup_custom.c.

References ahprintf(), lclTocEntry::dataPos, _tocEntry::formatData, _archiveHandle::public, and Archive::verbose.

{
    lclTocEntry *ctx = (lclTocEntry *) te->formatData;

    if (AH->public.verbose)
        ahprintf(AH, "-- Data Pos: " INT64_FORMAT "\n",
                 (int64) ctx->dataPos);
}

static void _PrintTocData ( ArchiveHandle AH,
TocEntry te,
RestoreOptions ropt 
) [static]

Definition at line 420 of file pg_backup_custom.c.

References _LoadBlobs(), _PrintData(), _readBlockHeader(), _skipBlobs(), _skipData(), BLK_BLOBS, BLK_DATA, _restoreOptions::dropSchema, _tocEntry::dumpId, exit_horribly(), _archiveHandle::FH, _tocEntry::formatData, _archiveHandle::formatData, fseeko, lclContext::hasSeek, K_OFFSET_NO_DATA, K_OFFSET_POS_NOT_SET, modulename, and strerror().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    lclTocEntry *tctx = (lclTocEntry *) te->formatData;
    int         blkType;
    int         id;

    if (tctx->dataState == K_OFFSET_NO_DATA)
        return;

    if (!ctx->hasSeek || tctx->dataState == K_OFFSET_POS_NOT_SET)
    {
        /*
         * We cannot seek directly to the desired block.  Instead, skip over
         * block headers until we find the one we want.  This could fail if we
         * are asked to restore items out-of-order.
         */
        _readBlockHeader(AH, &blkType, &id);

        while (blkType != EOF && id != te->dumpId)
        {
            switch (blkType)
            {
                case BLK_DATA:
                    _skipData(AH);
                    break;

                case BLK_BLOBS:
                    _skipBlobs(AH);
                    break;

                default:        /* Always have a default */
                    exit_horribly(modulename,
                                  "unrecognized data block type (%d) while searching archive\n",
                                  blkType);
                    break;
            }
            _readBlockHeader(AH, &blkType, &id);
        }
    }
    else
    {
        /* We can just seek to the place we need to be. */
        if (fseeko(AH->FH, tctx->dataPos, SEEK_SET) != 0)
            exit_horribly(modulename, "error during file seek: %s\n",
                          strerror(errno));

        _readBlockHeader(AH, &blkType, &id);
    }

    /* Produce suitable failure message if we fell off end of file */
    if (blkType == EOF)
    {
        if (tctx->dataState == K_OFFSET_POS_NOT_SET)
            exit_horribly(modulename, "could not find block ID %d in archive -- "
                          "possibly due to out-of-order restore request, "
                          "which cannot be handled due to lack of data offsets in archive\n",
                          te->dumpId);
        else if (!ctx->hasSeek)
            exit_horribly(modulename, "could not find block ID %d in archive -- "
                          "possibly due to out-of-order restore request, "
                  "which cannot be handled due to non-seekable input file\n",
                          te->dumpId);
        else    /* huh, the dataPos led us to EOF? */
            exit_horribly(modulename, "could not find block ID %d in archive -- "
                          "possibly corrupt archive\n",
                          te->dumpId);
    }

    /* Are we sane? */
    if (id != te->dumpId)
        exit_horribly(modulename, "found unexpected block ID (%d) when reading data -- expected %d\n",
                      id, te->dumpId);

    switch (blkType)
    {
        case BLK_DATA:
            _PrintData(AH);
            break;

        case BLK_BLOBS:
            _LoadBlobs(AH, ropt->dropSchema);
            break;

        default:                /* Always have a default */
            exit_horribly(modulename, "unrecognized data block type %d while restoring archive\n",
                          blkType);
            break;
    }
}

static void _readBlockHeader ( ArchiveHandle AH,
int *  type,
int *  id 
) [static]

Definition at line 923 of file pg_backup_custom.c.

References _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, K_VERS_1_3, ReadInt(), and _archiveHandle::version.

Referenced by _PrintTocData().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    int         byt;

    /*
     * Note: if we are at EOF with a pre-1.3 input file, we'll exit_horribly
     * inside ReadInt rather than returning EOF.  It doesn't seem worth
     * jumping through hoops to deal with that case better, because no such
     * files are likely to exist in the wild: only some 7.1 development
     * versions of pg_dump ever generated such files.
     */
    if (AH->version < K_VERS_1_3)
        *type = BLK_DATA;
    else
    {
        byt = getc(AH->FH);
        *type = byt;
        if (byt == EOF)
        {
            *id = 0;            /* don't return an uninitialized value */
            return;
        }
        ctx->filePos += 1;
    }

    *id = ReadInt(AH);
}

static size_t _ReadBuf ( ArchiveHandle AH,
void *  buf,
size_t  len 
) [static]

Definition at line 675 of file pg_backup_custom.c.

References _archiveHandle::FH, lclContext::filePos, and _archiveHandle::formatData.

Referenced by _CustomReadFunc().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    size_t      res;

    res = fread(buf, 1, len, AH->FH);
    ctx->filePos += res;

    return res;
}

static int _ReadByte ( ArchiveHandle AH  )  [static]

Definition at line 632 of file pg_backup_custom.c.

References exit_horribly(), _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, and modulename.

{
    lclContext *ctx = (lclContext *) AH->formatData;
    int         res;

    res = getc(AH->FH);
    if (res == EOF)
        exit_horribly(modulename, "unexpected end of file\n");
    ctx->filePos += 1;
    return res;
}

static void _ReadExtraToc ( ArchiveHandle AH,
TocEntry te 
) [static]

Definition at line 247 of file pg_backup_custom.c.

References lclTocEntry::dataPos, lclTocEntry::dataState, _tocEntry::formatData, K_VERS_1_7, NULL, pg_malloc0(), ReadInt(), ReadOffset(), and _archiveHandle::version.

{
    lclTocEntry *ctx = (lclTocEntry *) te->formatData;

    if (ctx == NULL)
    {
        ctx = (lclTocEntry *) pg_malloc0(sizeof(lclTocEntry));
        te->formatData = (void *) ctx;
    }

    ctx->dataState = ReadOffset(AH, &(ctx->dataPos));

    /*
     * Prior to V1.7 (pg7.3), we dumped the data size as an int now we don't
     * dump it at all.
     */
    if (AH->version < K_VERS_1_7)
        ReadInt(AH);
}

static void _ReopenArchive ( ArchiveHandle AH  )  [static]

Definition at line 740 of file pg_backup_custom.c.

References archModeWrite, exit_horribly(), _archiveHandle::FH, _archiveHandle::formatData, fseeko, _archiveHandle::fSpec, ftello, lclContext::hasSeek, _archiveHandle::mode, modulename, NULL, PG_BINARY_R, pgoff_t, and strerror().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    pgoff_t     tpos;

    if (AH->mode == archModeWrite)
        exit_horribly(modulename, "can only reopen input archives\n");

    /*
     * These two cases are user-facing errors since they represent unsupported
     * (but not invalid) use-cases.  Word the error messages appropriately.
     */
    if (AH->fSpec == NULL || strcmp(AH->fSpec, "") == 0)
        exit_horribly(modulename, "parallel restore from standard input is not supported\n");
    if (!ctx->hasSeek)
        exit_horribly(modulename, "parallel restore from non-seekable file is not supported\n");

    errno = 0;
    tpos = ftello(AH->FH);
    if (errno)
        exit_horribly(modulename, "could not determine seek position in archive file: %s\n",
                      strerror(errno));

#ifndef WIN32
    if (fclose(AH->FH) != 0)
        exit_horribly(modulename, "could not close archive file: %s\n",
                      strerror(errno));
#endif

    AH->FH = fopen(AH->fSpec, PG_BINARY_R);
    if (!AH->FH)
        exit_horribly(modulename, "could not open input file \"%s\": %s\n",
                      AH->fSpec, strerror(errno));

    if (fseeko(AH->FH, tpos, SEEK_SET) != 0)
        exit_horribly(modulename, "could not set seek position in archive file: %s\n",
                      strerror(errno));
}

static void _skipBlobs ( ArchiveHandle AH  )  [static]

Definition at line 546 of file pg_backup_custom.c.

References _skipData(), and ReadInt().

Referenced by _PrintTocData().

{
    Oid         oid;

    oid = ReadInt(AH);
    while (oid != 0)
    {
        _skipData(AH);
        oid = ReadInt(AH);
    }
}

static void _skipData ( ArchiveHandle AH  )  [static]

Definition at line 564 of file pg_backup_custom.c.

References buf, exit_horribly(), _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, free, modulename, NULL, pg_malloc(), ReadInt(), and strerror().

Referenced by _PrintTocData(), and _skipBlobs().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    size_t      blkLen;
    char       *buf = NULL;
    int         buflen = 0;
    size_t      cnt;

    blkLen = ReadInt(AH);
    while (blkLen != 0)
    {
        if (blkLen > buflen)
        {
            if (buf)
                free(buf);
            buf = (char *) pg_malloc(blkLen);
            buflen = blkLen;
        }
        cnt = fread(buf, 1, blkLen, AH->FH);
        if (cnt != blkLen)
        {
            if (feof(AH->FH))
                exit_horribly(modulename,
                            "could not read from input file: end of file\n");
            else
                exit_horribly(modulename,
                    "could not read from input file: %s\n", strerror(errno));
        }

        ctx->filePos += blkLen;

        blkLen = ReadInt(AH);
    }

    if (buf)
        free(buf);
}

static void _StartBlob ( ArchiveHandle AH,
TocEntry te,
Oid  oid 
) [static]
static void _StartBlobs ( ArchiveHandle AH,
TocEntry te 
) [static]

Definition at line 357 of file pg_backup_custom.c.

References _getFilePos(), _WriteByte(), BLK_BLOBS, _tocEntry::dumpId, _tocEntry::formatData, _archiveHandle::formatData, and WriteInt().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    lclTocEntry *tctx = (lclTocEntry *) te->formatData;

    tctx->dataPos = _getFilePos(AH, ctx);
    tctx->dataState = K_OFFSET_POS_SET;

    _WriteByte(AH, BLK_BLOBS);  /* Block type */
    WriteInt(AH, te->dumpId);   /* For sanity check */
}

static void _StartData ( ArchiveHandle AH,
TocEntry te 
) [static]

Definition at line 295 of file pg_backup_custom.c.

References _CustomWriteFunc(), _getFilePos(), _WriteByte(), AllocateCompressor(), BLK_DATA, _archiveHandle::compression, lclContext::cs, _tocEntry::dumpId, _tocEntry::formatData, _archiveHandle::formatData, and WriteInt().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    lclTocEntry *tctx = (lclTocEntry *) te->formatData;

    tctx->dataPos = _getFilePos(AH, ctx);
    tctx->dataState = K_OFFSET_POS_SET;

    _WriteByte(AH, BLK_DATA);   /* Block type */
    WriteInt(AH, te->dumpId);   /* For sanity check */

    ctx->cs = AllocateCompressor(AH->compression, _CustomWriteFunc);
}

char * _WorkerJobRestoreCustom ( ArchiveHandle AH,
TocEntry te 
)

Definition at line 816 of file pg_backup_custom.c.

References ParallelArgs::AH, buf, _tocEntry::dumpId, Archive::n_errors, parallel_restore(), pg_malloc(), _archiveHandle::public, snprintf(), ParallelArgs::te, and WORKER_IGNORED_ERRORS.

{
    /*
     * short fixed-size string + some ID so far, this needs to be malloc'ed
     * instead of static because we work with threads on windows
     */
    const int   buflen = 64;
    char       *buf = (char *) pg_malloc(buflen);
    ParallelArgs pargs;
    int         status;

    pargs.AH = AH;
    pargs.te = te;

    status = parallel_restore(&pargs);

    snprintf(buf, buflen, "OK RESTORE %d %d %d", te->dumpId, status,
             status == WORKER_IGNORED_ERRORS ? AH->public.n_errors : 0);

    return buf;
}

static size_t _WriteBuf ( ArchiveHandle AH,
const void *  buf,
size_t  len 
) [static]

Definition at line 652 of file pg_backup_custom.c.

References exit_horribly(), _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, modulename, and strerror().

Referenced by _CustomWriteFunc().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    size_t      res;

    res = fwrite(buf, 1, len, AH->FH);

    if (res != len)
        exit_horribly(modulename,
                    "could not write to output file: %s\n", strerror(errno));

    ctx->filePos += res;
    return res;
}

static int _WriteByte ( ArchiveHandle AH,
const int  i 
) [static]

Definition at line 610 of file pg_backup_custom.c.

References exit_horribly(), _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, modulename, and strerror().

Referenced by _StartBlobs(), and _StartData().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    int         res;

    res = fputc(i, AH->FH);
    if (res != EOF)
        ctx->filePos += 1;
    else
        exit_horribly(modulename, "could not write byte: %s\n", strerror(errno));
    return res;
}

static size_t _WriteData ( ArchiveHandle AH,
const void *  data,
size_t  dLen 
) [static]

Definition at line 319 of file pg_backup_custom.c.

References lclContext::cs, _archiveHandle::formatData, and WriteDataToArchive().

{
    lclContext *ctx = (lclContext *) AH->formatData;
    CompressorState *cs = ctx->cs;

    if (dLen == 0)
        return 0;

    return WriteDataToArchive(AH, cs, data, dLen);
}

static void _WriteExtraToc ( ArchiveHandle AH,
TocEntry te 
) [static]
void InitArchiveFmt_Custom ( ArchiveHandle AH  ) 

Definition at line 108 of file pg_backup_custom.c.

References _getFilePos(), _archiveHandle::ArchiveEntryPtr, archModeWrite, checkSeek(), _archiveHandle::ClonePtr, _archiveHandle::ClosePtr, lclContext::dataStart, _archiveHandle::DeClonePtr, _archiveHandle::EndBlobPtr, _archiveHandle::EndBlobsPtr, _archiveHandle::EndDataPtr, exit_horribly(), _archiveHandle::FH, lclContext::filePos, _archiveHandle::formatData, _archiveHandle::fSpec, lclContext::hasSeek, _archiveHandle::lo_buf, _archiveHandle::lo_buf_size, LOBBUFSIZE, _archiveHandle::MasterEndParallelItemPtr, _archiveHandle::MasterStartParallelItemPtr, _archiveHandle::mode, modulename, PG_BINARY_R, PG_BINARY_W, pg_malloc(), pg_malloc0(), _archiveHandle::PrintExtraTocPtr, _archiveHandle::PrintTocDataPtr, _archiveHandle::ReadBufPtr, _archiveHandle::ReadBytePtr, _archiveHandle::ReadExtraTocPtr, ReadHead(), ReadToc(), _archiveHandle::ReopenPtr, _archiveHandle::StartBlobPtr, _archiveHandle::StartBlobsPtr, _archiveHandle::StartDataPtr, strerror(), _archiveHandle::WorkerJobDumpPtr, _archiveHandle::WorkerJobRestorePtr, _archiveHandle::WriteBufPtr, _archiveHandle::WriteBytePtr, _archiveHandle::WriteDataPtr, and _archiveHandle::WriteExtraTocPtr.

Referenced by _allocAH().

{
    lclContext *ctx;

    /* Assuming static functions, this can be copied for each format. */
    AH->ArchiveEntryPtr = _ArchiveEntry;
    AH->StartDataPtr = _StartData;
    AH->WriteDataPtr = _WriteData;
    AH->EndDataPtr = _EndData;
    AH->WriteBytePtr = _WriteByte;
    AH->ReadBytePtr = _ReadByte;
    AH->WriteBufPtr = _WriteBuf;
    AH->ReadBufPtr = _ReadBuf;
    AH->ClosePtr = _CloseArchive;
    AH->ReopenPtr = _ReopenArchive;
    AH->PrintTocDataPtr = _PrintTocData;
    AH->ReadExtraTocPtr = _ReadExtraToc;
    AH->WriteExtraTocPtr = _WriteExtraToc;
    AH->PrintExtraTocPtr = _PrintExtraToc;

    AH->StartBlobsPtr = _StartBlobs;
    AH->StartBlobPtr = _StartBlob;
    AH->EndBlobPtr = _EndBlob;
    AH->EndBlobsPtr = _EndBlobs;
    AH->ClonePtr = _Clone;
    AH->DeClonePtr = _DeClone;

    AH->MasterStartParallelItemPtr = _MasterStartParallelItem;
    AH->MasterEndParallelItemPtr = _MasterEndParallelItem;

    /* no parallel dump in the custom archive, only parallel restore */
    AH->WorkerJobDumpPtr = NULL;
    AH->WorkerJobRestorePtr = _WorkerJobRestoreCustom;

    /* Set up a private area. */
    ctx = (lclContext *) pg_malloc0(sizeof(lclContext));
    AH->formatData = (void *) ctx;

    /* Initialize LO buffering */
    AH->lo_buf_size = LOBBUFSIZE;
    AH->lo_buf = (void *) pg_malloc(LOBBUFSIZE);

    ctx->filePos = 0;

    /*
     * Now open the file
     */
    if (AH->mode == archModeWrite)
    {
        if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
        {
            AH->FH = fopen(AH->fSpec, PG_BINARY_W);
            if (!AH->FH)
                exit_horribly(modulename, "could not open output file \"%s\": %s\n",
                              AH->fSpec, strerror(errno));
        }
        else
        {
            AH->FH = stdout;
            if (!AH->FH)
                exit_horribly(modulename, "could not open output file: %s\n",
                              strerror(errno));
        }

        ctx->hasSeek = checkSeek(AH->FH);
    }
    else
    {
        if (AH->fSpec && strcmp(AH->fSpec, "") != 0)
        {
            AH->FH = fopen(AH->fSpec, PG_BINARY_R);
            if (!AH->FH)
                exit_horribly(modulename, "could not open input file \"%s\": %s\n",
                              AH->fSpec, strerror(errno));
        }
        else
        {
            AH->FH = stdin;
            if (!AH->FH)
                exit_horribly(modulename, "could not open input file: %s\n",
                              strerror(errno));
        }

        ctx->hasSeek = checkSeek(AH->FH);

        ReadHead(AH);
        ReadToc(AH);
        ctx->dataStart = _getFilePos(AH, ctx);
    }

}


Variable Documentation

const char* modulename = gettext_noop("custom archiver") [static]