56
56
#include "compress_io.h"
57
57
#include "pg_backup_utils.h"
58
58
59
+ #ifdef HAVE_LIBZ
60
+ #include <zlib.h>
61
+ #endif
62
+
63
+ /*----------------------
64
+ * Generic functions
65
+ *----------------------
66
+ */
67
+
68
+ /*
69
+ * Checks whether a compression algorithm is supported.
70
+ *
71
+ * On success returns NULL, otherwise returns a malloc'ed string which can be
72
+ * used by the caller in an error message.
73
+ */
74
+ char *
75
+ supports_compression (const pg_compress_specification compression_spec )
76
+ {
77
+ const pg_compress_algorithm algorithm = compression_spec .algorithm ;
78
+ bool supported = false;
79
+
80
+ if (algorithm == PG_COMPRESSION_NONE )
81
+ supported = true;
82
+ #ifdef HAVE_LIBZ
83
+ if (algorithm == PG_COMPRESSION_GZIP )
84
+ supported = true;
85
+ #endif
86
+
87
+ if (!supported )
88
+ return psprintf ("this build does not support compression with %s" ,
89
+ get_compress_algorithm_name (algorithm ));
90
+
91
+ return NULL ;
92
+ }
93
+
59
94
/*----------------------
60
95
* Compressor API
61
96
*----------------------
@@ -490,16 +525,19 @@ cfopen_write(const char *path, const char *mode,
490
525
}
491
526
492
527
/*
493
- * Opens file 'path' in 'mode'. If compression is GZIP, the file
494
- * is opened with libz gzopen(), otherwise with plain fopen().
528
+ * This is the workhorse for cfopen() or cfdopen(). It opens file 'path' or
529
+ * associates a stream 'fd', if 'fd' is a valid descriptor, in 'mode'. The
530
+ * descriptor is not dup'ed and it is the caller's responsibility to do so.
531
+ * The caller must verify that the 'compress_algorithm' is supported by the
532
+ * current build.
495
533
*
496
534
* On failure, return NULL with an error code in errno.
497
535
*/
498
- cfp *
499
- cfopen (const char * path , const char * mode ,
500
- const pg_compress_specification compression_spec )
536
+ static cfp *
537
+ cfopen_internal (const char * path , int fd , const char * mode ,
538
+ pg_compress_specification compression_spec )
501
539
{
502
- cfp * fp = pg_malloc (sizeof (cfp ));
540
+ cfp * fp = pg_malloc0 (sizeof (cfp ));
503
541
504
542
if (compression_spec .algorithm == PG_COMPRESSION_GZIP )
505
543
{
@@ -511,15 +549,20 @@ cfopen(const char *path, const char *mode,
511
549
512
550
snprintf (mode_compression , sizeof (mode_compression ), "%s%d" ,
513
551
mode , compression_spec .level );
514
- fp -> compressedfp = gzopen (path , mode_compression );
552
+ if (fd >= 0 )
553
+ fp -> compressedfp = gzdopen (fd , mode_compression );
554
+ else
555
+ fp -> compressedfp = gzopen (path , mode_compression );
515
556
}
516
557
else
517
558
{
518
559
/* don't specify a level, just use the zlib default */
519
- fp -> compressedfp = gzopen (path , mode );
560
+ if (fd >= 0 )
561
+ fp -> compressedfp = gzdopen (fd , mode );
562
+ else
563
+ fp -> compressedfp = gzopen (path , mode );
520
564
}
521
565
522
- fp -> uncompressedfp = NULL ;
523
566
if (fp -> compressedfp == NULL )
524
567
{
525
568
free_keep_errno (fp );
@@ -531,10 +574,11 @@ cfopen(const char *path, const char *mode,
531
574
}
532
575
else
533
576
{
534
- #ifdef HAVE_LIBZ
535
- fp -> compressedfp = NULL ;
536
- #endif
537
- fp -> uncompressedfp = fopen (path , mode );
577
+ if (fd >= 0 )
578
+ fp -> uncompressedfp = fdopen (fd , mode );
579
+ else
580
+ fp -> uncompressedfp = fopen (path , mode );
581
+
538
582
if (fp -> uncompressedfp == NULL )
539
583
{
540
584
free_keep_errno (fp );
@@ -545,6 +589,33 @@ cfopen(const char *path, const char *mode,
545
589
return fp ;
546
590
}
547
591
592
+ /*
593
+ * Opens file 'path' in 'mode' and compression as defined in
594
+ * compression_spec. The caller must verify that the compression
595
+ * is supported by the current build.
596
+ *
597
+ * On failure, return NULL with an error code in errno.
598
+ */
599
+ cfp *
600
+ cfopen (const char * path , const char * mode ,
601
+ const pg_compress_specification compression_spec )
602
+ {
603
+ return cfopen_internal (path , -1 , mode , compression_spec );
604
+ }
605
+
606
+ /*
607
+ * Associates a stream 'fd', if 'fd' is a valid descriptor, in 'mode'
608
+ * and compression as defined in compression_spec. The caller must
609
+ * verify that the compression is supported by the current build.
610
+ *
611
+ * On failure, return NULL with an error code in errno.
612
+ */
613
+ cfp *
614
+ cfdopen (int fd , const char * mode ,
615
+ const pg_compress_specification compression_spec )
616
+ {
617
+ return cfopen_internal (NULL , fd , mode , compression_spec );
618
+ }
548
619
549
620
int
550
621
cfread (void * ptr , int size , cfp * fp )
0 commit comments