Мова піде про винахід колеса для кожного окремого воза. Вкотре знадобилася функція, яка б виконувала 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:
Немає коментарів:
Дописати коментар