]> granicus.if.org Git - postgresql/blob - src/common/rmtree.c
Don't zero opfuncid when reading nodes.
[postgresql] / src / common / rmtree.c
1 /*-------------------------------------------------------------------------
2  *
3  * rmtree.c
4  *
5  * Portions Copyright (c) 1996-2015, 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 }