From 0a2222476df6eea6f4ffba176395b589d42b22be Mon Sep 17 00:00:00 2001 From: Mahendra Singh Thalor Date: Mon, 7 Apr 2025 17:43:05 +0530 Subject: [PATCH] move create dir code to the switch as per commit in pg_dumpall in commit 643a1a61985bef2590496, we moved code of create/open directory into switch case. Same code we are using in InitArchiveFmt_Directory also. (file: src/bin/pg_dump/pg_backup_directory.c) As per pg_dumpall, we can make same here. If we want, we can move common code to other common file also. --- src/bin/pg_dump/pg_backup_directory.c | 71 ++++++++++++++------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/src/bin/pg_dump/pg_backup_directory.c b/src/bin/pg_dump/pg_backup_directory.c index b2a841bb0ff..7db1bae334b 100644 --- a/src/bin/pg_dump/pg_backup_directory.c +++ b/src/bin/pg_dump/pg_backup_directory.c @@ -39,6 +39,7 @@ #include #include +#include "common/file_perm.h" #include "common/file_utils.h" #include "compress_io.h" #include "parallel.h" @@ -94,6 +95,7 @@ static int _WorkerJobDumpDirectory(ArchiveHandle *AH, TocEntry *te); static void setFilePath(ArchiveHandle *AH, char *buf, const char *relativeFilename); +static void create_or_open_dir(const char *dirname); /* * Init routine required by ALL formats. This is a global routine @@ -156,41 +158,8 @@ InitArchiveFmt_Directory(ArchiveHandle *AH) if (AH->mode == archModeWrite) { - struct stat st; - bool is_empty = false; - /* we accept an empty existing directory */ - if (stat(ctx->directory, &st) == 0 && S_ISDIR(st.st_mode)) - { - DIR *dir = opendir(ctx->directory); - - if (dir) - { - struct dirent *d; - - is_empty = true; - while (errno = 0, (d = readdir(dir))) - { - if (strcmp(d->d_name, ".") != 0 && strcmp(d->d_name, "..") != 0) - { - is_empty = false; - break; - } - } - - if (errno) - pg_fatal("could not read directory \"%s\": %m", - ctx->directory); - - if (closedir(dir)) - pg_fatal("could not close directory \"%s\": %m", - ctx->directory); - } - } - - if (!is_empty && mkdir(ctx->directory, 0700) < 0) - pg_fatal("could not create directory \"%s\": %m", - ctx->directory); + create_or_open_dir(ctx->directory); } else { /* Read Mode */ @@ -875,3 +844,37 @@ _WorkerJobRestoreDirectory(ArchiveHandle *AH, TocEntry *te) { return parallel_restore(AH, te); } + +/* + * create_or_open_dir + * + * This will create a new directory with the given dirname. If there is + * already an empty directory with that name, then use it. + */ +void +create_or_open_dir(const char *dirname) +{ + int ret; + + switch ((ret = pg_check_dir(dirname))) + { + case -1: + /* opendir failed but not with ENOENT */ + pg_fatal("could not open directory \"%s\": %m", dirname); + break; + case 0: + /* directory does not exist */ + if (mkdir(dirname, pg_dir_create_mode) < 0) + pg_fatal("could not create directory \"%s\": %m", dirname); + break; + case 1: + /* exists and is empty, fix perms */ + if (chmod(dirname, pg_dir_create_mode) != 0) + pg_fatal("could not change permissions of directory \"%s\": %m", + dirname); + break; + default: + /* exists and is not empty */ + pg_fatal("directory \"%s\" is not empty", dirname); + } +} -- 2.39.3