PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
rmtree.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * rmtree.c
4  *
5  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
6  * Portions Copyright (c) 1994, Regents of the University of California
7  *
8  * IDENTIFICATION
9  * src/common/rmtree.c
10  *
11  *-------------------------------------------------------------------------
12  */
13 
14 #ifndef FRONTEND
15 #include "postgres.h"
16 #else
17 #include "postgres_fe.h"
18 #endif
19 
20 #include <unistd.h>
21 #include <sys/stat.h>
22 
23 
24 /*
25  * rmtree
26  *
27  * Delete a directory tree recursively.
28  * Assumes path points to a valid directory.
29  * Deletes everything under path.
30  * If rmtopdir is true deletes the directory too.
31  * Returns true if successful, false if there was any problem.
32  * (The details of the problem are reported already, so caller
33  * doesn't really have to say anything more, but most do.)
34  */
35 bool
36 rmtree(const char *path, bool rmtopdir)
37 {
38  bool result = true;
39  char pathbuf[MAXPGPATH];
40  char **filenames;
41  char **filename;
42  struct stat statbuf;
43 
44  /*
45  * we copy all the names out of the directory before we start modifying
46  * it.
47  */
48  filenames = pgfnames(path);
49 
50  if (filenames == NULL)
51  return false;
52 
53  /* now we have the names we can start removing things */
54  for (filename = filenames; *filename; filename++)
55  {
56  snprintf(pathbuf, MAXPGPATH, "%s/%s", path, *filename);
57 
58  /*
59  * It's ok if the file is not there anymore; we were just about to
60  * delete it anyway.
61  *
62  * This is not an academic possibility. One scenario where this
63  * happens is when bgwriter has a pending unlink request for a file in
64  * a database that's being dropped. In dropdb(), we call
65  * ForgetDatabaseFsyncRequests() to flush out any such pending unlink
66  * requests, but because that's asynchronous, it's not guaranteed that
67  * the bgwriter receives the message in time.
68  */
69  if (lstat(pathbuf, &statbuf) != 0)
70  {
71  if (errno != ENOENT)
72  {
73 #ifndef FRONTEND
74  elog(WARNING, "could not stat file or directory \"%s\": %m",
75  pathbuf);
76 #else
77  fprintf(stderr, _("could not stat file or directory \"%s\": %s\n"),
78  pathbuf, strerror(errno));
79 #endif
80  result = false;
81  }
82  continue;
83  }
84 
85  if (S_ISDIR(statbuf.st_mode))
86  {
87  /* call ourselves recursively for a directory */
88  if (!rmtree(pathbuf, true))
89  {
90  /* we already reported the error */
91  result = false;
92  }
93  }
94  else
95  {
96  if (unlink(pathbuf) != 0)
97  {
98  if (errno != ENOENT)
99  {
100 #ifndef FRONTEND
101  elog(WARNING, "could not remove file or directory \"%s\": %m",
102  pathbuf);
103 #else
104  fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
105  pathbuf, strerror(errno));
106 #endif
107  result = false;
108  }
109  }
110  }
111  }
112 
113  if (rmtopdir)
114  {
115  if (rmdir(path) != 0)
116  {
117 #ifndef FRONTEND
118  elog(WARNING, "could not remove file or directory \"%s\": %m",
119  path);
120 #else
121  fprintf(stderr, _("could not remove file or directory \"%s\": %s\n"),
122  path, strerror(errno));
123 #endif
124  result = false;
125  }
126  }
127 
128  pgfnames_cleanup(filenames);
129 
130  return result;
131 }
char ** pgfnames(const char *path)
Definition: pgfnames.c:31
return result
Definition: formatting.c:1618
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
#define MAXPGPATH
int unlink(const char *filename)
#define WARNING
Definition: elog.h:40
bool rmtree(const char *path, bool rmtopdir)
Definition: rmtree.c:36
#define NULL
Definition: c.h:229
void pgfnames_cleanup(char **filenames)
Definition: pgfnames.c:99
static char * filename
Definition: pg_dumpall.c:87
const char * strerror(int errnum)
Definition: strerror.c:19
#define elog
Definition: elog.h:219
#define lstat(path, sb)
Definition: win32.h:262
#define _(x)
Definition: elog.c:84