1
1
/*
2
2
* Phusion Passenger - https://www.phusionpassenger.com/
3
- * Copyright (c) 2010-2013 Phusion
3
+ * Copyright (c) 2010-2014 Phusion
4
4
*
5
5
* "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui.
6
6
*
@@ -193,6 +193,9 @@ class ServerInstanceDir: public noncopyable {
193
193
194
194
void initialize (const string &path, bool owner) {
195
195
TRACE_POINT ();
196
+ struct stat buf;
197
+ int ret;
198
+
196
199
this ->path = path;
197
200
this ->owner = owner;
198
201
@@ -212,18 +215,25 @@ class ServerInstanceDir: public noncopyable {
212
215
* rights though, because we want admin tools to be able to list the available
213
216
* generations no matter what user they're running as.
214
217
*/
218
+
219
+ do {
220
+ ret = lstat (path.c_str (), &buf);
221
+ } while (ret == -1 && errno == EAGAIN);
215
222
if (owner) {
216
- switch (getFileTypeNoFollowSymlinks (path)) {
217
- case FT_NONEXISTANT:
223
+ if (ret == 0 ) {
224
+ if (S_ISDIR (buf.st_mode )) {
225
+ verifyDirectoryPermissions (path, buf);
226
+ } else {
227
+ throw RuntimeException (" '" + path + " ' already exists, and is not a directory" );
228
+ }
229
+ } else if (errno == ENOENT) {
218
230
createDirectory (path);
219
- break ;
220
- case FT_DIRECTORY:
221
- verifyDirectoryPermissions (path);
222
- break ;
223
- default :
224
- throw RuntimeException (" '" + path + " ' already exists, and is not a directory" );
231
+ } else {
232
+ int e = errno;
233
+ throw FileSystemException (" Cannot lstat '" + path + " '" ,
234
+ e, path);
225
235
}
226
- } else if (getFileType (path) != FT_DIRECTORY ) {
236
+ } else if (! S_ISDIR (buf. st_mode ) ) {
227
237
throw RuntimeException (" Server instance directory '" + path +
228
238
" ' does not exist" );
229
239
}
@@ -259,14 +269,10 @@ class ServerInstanceDir: public noncopyable {
259
269
* so that an attacker cannot pre-create a directory with too liberal
260
270
* permissions.
261
271
*/
262
- void verifyDirectoryPermissions (const string &path) {
272
+ void verifyDirectoryPermissions (const string &path, struct stat &buf ) {
263
273
TRACE_POINT ();
264
- struct stat buf;
265
274
266
- if (stat (path.c_str (), &buf) == -1 ) {
267
- int e = errno;
268
- throw FileSystemException (" Cannot stat() " + path, e, path);
269
- } else if (buf.st_mode != (S_IFDIR | parseModeString (" u=rwx,g=rx,o=rx" ))) {
275
+ if (buf.st_mode != (S_IFDIR | parseModeString (" u=rwx,g=rx,o=rx" ))) {
270
276
throw RuntimeException (" Tried to reuse existing server instance directory " +
271
277
path + " , but it has wrong permissions" );
272
278
} else if (buf.st_uid != geteuid () || buf.st_gid != getegid ()) {
0 commit comments