#include "postgres.h"
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
Go to the source code of this file.
Functions | |
char ** | pgfnames (const char *path) |
void | pgfnames_cleanup (char **filenames) |
bool | rmtree (const char *path, bool rmtopdir) |
char** pgfnames | ( | const char * | path | ) |
Definition at line 363 of file dirmod.c.
References _, closedir(), dirent::d_name, elog, NULL, opendir(), palloc(), pstrdup(), readdir(), repalloc(), strerror(), and WARNING.
Referenced by convert_sourcefiles_in(), rmtree(), and scan_available_timezones().
{ DIR *dir; struct dirent *file; char **filenames; int numnames = 0; int fnsize = 200; /* enough for many small dbs */ dir = opendir(path); if (dir == NULL) { #ifndef FRONTEND elog(WARNING, "could not open directory \"%s\": %m", path); #else fprintf(stderr, _("could not open directory \"%s\": %s\n"), path, strerror(errno)); #endif return NULL; } filenames = (char **) palloc(fnsize * sizeof(char *)); errno = 0; while ((file = readdir(dir)) != NULL) { if (strcmp(file->d_name, ".") != 0 && strcmp(file->d_name, "..") != 0) { if (numnames + 1 >= fnsize) { fnsize *= 2; filenames = (char **) repalloc(filenames, fnsize * sizeof(char *)); } filenames[numnames++] = pstrdup(file->d_name); } errno = 0; } #ifdef WIN32 /* * This fix is in mingw cvs (runtime/mingwex/dirent.c rev 1.4), but not in * released version */ if (GetLastError() == ERROR_NO_MORE_FILES) errno = 0; #endif if (errno) { #ifndef FRONTEND elog(WARNING, "could not read directory \"%s\": %m", path); #else fprintf(stderr, _("could not read directory \"%s\": %s\n"), path, strerror(errno)); #endif } filenames[numnames] = NULL; closedir(dir); return filenames; }
void pgfnames_cleanup | ( | char ** | filenames | ) |
Definition at line 433 of file dirmod.c.
References pfree().
Referenced by convert_sourcefiles_in(), rmtree(), and scan_available_timezones().
Definition at line 456 of file dirmod.c.
References _, elog, filename, lstat, MAXPGPATH, NULL, pgfnames(), pgfnames_cleanup(), rmtree(), snprintf(), strerror(), unlink(), and WARNING.
Referenced by convert_sourcefiles_in(), copy_subdir_files(), create_tablespace_directories(), dbase_redo(), exit_nicely(), movedb(), movedb_failure_callback(), regression_main(), remove_dbtablespaces(), and rmtree().
{ bool result = true; char pathbuf[MAXPGPATH]; char **filenames; char **filename; struct stat statbuf; /* * we copy all the names out of the directory before we start modifying * it. */ filenames = pgfnames(path); if (filenames == NULL) return false; /* now we have the names we can start removing things */ for (filename = filenames; *filename; filename++) { snprintf(pathbuf, MAXPGPATH, "%s/%s", path, *filename); /* * It's ok if the file is not there anymore; we were just about to * delete it anyway. * * This is not an academic possibility. One scenario where this * happens is when bgwriter has a pending unlink request for a file in * a database that's being dropped. In dropdb(), we call * ForgetDatabaseFsyncRequests() to flush out any such pending unlink * requests, but because that's asynchronous, it's not guaranteed that * the bgwriter receives the message in time. */ if (lstat(pathbuf, &statbuf) != 0) { if (errno != ENOENT) { #ifndef FRONTEND elog(WARNING, "could not stat file or directory \"%s\": %m", pathbuf); #else fprintf(stderr, _("could not stat file or directory \"%s\": %s\n"), pathbuf, strerror(errno)); #endif result = false; } continue; } if (S_ISDIR(statbuf.st_mode)) { /* call ourselves recursively for a directory */ if (!rmtree(pathbuf, true)) { /* we already reported the error */ result = false; } } else { if (unlink(pathbuf) != 0) { if (errno != ENOENT) { #ifndef FRONTEND elog(WARNING, "could not remove file or directory \"%s\": %m", pathbuf); #else fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), pathbuf, strerror(errno)); #endif result = false; } } } } if (rmtopdir) { if (rmdir(path) != 0) { #ifndef FRONTEND elog(WARNING, "could not remove file or directory \"%s\": %m", path); #else fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"), path, strerror(errno)); #endif result = false; } } pgfnames_cleanup(filenames); return result; }