File tree Expand file tree Collapse file tree 1 file changed +30
-2
lines changed Expand file tree Collapse file tree 1 file changed +30
-2
lines changed Original file line number Diff line number Diff line change 19
19
#include < sys/types.h>
20
20
#include < unistd.h>
21
21
22
+ #include < cerrno>
23
+ #include < iostream>
22
24
#include < string>
23
25
24
26
#ifdef __APPLE__
@@ -100,7 +102,13 @@ bool MakeDirs(const std::string &path, int mode) {
100
102
struct stat dir_stats;
101
103
if (stat (path.c_str (), &dir_stats) == 0 ) {
102
104
// Return true if the directory already exists.
103
- return S_ISDIR (dir_stats.st_mode );
105
+ if (S_ISDIR (dir_stats.st_mode )) {
106
+ return true ;
107
+ }
108
+
109
+ std::cerr << " error: path already exists but is not a directory: "
110
+ << path << " \n " ;
111
+ return false ;
104
112
}
105
113
106
114
// Recurse to create the parent directory.
@@ -109,5 +117,25 @@ bool MakeDirs(const std::string &path, int mode) {
109
117
}
110
118
111
119
// Create the directory that was requested.
112
- return mkdir (path.c_str (), mode) == 0 ;
120
+ if (mkdir (path.c_str (), mode) == 0 ) {
121
+ return true ;
122
+ }
123
+
124
+ // Race condition: The above call to `mkdir` could fail if there are multiple
125
+ // calls to `MakeDirs` running at the same time with overlapping paths, so
126
+ // check again to see if the directory exists despite the call failing. If it
127
+ // does, that's ok.
128
+ if (errno == EEXIST && stat (path.c_str (), &dir_stats) == 0 ) {
129
+ if (S_ISDIR (dir_stats.st_mode )) {
130
+ return true ;
131
+ }
132
+
133
+ std::cerr << " error: path already exists but is not a directory: "
134
+ << path << " \n " ;
135
+ return false ;
136
+ }
137
+
138
+ std::cerr << " error: could not create directory: " << path
139
+ << " (" << strerror (errno) << " )\n " ;
140
+ return false ;
113
141
}
You can’t perform that action at this time.
0 commit comments