|
|
|
@ -21,12 +21,6 @@ static int copy_file(const char *fromfile, const char *tofile, bool force); |
|
|
|
|
static int win32_pghardlink(const char *src, const char *dst); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#ifndef HAVE_SCANDIR |
|
|
|
|
static int pg_scandir_internal(const char *dirname, |
|
|
|
|
struct dirent *** namelist, |
|
|
|
|
int (*selector) (const struct dirent *)); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* copyAndUpdateFile() |
|
|
|
@ -228,45 +222,7 @@ copy_file(const char *srcfile, const char *dstfile, bool force) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* pg_scandir() |
|
|
|
|
* |
|
|
|
|
* Wrapper for portable scandir functionality |
|
|
|
|
*/ |
|
|
|
|
int |
|
|
|
|
pg_scandir(const char *dirname, |
|
|
|
|
struct dirent *** namelist, |
|
|
|
|
int (*selector) (const struct dirent *)) |
|
|
|
|
{ |
|
|
|
|
#ifndef HAVE_SCANDIR |
|
|
|
|
return pg_scandir_internal(dirname, namelist, selector); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* scandir() is originally from BSD 4.3, which had the third argument as |
|
|
|
|
* non-const. Linux and other C libraries have updated it to use a const. |
|
|
|
|
* http://unix.derkeiler.com/Mailing-Lists/FreeBSD/questions/2005-12/msg002
|
|
|
|
|
* 14.html |
|
|
|
|
* |
|
|
|
|
* Here we try to guess which libc's need const, and which don't. The net |
|
|
|
|
* goal here is to try to suppress a compiler warning due to a prototype |
|
|
|
|
* mismatch of const usage. Ideally we would do this via autoconf, but |
|
|
|
|
* autoconf doesn't have a suitable builtin test and it seems overkill to |
|
|
|
|
* add one just to avoid a warning. |
|
|
|
|
*/ |
|
|
|
|
#elif defined(__FreeBSD__) || defined(__bsdi__) || defined(__darwin__) || defined(__OpenBSD__) |
|
|
|
|
/* no const */ |
|
|
|
|
return scandir(dirname, namelist, (int (*) (struct dirent *)) selector, NULL); |
|
|
|
|
#else |
|
|
|
|
/* use const */ |
|
|
|
|
return scandir(dirname, namelist, selector, NULL); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef HAVE_SCANDIR |
|
|
|
|
/*
|
|
|
|
|
* pg_scandir_internal() |
|
|
|
|
* |
|
|
|
|
* Implement our own scandir() on platforms that don't have it. |
|
|
|
|
* load_directory() |
|
|
|
|
* |
|
|
|
|
* Returns count of files that meet the selection criteria coded in |
|
|
|
|
* the function pointed to by selector. Creates an array of pointers |
|
|
|
@ -274,13 +230,10 @@ pg_scandir(const char *dirname, |
|
|
|
|
* |
|
|
|
|
* Note that the number of dirent structures needed is dynamically |
|
|
|
|
* allocated using realloc. Realloc can be inefficient if invoked a |
|
|
|
|
* large number of times. Its use in pg_upgrade is to find filesystem |
|
|
|
|
* filenames that have extended beyond the initial segment (file.1, |
|
|
|
|
* .2, etc.) and should therefore be invoked a small number of times. |
|
|
|
|
* large number of times. |
|
|
|
|
*/ |
|
|
|
|
static int |
|
|
|
|
pg_scandir_internal(const char *dirname, |
|
|
|
|
struct dirent *** namelist, int (*selector) (const struct dirent *)) |
|
|
|
|
int |
|
|
|
|
load_directory(const char *dirname, struct dirent ***namelist) |
|
|
|
|
{ |
|
|
|
|
DIR *dirdesc; |
|
|
|
|
struct dirent *direntry; |
|
|
|
@ -295,42 +248,37 @@ pg_scandir_internal(const char *dirname, |
|
|
|
|
|
|
|
|
|
while ((direntry = readdir(dirdesc)) != NULL) |
|
|
|
|
{ |
|
|
|
|
/* Invoke the selector function to see if the direntry matches */ |
|
|
|
|
if (!selector || (*selector) (direntry)) |
|
|
|
|
{ |
|
|
|
|
count++; |
|
|
|
|
count++; |
|
|
|
|
|
|
|
|
|
*namelist = (struct dirent **) realloc((void *) (*namelist), |
|
|
|
|
(size_t) ((name_num + 1) * sizeof(struct dirent *))); |
|
|
|
|
*namelist = (struct dirent **) realloc((void *) (*namelist), |
|
|
|
|
(size_t) ((name_num + 1) * sizeof(struct dirent *))); |
|
|
|
|
|
|
|
|
|
if (*namelist == NULL) |
|
|
|
|
{ |
|
|
|
|
closedir(dirdesc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if (*namelist == NULL) |
|
|
|
|
{ |
|
|
|
|
closedir(dirdesc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
entrysize = sizeof(struct dirent) - sizeof(direntry->d_name) + |
|
|
|
|
strlen(direntry->d_name) + 1; |
|
|
|
|
entrysize = sizeof(struct dirent) - sizeof(direntry->d_name) + |
|
|
|
|
strlen(direntry->d_name) + 1; |
|
|
|
|
|
|
|
|
|
(*namelist)[name_num] = (struct dirent *) malloc(entrysize); |
|
|
|
|
(*namelist)[name_num] = (struct dirent *) malloc(entrysize); |
|
|
|
|
|
|
|
|
|
if ((*namelist)[name_num] == NULL) |
|
|
|
|
{ |
|
|
|
|
closedir(dirdesc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
if ((*namelist)[name_num] == NULL) |
|
|
|
|
{ |
|
|
|
|
closedir(dirdesc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memcpy((*namelist)[name_num], direntry, entrysize); |
|
|
|
|
memcpy((*namelist)[name_num], direntry, entrysize); |
|
|
|
|
|
|
|
|
|
name_num++; |
|
|
|
|
} |
|
|
|
|
name_num++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
closedir(dirdesc); |
|
|
|
|
|
|
|
|
|
return count; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void |
|
|
|
|