Skip to content

Commit b84334b

Browse files
author
Michael Paquier
committed
Remove unportable code of IsDir
IsDir was somewhat optimized on systems where DT_DIR (dirent.d_type being not part of the POSIX spec) is present on some systems leading to more complex logic depending on the file system used, particularly on XFS this routine was actually broken. Having a call to stat() should not be that expensive to check if a path is a directory or not and this is proving to be far more stable coding, so just rely on that, that's more portable anyway and will avoid future surprises. Report by Yury Zhuravlev, though I did not use his patch.
1 parent 7254d30 commit b84334b

File tree

1 file changed

+9
-18
lines changed

1 file changed

+9
-18
lines changed

catalog.c

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -90,24 +90,14 @@ catalog_get_backup(time_t timestamp)
9090
}
9191

9292
static bool
93-
IsDir(const char *dirpath, const DIR *dir, const struct dirent *ent)
93+
IsDir(const char *dirpath, const char *entry)
9494
{
95-
#if defined(DT_DIR)
96-
return ent->d_type == DT_DIR;
97-
#elif defined(_finddata_t)
98-
/* Optimization for VC++ on Windows. */
99-
return (dir->dd_dta.attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
100-
#else
101-
/* Portable implementation because dirent.d_type is not in POSIX. */
10295
char path[MAXPGPATH];
10396
struct stat st;
10497

105-
strlcpy(path, dirpath, MAXPGPATH);
106-
strlcat(path, "/", MAXPGPATH);
107-
strlcat(path, ent->d_name, MAXPGPATH);
98+
snprintf(path, MAXPGPATH, "%s/%s", dirpath, entry);
10899

109100
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
110-
#endif
111101
}
112102

113103
/*
@@ -157,7 +147,7 @@ catalog_get_backup_list(const pgBackupRange *range)
157147
for (; (date_ent = readdir(date_dir)) != NULL; errno = 0)
158148
{
159149
/* skip not-directory entries and hidden entries */
160-
if (!IsDir(backup_path, date_dir, date_ent) || date_ent->d_name[0] == '.')
150+
if (!IsDir(backup_path, date_ent->d_name) || date_ent->d_name[0] == '.')
161151
continue;
162152

163153
/* skip online WAL backup directory */
@@ -183,20 +173,21 @@ catalog_get_backup_list(const pgBackupRange *range)
183173
{
184174
char ini_path[MAXPGPATH];
185175

186-
/* skip not-directory and hidden directories */
187-
if (!IsDir(date_path, date_dir, time_ent) || time_ent->d_name[0] == '.')
176+
/* skip entries that are directories and hidden directories */
177+
if (!IsDir(date_path, time_ent->d_name) || time_ent->d_name[0] == '.')
188178
continue;
189179

190180
/* If the time is out of range, skip it. */
191181
if (pgBackupRangeIsValid(range) &&
192-
(strcmp(begin_time, time_ent->d_name) > 0 ||
193-
strcmp(end_time, time_ent->d_name) < 0))
182+
(strcmp(begin_time, time_ent->d_name) > 0 ||
183+
strcmp(end_time, time_ent->d_name) < 0))
194184
continue;
195185

196186
/* read backup information from backup.ini */
197187
snprintf(ini_path, MAXPGPATH, "%s/%s/%s", date_path,
198-
time_ent->d_name, BACKUP_INI_FILE);
188+
time_ent->d_name, BACKUP_INI_FILE);
199189
backup = catalog_read_ini(ini_path);
190+
200191
/* ignore corrupted backup */
201192
if (backup)
202193
{

0 commit comments

Comments
 (0)