1 /*-------------------------------------------------------------------------
5 * Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
6 * Portions Copyright (c) 1994, Regents of the University of California
11 *-------------------------------------------------------------------------
17 #include "postgres_fe.h"
23 #include "common/file_utils.h"
26 #include "storage/fd.h"
27 #define pg_log_warning(...) elog(WARNING, __VA_ARGS__)
28 #define LOG_LEVEL WARNING
29 #define OPENDIR(x) AllocateDir(x)
30 #define CLOSEDIR(x) FreeDir(x)
32 #include "common/logging.h"
33 #define LOG_LEVEL PG_LOG_WARNING
34 #define OPENDIR(x) opendir(x)
35 #define CLOSEDIR(x) closedir(x)
41 * Delete a directory tree recursively.
42 * Assumes path points to a valid directory.
43 * Deletes everything under path.
44 * If rmtopdir is true deletes the directory too.
45 * Returns true if successful, false if there was any problem.
46 * (The details of the problem are reported already, so caller
47 * doesn't really have to say anything more, but most do.)
50 rmtree(const char *path
, bool rmtopdir
)
52 char pathbuf
[MAXPGPATH
];
56 size_t dirnames_size
= 0;
57 size_t dirnames_capacity
= 8;
63 pg_log_warning("could not open directory \"%s\": %m", path
);
67 dirnames
= (char **) palloc(sizeof(char *) * dirnames_capacity
);
69 while (errno
= 0, (de
= readdir(dir
)))
71 if (strcmp(de
->d_name
, ".") == 0 ||
72 strcmp(de
->d_name
, "..") == 0)
74 snprintf(pathbuf
, sizeof(pathbuf
), "%s/%s", path
, de
->d_name
);
75 switch (get_dirent_type(pathbuf
, de
, false, LOG_LEVEL
))
77 case PGFILETYPE_ERROR
:
78 /* already logged, press on */
83 * Defer recursion until after we've closed this directory, to
84 * avoid using more than one file descriptor at a time.
86 if (dirnames_size
== dirnames_capacity
)
88 dirnames
= repalloc(dirnames
,
89 sizeof(char *) * dirnames_capacity
* 2);
90 dirnames_capacity
*= 2;
92 dirnames
[dirnames_size
++] = pstrdup(pathbuf
);
95 if (unlink(pathbuf
) != 0 && errno
!= ENOENT
)
97 pg_log_warning("could not remove file \"%s\": %m", pathbuf
);
106 pg_log_warning("could not read directory \"%s\": %m", path
);
112 /* Now recurse into the subdirectories we found. */
113 for (size_t i
= 0; i
< dirnames_size
; ++i
)
115 if (!rmtree(dirnames
[i
], true))
122 if (rmdir(path
) != 0)
124 pg_log_warning("could not remove directory \"%s\": %m", path
);