blob: 0cece75730e02a1fa0ad51b9136d765049f8d2be [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "filesystem/directory.h"
#include <limits.h>
#include <sys/stat.h>
#include <vector>
#include "filesystem/path.h"
#include "filesystem/portable_unistd.h"
namespace filesystem {
std::string GetCurrentDirectory() {
char buffer[PATH_MAX];
if (getcwd(buffer, sizeof(buffer)) == NULL) {
return {};
}
return std::string(buffer);
}
bool IsDirectory(const std::string& path) {
struct stat buf;
if (stat(path.c_str(), &buf) != 0)
return false;
return S_ISDIR(buf.st_mode);
}
bool CreateDirectory(const std::string& full_path) {
std::vector<std::string> subpaths;
// Collect a list of all parent directories.
std::string last_path = full_path;
subpaths.push_back(full_path);
for (std::string path = GetDirectoryName(full_path);
!path.empty() && path != last_path; path = GetDirectoryName(path)) {
subpaths.push_back(path);
last_path = path;
}
// Iterate through the parents and create the missing ones.
for (auto it = subpaths.rbegin(); it != subpaths.rend(); ++it) {
if (IsDirectory(*it))
continue;
if (mkdir(it->c_str(), 0700) == 0)
continue;
// Mkdir failed, but it might be due to the directory appearing out of thin
// air. This can occur if two processes are trying to create the same file
// system tree at the same time. Check to see if it exists and make sure it
// is a directory.
if (!IsDirectory(*it))
return false;
}
return true;
}
} // namespace filesystem