LCOV - code coverage report
Current view: top level - src/bin/pg_dump - compress_none.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 87.3 % 110 96
Test Date: 2026-04-07 14:16:30 Functions: 92.9 % 14 13
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * compress_none.c
       4              :  *   Routines for archivers to read or write an uncompressed stream.
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  * IDENTIFICATION
      10              :  *     src/bin/pg_dump/compress_none.c
      11              :  *
      12              :  *-------------------------------------------------------------------------
      13              :  */
      14              : #include "postgres_fe.h"
      15              : #include <unistd.h>
      16              : 
      17              : #include "compress_none.h"
      18              : #include "pg_backup_utils.h"
      19              : 
      20              : /*----------------------
      21              :  * Compressor API
      22              :  *----------------------
      23              :  */
      24              : 
      25              : /*
      26              :  * We buffer outgoing data, just to ensure that data blocks written to the
      27              :  * archive file are of reasonable size.  The read side could use this struct,
      28              :  * but there's no need because it does not retain data across calls.
      29              :  */
      30              : typedef struct NoneCompressorState
      31              : {
      32              :     char       *buffer;         /* buffer for unwritten data */
      33              :     size_t      buflen;         /* allocated size of buffer */
      34              :     size_t      bufdata;        /* amount of valid data currently in buffer */
      35              : } NoneCompressorState;
      36              : 
      37              : /*
      38              :  * Private routines
      39              :  */
      40              : 
      41              : static void
      42            3 : ReadDataFromArchiveNone(ArchiveHandle *AH, CompressorState *cs)
      43              : {
      44              :     size_t      cnt;
      45              :     char       *buf;
      46              :     size_t      buflen;
      47              : 
      48            3 :     buflen = DEFAULT_IO_BUFFER_SIZE;
      49            3 :     buf = pg_malloc(buflen);
      50              : 
      51            8 :     while ((cnt = cs->readF(AH, &buf, &buflen)))
      52              :     {
      53            5 :         ahwrite(buf, 1, cnt, AH);
      54              :     }
      55              : 
      56            3 :     free(buf);
      57            3 : }
      58              : 
      59              : 
      60              : static void
      61            4 : WriteDataToArchiveNone(ArchiveHandle *AH, CompressorState *cs,
      62              :                        const void *data, size_t dLen)
      63              : {
      64            4 :     NoneCompressorState *nonecs = (NoneCompressorState *) cs->private_data;
      65            4 :     size_t      remaining = dLen;
      66              : 
      67           10 :     while (remaining > 0)
      68              :     {
      69              :         size_t      chunk;
      70              : 
      71              :         /* Dump buffer if full */
      72            6 :         if (nonecs->bufdata >= nonecs->buflen)
      73              :         {
      74            2 :             cs->writeF(AH, nonecs->buffer, nonecs->bufdata);
      75            2 :             nonecs->bufdata = 0;
      76              :         }
      77              :         /* And fill it */
      78            6 :         chunk = nonecs->buflen - nonecs->bufdata;
      79            6 :         if (chunk > remaining)
      80            4 :             chunk = remaining;
      81            6 :         memcpy(nonecs->buffer + nonecs->bufdata, data, chunk);
      82            6 :         nonecs->bufdata += chunk;
      83            6 :         data = ((const char *) data) + chunk;
      84            6 :         remaining -= chunk;
      85              :     }
      86            4 : }
      87              : 
      88              : static void
      89            6 : EndCompressorNone(ArchiveHandle *AH, CompressorState *cs)
      90              : {
      91            6 :     NoneCompressorState *nonecs = (NoneCompressorState *) cs->private_data;
      92              : 
      93            6 :     if (nonecs)
      94              :     {
      95              :         /* Dump buffer if nonempty */
      96            3 :         if (nonecs->bufdata > 0)
      97            3 :             cs->writeF(AH, nonecs->buffer, nonecs->bufdata);
      98              :         /* Free working state */
      99            3 :         pg_free(nonecs->buffer);
     100            3 :         pg_free(nonecs);
     101            3 :         cs->private_data = NULL;
     102              :     }
     103            6 : }
     104              : 
     105              : /*
     106              :  * Public interface
     107              :  */
     108              : 
     109              : void
     110            6 : InitCompressorNone(CompressorState *cs,
     111              :                    const pg_compress_specification compression_spec)
     112              : {
     113            6 :     cs->readData = ReadDataFromArchiveNone;
     114            6 :     cs->writeData = WriteDataToArchiveNone;
     115            6 :     cs->end = EndCompressorNone;
     116              : 
     117            6 :     cs->compression_spec = compression_spec;
     118              : 
     119              :     /*
     120              :      * If the caller has defined a write function, prepare the necessary
     121              :      * buffer.
     122              :      */
     123            6 :     if (cs->writeF)
     124              :     {
     125              :         NoneCompressorState *nonecs;
     126              : 
     127            3 :         nonecs = pg_malloc_object(NoneCompressorState);
     128            3 :         nonecs->buflen = DEFAULT_IO_BUFFER_SIZE;
     129            3 :         nonecs->buffer = pg_malloc(nonecs->buflen);
     130            3 :         nonecs->bufdata = 0;
     131              : 
     132            3 :         cs->private_data = nonecs;
     133              :     }
     134            6 : }
     135              : 
     136              : 
     137              : /*----------------------
     138              :  * Compress File API
     139              :  *----------------------
     140              :  */
     141              : 
     142              : /*
     143              :  * Private routines
     144              :  */
     145              : 
     146              : static size_t
     147        20295 : read_none(void *ptr, size_t size, CompressFileHandle *CFH)
     148              : {
     149        20295 :     FILE       *fp = (FILE *) CFH->private_data;
     150              :     size_t      ret;
     151              : 
     152        20295 :     ret = fread(ptr, 1, size, fp);
     153        20295 :     if (ferror(fp))
     154            0 :         pg_fatal("could not read from input file: %m");
     155              : 
     156        20295 :     return ret;
     157              : }
     158              : 
     159              : static void
     160      2213202 : write_none(const void *ptr, size_t size, CompressFileHandle *CFH)
     161              : {
     162              :     size_t      ret;
     163              : 
     164      2213202 :     errno = 0;
     165      2213202 :     ret = fwrite(ptr, 1, size, (FILE *) CFH->private_data);
     166      2213202 :     if (ret != size)
     167              :     {
     168            0 :         errno = (errno) ? errno : ENOSPC;
     169            0 :         pg_fatal("could not write to file: %m");
     170              :     }
     171      2213202 : }
     172              : 
     173              : static const char *
     174            0 : get_error_none(CompressFileHandle *CFH)
     175              : {
     176            0 :     return strerror(errno);
     177              : }
     178              : 
     179              : static char *
     180            8 : gets_none(char *ptr, int size, CompressFileHandle *CFH)
     181              : {
     182            8 :     return fgets(ptr, size, (FILE *) CFH->private_data);
     183              : }
     184              : 
     185              : static int
     186       186721 : getc_none(CompressFileHandle *CFH)
     187              : {
     188       186721 :     FILE       *fp = (FILE *) CFH->private_data;
     189              :     int         ret;
     190              : 
     191       186721 :     ret = fgetc(fp);
     192       186721 :     if (ret == EOF)
     193              :     {
     194            0 :         if (!feof(fp))
     195            0 :             pg_fatal("could not read from input file: %m");
     196              :         else
     197            0 :             pg_fatal("could not read from input file: end of file");
     198              :     }
     199              : 
     200       186721 :     return ret;
     201              : }
     202              : 
     203              : static bool
     204          788 : close_none(CompressFileHandle *CFH)
     205              : {
     206          788 :     FILE       *fp = (FILE *) CFH->private_data;
     207          788 :     int         ret = 0;
     208              : 
     209          788 :     CFH->private_data = NULL;
     210              : 
     211          788 :     if (fp)
     212              :     {
     213          788 :         errno = 0;
     214          788 :         ret = fclose(fp);
     215          788 :         if (ret != 0)
     216            0 :             pg_log_error("could not close file: %m");
     217              :     }
     218              : 
     219          788 :     return ret == 0;
     220              : }
     221              : 
     222              : static bool
     223            4 : eof_none(CompressFileHandle *CFH)
     224              : {
     225            4 :     return feof((FILE *) CFH->private_data) != 0;
     226              : }
     227              : 
     228              : static bool
     229          739 : open_none(const char *path, int fd, const char *mode, CompressFileHandle *CFH)
     230              : {
     231              :     Assert(CFH->private_data == NULL);
     232              : 
     233          739 :     if (fd >= 0)
     234              :     {
     235          439 :         int         dup_fd = dup(fd);
     236              : 
     237          439 :         if (dup_fd < 0)
     238            0 :             return false;
     239          439 :         CFH->private_data = fdopen(dup_fd, mode);
     240          439 :         if (CFH->private_data == NULL)
     241              :         {
     242            0 :             close(dup_fd);
     243            0 :             return false;
     244              :         }
     245              :     }
     246              :     else
     247              :     {
     248          300 :         CFH->private_data = fopen(path, mode);
     249          300 :         if (CFH->private_data == NULL)
     250            0 :             return false;
     251              :     }
     252              : 
     253          739 :     return true;
     254              : }
     255              : 
     256              : static bool
     257           71 : open_write_none(const char *path, const char *mode, CompressFileHandle *CFH)
     258              : {
     259              :     Assert(CFH->private_data == NULL);
     260              : 
     261           71 :     CFH->private_data = fopen(path, mode);
     262           71 :     if (CFH->private_data == NULL)
     263            0 :         return false;
     264              : 
     265           71 :     return true;
     266              : }
     267              : 
     268              : /*
     269              :  * Public interface
     270              :  */
     271              : 
     272              : void
     273          810 : InitCompressFileHandleNone(CompressFileHandle *CFH,
     274              :                            const pg_compress_specification compression_spec)
     275              : {
     276          810 :     CFH->open_func = open_none;
     277          810 :     CFH->open_write_func = open_write_none;
     278          810 :     CFH->read_func = read_none;
     279          810 :     CFH->write_func = write_none;
     280          810 :     CFH->gets_func = gets_none;
     281          810 :     CFH->getc_func = getc_none;
     282          810 :     CFH->close_func = close_none;
     283          810 :     CFH->eof_func = eof_none;
     284          810 :     CFH->get_error_func = get_error_none;
     285              : 
     286          810 :     CFH->private_data = NULL;
     287          810 : }
        

Generated by: LCOV version 2.0-1