LCOV - code coverage report
Current view: top level - src/bin/pg_dump - compress_none.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 89.4 % 104 93
Test Date: 2026-03-03 18:14:56 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        19272 : read_none(void *ptr, size_t size, CompressFileHandle *CFH)
     148              : {
     149        19272 :     FILE       *fp = (FILE *) CFH->private_data;
     150              :     size_t      ret;
     151              : 
     152        19272 :     ret = fread(ptr, 1, size, fp);
     153        19272 :     if (ferror(fp))
     154            0 :         pg_fatal("could not read from input file: %m");
     155              : 
     156        19272 :     return ret;
     157              : }
     158              : 
     159              : static void
     160      2186623 : write_none(const void *ptr, size_t size, CompressFileHandle *CFH)
     161              : {
     162              :     size_t      ret;
     163              : 
     164      2186623 :     errno = 0;
     165      2186623 :     ret = fwrite(ptr, 1, size, (FILE *) CFH->private_data);
     166      2186623 :     if (ret != size)
     167              :     {
     168            0 :         errno = (errno) ? errno : ENOSPC;
     169            0 :         pg_fatal("could not write to file: %m");
     170              :     }
     171      2186623 : }
     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       176680 : getc_none(CompressFileHandle *CFH)
     187              : {
     188       176680 :     FILE       *fp = (FILE *) CFH->private_data;
     189              :     int         ret;
     190              : 
     191       176680 :     ret = fgetc(fp);
     192       176680 :     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       176680 :     return ret;
     201              : }
     202              : 
     203              : static bool
     204          743 : close_none(CompressFileHandle *CFH)
     205              : {
     206          743 :     FILE       *fp = (FILE *) CFH->private_data;
     207          743 :     int         ret = 0;
     208              : 
     209          743 :     CFH->private_data = NULL;
     210              : 
     211          743 :     if (fp)
     212              :     {
     213          743 :         errno = 0;
     214          743 :         ret = fclose(fp);
     215          743 :         if (ret != 0)
     216            0 :             pg_log_error("could not close file: %m");
     217              :     }
     218              : 
     219          743 :     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          702 : open_none(const char *path, int fd, const char *mode, CompressFileHandle *CFH)
     230              : {
     231              :     Assert(CFH->private_data == NULL);
     232              : 
     233          702 :     if (fd >= 0)
     234          418 :         CFH->private_data = fdopen(dup(fd), mode);
     235              :     else
     236          284 :         CFH->private_data = fopen(path, mode);
     237              : 
     238          702 :     if (CFH->private_data == NULL)
     239            0 :         return false;
     240              : 
     241          702 :     return true;
     242              : }
     243              : 
     244              : static bool
     245           63 : open_write_none(const char *path, const char *mode, CompressFileHandle *CFH)
     246              : {
     247              :     Assert(CFH->private_data == NULL);
     248              : 
     249           63 :     CFH->private_data = fopen(path, mode);
     250           63 :     if (CFH->private_data == NULL)
     251            0 :         return false;
     252              : 
     253           63 :     return true;
     254              : }
     255              : 
     256              : /*
     257              :  * Public interface
     258              :  */
     259              : 
     260              : void
     261          765 : InitCompressFileHandleNone(CompressFileHandle *CFH,
     262              :                            const pg_compress_specification compression_spec)
     263              : {
     264          765 :     CFH->open_func = open_none;
     265          765 :     CFH->open_write_func = open_write_none;
     266          765 :     CFH->read_func = read_none;
     267          765 :     CFH->write_func = write_none;
     268          765 :     CFH->gets_func = gets_none;
     269          765 :     CFH->getc_func = getc_none;
     270          765 :     CFH->close_func = close_none;
     271          765 :     CFH->eof_func = eof_none;
     272          765 :     CFH->get_error_func = get_error_none;
     273              : 
     274          765 :     CFH->private_data = NULL;
     275          765 : }
        

Generated by: LCOV version 2.0-1