| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- // Filename: mkdir_complete.cxx
- // Created by: drose (29Jun09)
- //
- ////////////////////////////////////////////////////////////////////
- //
- // PANDA 3D SOFTWARE
- // Copyright (c) Carnegie Mellon University. All rights reserved.
- //
- // All use of this software is subject to the terms of the revised BSD
- // license. You should have received a copy of this license along
- // with this source code in a file named "LICENSE."
- //
- ////////////////////////////////////////////////////////////////////
- #include "mkdir_complete.h"
- #ifdef _WIN32
- #include <windows.h>
- #else
- #include <fcntl.h>
- #include <sys/stat.h> // for mkdir()
- #include <errno.h>
- #endif
- ////////////////////////////////////////////////////////////////////
- // Function: get_dirname
- // Description: Returns the directory component of the indicated
- // pathname, or the empty string if there is no
- // directory prefix.
- ////////////////////////////////////////////////////////////////////
- static string
- get_dirname(const string &filename) {
- size_t p = filename.length();
- while (p > 0) {
- --p;
- if (is_pathsep(filename[p])) {
- return filename.substr(0, p);
- }
- }
- return string();
- }
- ////////////////////////////////////////////////////////////////////
- // Function: mkdir_complete
- // Description: Creates a new directory, with normal access
- // privileges. Returns true on success, false on
- // failure. Will create intervening directories if
- // necessary.
- ////////////////////////////////////////////////////////////////////
- bool
- mkdir_complete(const string &dirname) {
- #ifdef _WIN32
- if (CreateDirectory(dirname.c_str(), NULL) != 0) {
- // Success!
- return true;
- }
- // Failed.
- DWORD last_error = GetLastError();
- if (last_error == ERROR_ALREADY_EXISTS) {
- // Not really an error: the directory is already there.
- return true;
- }
- if (last_error == ERROR_PATH_NOT_FOUND) {
- // We need to make the parent directory first.
- string parent = get_dirname(dirname);
- if (!parent.empty() && mkdir_complete(parent)) {
- // Parent successfully created. Try again to make the child.
- if (CreateDirectory(dirname.c_str(), NULL) != 0) {
- // Got it!
- return true;
- }
- }
- }
- return false;
- #else //_WIN32
- if (mkdir(dirname.c_str(), 0777) == 0) {
- // Success!
- return true;
- }
- // Failed.
- if (errno == EEXIST) {
- // Not really an error: the directory is already there.
- return true;
- }
- if (errno == ENOENT) {
- // We need to make the parent directory first.
- string parent = get_dirname(dirname);
- if (!parent.empty() && mkdir_complete(parent)) {
- // Parent successfully created. Try again to make the child.
- if (mkdir(dirname.c_str(), 0777) == 0) {
- // Got it!
- return true;
- }
- }
- }
- return false;
- #endif // _WIN32
- }
- ////////////////////////////////////////////////////////////////////
- // Function: mkfile_complete
- // Description: Creates a new file with normal access
- // priviledges. Returns true on success, false on
- // failure. This will create intervening directories if
- // needed.
- ////////////////////////////////////////////////////////////////////
- bool
- mkfile_complete(const string &filename) {
- #ifdef _WIN32
- HANDLE file = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- if (file == INVALID_HANDLE_VALUE) {
- // Try to make the parent directory first.
- string parent = get_dirname(filename);
- if (!parent.empty() && mkdir_complete(parent)) {
- // Parent successfully created. Try again to make the file.
- file = CreateFile(filename.c_str(), GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
- }
- if (file == INVALID_HANDLE_VALUE) {
- return false;
- }
- }
- CloseHandle(file);
- return true;
- #else // _WIN32
- int fd = creat(filename.c_str(), 0777);
- if (fd == -1) {
- // Try to make the parent directory first.
- string parent = get_dirname(filename);
- if (!parent.empty() && mkdir_complete(parent)) {
- // Parent successfully created. Try again to make the file.
- fd = creat(filename.c_str(), 0777);
- }
- if (fd == -1) {
- return false;
- }
- }
- close(fd);
- return true;
- #endif // _WIN32
- }
|