Мова піде про винахід колеса для кожного окремого воза. Вкотре знадобилася функція, яка б виконувала mkdir -p, тобто рекурсивно створювала директорії по заданому шляху. mkdir(2) справляється тільки тоді, коли всі батьківські директорії вже існують, а нам саме треба створити бракуючі.
Найдоступніші замінники:
system ("mkdir -p a/b/c/d")
Для простої операції створює процес оболонки, а та ще один для mkdir — зажирно.
boost::filesystem::create_directories ("a/b/c/d")
Цей тягне за собою не потрібну ні для чого іншого бібліотеку, жаба душить. Крім того, немає можливості задати права доступу до нових каталогів.
Ретельніший пошук показав, що у світі Unix кожен сам собі пише потрібну приблуду. А раз так, то й я не хотів зостатися осторонь. Нічого в ній особливого немає, тому прошу смакувати (C++):
// // Mkdir.cc // // Created: 21.04.2010 // Author: A. Sakhnik // #include "Mkdir.hh" #include <fcntl.h> #include <errno.h> #include <string> #include <syslog.h> using namespace std; static int mkdir_if_missing (char const* path, mode_t mode) { struct stat buf; if (-1 != ::lstat (path, &buf)) { if (S_ISDIR (buf.st_mode)) return 0; // The path is a directory, OK errno = ENOTDIR; return -1; // The path exists, and isn't a directory } if (errno != ENOENT) return -1; // Something bad happened if (-1 == ::mkdir (path, mode)) return -1; // Wasn't able to create the directory return 0; // We were lucky enough indeed } // Create directory recursively int mkdir_p (char const* path, mode_t mode) { string parents; // Partial paths a, a/b, a/b/c etc for (const char *next = strchr (path, '/'), *prev = path; next; prev = next, next = strchr (next + 1, '/')) { parents.insert (parents.end(), prev, next); // Consider next component if (parents.empty()) continue; // Omit root directory for absolute path if (-1 == mkdir_if_missing (parents.c_str(), mode)) return -1; } return mkdir_if_missing (path, mode); // Create final component } // vim: set et ts=4 sw=4:
Немає коментарів:
Дописати коментар