File tree Expand file tree Collapse file tree 1 file changed +27
-1
lines changed Expand file tree Collapse file tree 1 file changed +27
-1
lines changed Original file line number Diff line number Diff line change 9999pgunlink (const char * path )
100100{
101101 int loops = 0 ;
102+ struct stat st ;
103+
104+ /*
105+ * This function might be called for a regular file or for a junction
106+ * point (which we use to emulate symlinks). The latter must be unlinked
107+ * with rmdir() on Windows. Before we worry about any of that, let's see
108+ * if we can unlink directly, since that's expected to be the most common
109+ * case.
110+ */
111+ if (unlink (path ) == 0 )
112+ return 0 ;
113+ if (errno != EACCES )
114+ return -1 ;
115+
116+ /*
117+ * EACCES is reported for many reasons including unlink() of a junction
118+ * point. Check if that's the case so we can redirect to rmdir().
119+ *
120+ * Note that by checking only once, we can't cope with a path that changes
121+ * from regular file to junction point underneath us while we're retrying
122+ * due to sharing violations, but that seems unlikely. We could perhaps
123+ * prevent that by holding a file handle ourselves across the lstat() and
124+ * the retry loop, but that seems like over-engineering for now.
125+ */
126+ if (lstat (path , & st ) < 0 )
127+ return -1 ;
102128
103129 /*
104130 * We need to loop because even though PostgreSQL uses flags that allow
@@ -107,7 +133,7 @@ pgunlink(const char *path)
107133 * someone else to close the file, as the caller might be holding locks
108134 * and blocking other backends.
109135 */
110- while (unlink (path ))
136+ while (( S_ISLNK ( st . st_mode ) ? rmdir ( path ) : unlink (path )) < 0 )
111137 {
112138 if (errno != EACCES )
113139 return -1 ;
You can’t perform that action at this time.
0 commit comments