Library: base implementation of temp-dir creation
Inspired by https://stackoverflow.com/a/58454949 Verified behaviour of fs::create_directory --> it returns true only if it ''indeed could create'' a new directory --> it returns false if the directory exists already --> it throws when some other obstacle shows up As an aside: the Header include/limits.h could be cleaned up, and it is used solely from C++ code, thus could be typed, namespaced etc.
This commit is contained in:
parent
b426ea4921
commit
a1832b1cb9
10 changed files with 237 additions and 12 deletions
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
LIMITS.h - hard wired safety limits
|
||||
LIMITS.hpp - hard wired safety limits
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2012, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
|
@ -20,13 +20,15 @@
|
|||
|
||||
*/
|
||||
|
||||
/** @file limits.h
|
||||
|
||||
/** @file limits.hpp
|
||||
** hard wired safety limits.
|
||||
** This tiny header defines some hard limits for indexing, counting, searching
|
||||
** Whenever some task is attempted until success, or in response to external input,
|
||||
** an arbitrary fixed constraint is imposed for indexing, counting, searching
|
||||
** and similar ordinal operations. These limits are a protection against ordinal
|
||||
** and index numbers insanely out-of dimension, like e.g. a symbolic ID with more
|
||||
** than 1000 characters. Whenever an actual allocation is based on such ordinal values,
|
||||
** a tighter and more specific limitation will be enforced on a case by case base
|
||||
** a tighter and more specific limitation will be enforced on a case by case base.
|
||||
**
|
||||
** @see symbol-impl.cpp
|
||||
** @see util::uNum
|
||||
|
|
@ -39,5 +41,6 @@
|
|||
|
||||
#define LUMIERA_IDSTRING_MAX_RELEVANT 1000
|
||||
#define LUMIERA_MAX_ORDINAL_NUMBER 1000
|
||||
#define LUMIERA_MAX_COMPETITION 100
|
||||
|
||||
#endif /*LUMIERA_LIMITS_H*/
|
||||
|
|
@ -85,6 +85,7 @@ namespace lumiera {
|
|||
LUMIERA_ERROR_DEFINE (WRONG_TYPE, "runtime type mismatch");
|
||||
LUMIERA_ERROR_DEFINE (ITER_EXHAUST, "end of sequence reached");
|
||||
LUMIERA_ERROR_DEFINE (CAPACITY, "predefined fixed storage capacity");
|
||||
LUMIERA_ERROR_DEFINE (SAFETY_LIMIT, "exceeding fixed internal safety limit");
|
||||
LUMIERA_ERROR_DEFINE (INDEX_BOUNDS, "index out of bounds");
|
||||
LUMIERA_ERROR_DEFINE (BOTTOM_VALUE, "invalid or NIL value");
|
||||
LUMIERA_ERROR_DEFINE (UNCONNECTED, "missing connection");
|
||||
|
|
|
|||
|
|
@ -182,6 +182,7 @@ namespace lumiera {
|
|||
LUMIERA_ERROR_DECLARE (WRONG_TYPE); ///< runtime type mismatch
|
||||
LUMIERA_ERROR_DECLARE (ITER_EXHAUST); ///< end of sequence reached
|
||||
LUMIERA_ERROR_DECLARE (CAPACITY); ///< predefined fixed storage capacity
|
||||
LUMIERA_ERROR_DECLARE (SAFETY_LIMIT); ///< exceeding fixed internal safety limit
|
||||
LUMIERA_ERROR_DECLARE (INDEX_BOUNDS); ///< index out of bounds
|
||||
LUMIERA_ERROR_DECLARE (BOTTOM_VALUE); ///< invalid or NIL value
|
||||
LUMIERA_ERROR_DECLARE (UNCONNECTED); ///< missing connection
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ namespace util {
|
|||
static std::string
|
||||
invoke (fs::path path) noexcept
|
||||
try {
|
||||
return "\""+std::string{path}+"\"";
|
||||
return "≺"+std::string{path}+"≻";
|
||||
}
|
||||
catch(...)
|
||||
{ return lib::meta::FAILURE_INDICATOR; }
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@
|
|||
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/symbol-table.hpp"
|
||||
#include "include/limits.h"
|
||||
#include "include/limits.hpp"
|
||||
extern "C" {
|
||||
#include "lib/safeclib.h"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,16 +33,49 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/random.hpp"
|
||||
#include "lib/stat/file.hpp"
|
||||
#include "include/limits.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
//#include <unordered_map>
|
||||
//#include <iostream>
|
||||
//#include <vector>
|
||||
#include <string>
|
||||
//#include <map>
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
||||
namespace error = lumiera::error;
|
||||
|
||||
using util::_Fmt;
|
||||
|
||||
namespace {
|
||||
Literal TEMPFILE_PREFIX = "Lux";
|
||||
}
|
||||
inline bool
|
||||
has_perm (fs::path const& p, fs::perms permissionMask)
|
||||
{
|
||||
return (fs::status(p).permissions() & permissionMask) == permissionMask;
|
||||
}
|
||||
inline bool
|
||||
can_read (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_read);
|
||||
}
|
||||
inline bool
|
||||
can_write (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_write);
|
||||
}
|
||||
inline bool
|
||||
can_exec (fs::path const& p)
|
||||
{
|
||||
return has_perm (p, fs::perms::owner_exec);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A RAII style temporary directory.
|
||||
*/
|
||||
|
|
@ -52,14 +85,53 @@ namespace test{
|
|||
fs::path loc_;
|
||||
|
||||
public:
|
||||
TempDir() = default;
|
||||
TempDir()
|
||||
: loc_{establishNewDirectory()}
|
||||
{ }
|
||||
|
||||
~TempDir()
|
||||
{
|
||||
destroyTempDirectory();
|
||||
}
|
||||
|
||||
|
||||
operator fs::path const& () const
|
||||
{
|
||||
return loc_;
|
||||
}
|
||||
|
||||
fs::path
|
||||
makeFile()
|
||||
{
|
||||
UNIMPLEMENTED ("make temporary file");
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
static fs::path
|
||||
establishNewDirectory()
|
||||
{
|
||||
auto tmpDir = fs::temp_directory_path();
|
||||
for (uint attempt=0; attempt<LUMIERA_MAX_COMPETITION; ++attempt)
|
||||
{
|
||||
auto randName = TEMPFILE_PREFIX + util::showHash (entropyGen.u64());
|
||||
auto newPath = tmpDir / randName;
|
||||
// attempt to create it....
|
||||
if (fs::create_directory (newPath)
|
||||
and has_perm (newPath, fs::perms::owner_all)
|
||||
and fs::is_empty (newPath)
|
||||
) // success!
|
||||
return newPath;
|
||||
}
|
||||
throw error::Fatal{_Fmt{"Failed to create unique new TempDir after %d attempts."}
|
||||
% LUMIERA_MAX_COMPETITION
|
||||
,error::LUMIERA_ERROR_SAFETY_LIMIT };
|
||||
}
|
||||
void
|
||||
destroyTempDirectory()
|
||||
{
|
||||
UNIMPLEMENTED ("destroy");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@
|
|||
#ifndef LIB_UTIL_H
|
||||
#define LIB_UTIL_H
|
||||
|
||||
#include "include/limits.h"
|
||||
#include "include/limits.hpp"
|
||||
#include "lib/hash-standard.hpp"
|
||||
|
||||
#include <set>
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "lib/nocopy.hpp"
|
||||
#include "lib/result.hpp"
|
||||
#include "include/limits.h"
|
||||
#include "include/limits.hpp"
|
||||
#include "lib/variant.hpp"
|
||||
#include "lib/meta/typelist-manip.hpp"
|
||||
#include "lib/access-casted.hpp"
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
//#include "lib/error.hpp"
|
||||
//#include "lib/util-foreach.hpp"
|
||||
#include "lib/format-cout.hpp"
|
||||
#include "lib/test/diagnostic-output.hpp"
|
||||
|
||||
//#include <boost/algorithm/string.hpp>
|
||||
#include <fstream>
|
||||
|
|
@ -78,6 +79,24 @@ namespace test{
|
|||
simpleUsage()
|
||||
{
|
||||
TempDir temp;
|
||||
SHOW_EXPR(temp)
|
||||
SHOW_EXPR(fs::path{temp})
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_read));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_write));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_exec));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::owner_all));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_read));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_write));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_exec));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::group_all));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_read));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_write));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_exec));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::others_all));
|
||||
SHOW_EXPR(has_perm(temp, fs::perms::all));
|
||||
SHOW_EXPR(can_read(temp));
|
||||
SHOW_EXPR(can_write(temp));
|
||||
SHOW_EXPR(can_exec(temp));
|
||||
auto ff = temp.makeFile();
|
||||
CHECK (fs::exists (ff));
|
||||
CHECK (fs::is_empty (ff));
|
||||
|
|
|
|||
|
|
@ -57248,19 +57248,148 @@
|
|||
</node>
|
||||
<node CREATED="1710185930891" ID="ID_406086033" MODIFIED="1710185934026" TEXT="Implementierung">
|
||||
<node CREATED="1710185934990" ID="ID_1561994557" LINK="https://stackoverflow.com/a/58454949" MODIFIED="1710186020053" TEXT="Ausgangspunkt: Lösung von Stackoverflow"/>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710186086663" ID="ID_206197040" MODIFIED="1710186142632" TEXT="Zufallserzeugung extrahiert">
|
||||
<node COLOR="#338800" CREATED="1710186086663" ID="ID_206197040" MODIFIED="1710269456216" TEXT="Zufallserzeugung extrahiert">
|
||||
<arrowlink COLOR="#752d90" DESTINATION="ID_588494337" ENDARROW="Default" ENDINCLINATION="33;-54;" ID="Arrow_ID_353980881" STARTARROW="None" STARTINCLINATION="-193;18;"/>
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710188183049" ID="ID_91824274" MODIFIED="1710188192430" TEXT="Allokation">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
<node COLOR="#435e98" CREATED="1710262702973" ID="ID_18843364" MODIFIED="1710266321814" TEXT="Semantik von fs::create_directory ist nicht klar">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
<node CREATED="1710262728032" ID="ID_1183825932" LINK="https://en.cppreference.com/w/cpp/filesystem/create_directory" MODIFIED="1710262791786">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Verstehe die Doku so: wenn directory existiert ⟹ <b>kein</b> Fehler
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1710262793847" ID="ID_921510496" LINK="https://pubs.opengroup.org/onlinepubs/9699919799/functions/mkdir.html" MODIFIED="1710262817664" TEXT="Doku verweist auf POSIX mkdir()">
|
||||
<node CREATED="1710262820691" ID="ID_715729723" MODIFIED="1710262853435" TEXT="dieses erzeugt Fehler EEXIST"/>
|
||||
<node CREATED="1710262854071" ID="ID_1948805301" MODIFIED="1710262901444" TEXT="wobei aber dieser Fall die sonstige Invariante bricht">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
if -1 is returned, no directory shall be created.
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
<node CREATED="1710262914300" ID="ID_1769904987" MODIFIED="1710262918682" TEXT="naja... nicht wirklich"/>
|
||||
<node CREATED="1710262919166" ID="ID_156263596" MODIFIED="1710262926049" TEXT="es existiert, wurde aber nicht created"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1710263014505" ID="ID_470708116" MODIFIED="1710263110225" TEXT="welche Sicherheit kann erziehlt werden?">
|
||||
<node CREATED="1710263043693" ID="ID_328268341" MODIFIED="1710263096296" TEXT="kann ausschließen ein bestehendes Directory zu übernehmen">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
</node>
|
||||
<node CREATED="1710263058838" ID="ID_1049837870" MODIFIED="1710263079639" TEXT="kann nicht verhindern, daß jemand anders unser Directory nachträglich übernimmt">
|
||||
<icon BUILTIN="messagebox_warning"/>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1710263141623" ID="ID_1220074593" MODIFIED="1710266211717" TEXT="fs::create_directory : Verhalten empirisch festgesetellt">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1710265983100" ID="ID_623012849" MODIFIED="1710266027266" TEXT="dir existiert nicht und kann erzeugt werden ⟹ true"/>
|
||||
<node CREATED="1710266029270" ID="ID_20326045" MODIFIED="1710266050247" TEXT="dir existiert bereits (egal ob erzeugt werden kann) ⟹ false"/>
|
||||
<node CREATED="1710266058142" ID="ID_676406433" MODIFIED="1710266085429" TEXT="dir existiert nicht kann aber nicht erzeugt werden ⟹ ��"/>
|
||||
<node CREATED="1710266144038" ID="ID_107534916" MODIFIED="1710266165920" TEXT="parent-dir existiert nicht ⟹ ��"/>
|
||||
</node>
|
||||
<node COLOR="#435e98" CREATED="1710266252824" ID="ID_1948057081" MODIFIED="1710266296643" TEXT="Fazit">
|
||||
<font BOLD="true" NAME="SansSerif" SIZE="12"/>
|
||||
<node BACKGROUND_COLOR="#c8c0b6" CREATED="1710266259400" ID="ID_980650911" MODIFIED="1710266303001" TEXT="hat genau die erwartete/benötigte Semantik"/>
|
||||
<node COLOR="#a2937b" CREATED="1710266276564" ID="ID_1966159866" MODIFIED="1710266313968" TEXT="da haben die Leute im Kommittee mal wieder gut nachgedacht">
|
||||
<font NAME="SansSerif" SIZE="12"/>
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1710269458136" ID="ID_699523271" MODIFIED="1710269879636" TEXT="zufälligen Namen generieren">
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1710269468016" ID="ID_1037664888" MODIFIED="1710269476002" TEXT="Präfix "Lux"">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
<node COLOR="#5b280f" CREATED="1710269492723" ID="ID_1309550796" MODIFIED="1710269498577" TEXT="noch die PID einbauen?">
|
||||
<icon BUILTIN="button_cancel"/>
|
||||
<node CREATED="1710269499810" ID="ID_358382158" LINK="https://stackoverflow.com/q/50086895" MODIFIED="1710269522742" TEXT="Konzept »Prozess« ist nicht portabel"/>
|
||||
<node CREATED="1710269523471" ID="ID_970699149" MODIFIED="1710269534326" TEXT="man könnte POSIX getpid() verwenden..."/>
|
||||
<node CREATED="1710269534846" ID="ID_705812768" MODIFIED="1710269721624" TEXT="wozu....? welches Risiko?">
|
||||
<richcontent TYPE="NOTE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
ja man könnte.... aber welches Risiko soll damit adressiert werden (da es ja nun doch zusätzliche Kosten in der Form von Nonportabilität beinhaltet)? Immerhin ist die ganze Sache mit den Zufallszahlen sowiso mehr oder weniger professionelle Paranoia, denn 2^64 ~ 10^19 ist schon eine Menge
|
||||
</p>
|
||||
<p>
|
||||
⟹ <font size="5" color="#ca0992">JAGNI</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1710269734115" ID="ID_536611603" MODIFIED="1710269883844" TEXT="Zufallszahl als Hex">
|
||||
<icon BUILTIN="idea"/>
|
||||
<node CREATED="1710269741378" ID="ID_1044233602" LINK="#ID_1334461494" MODIFIED="1710269822240">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
die gestern implementierte Zufalls-Sequenz <font face="Monospaced" color="#2216ba">entropyGen.u64()</font>
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
</richcontent>
|
||||
</node>
|
||||
<node CREATED="1710269833165" ID="ID_1640785265" MODIFIED="1710269871853" TEXT="das util::showHash() von vor zwei Monaten">
|
||||
<icon BUILTIN="ksmiletris"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node COLOR="#338800" CREATED="1710269892325" ID="ID_226025075" MODIFIED="1710269926842">
|
||||
<richcontent TYPE="NODE"><html>
|
||||
<head>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<p>
|
||||
Rückgabewert von create_directory
|
||||
</p>
|
||||
<p>
|
||||
+ weitere Eigenschaften prüfen
|
||||
</p>
|
||||
</body>
|
||||
</html></richcontent>
|
||||
<icon BUILTIN="button_ok"/>
|
||||
<node CREATED="1710269928521" ID="ID_1272555016" MODIFIED="1710269946386" TEXT="ohh... Extrahieren von Permissions ist aber mühsam">
|
||||
<icon BUILTIN="smiley-angry"/>
|
||||
</node>
|
||||
<node CREATED="1710269947604" ID="ID_1418089221" MODIFIED="1710269962399" TEXT="Hilfsfunktion hierfür ⟶ file.hpp"/>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1710188193120" ID="ID_988204568" MODIFIED="1710188200824" TEXT="Destruktion">
|
||||
<icon BUILTIN="flag-yellow"/>
|
||||
</node>
|
||||
</node>
|
||||
<node CREATED="1710269985121" ID="ID_1475343702" MODIFIED="1710269987814" TEXT="Test">
|
||||
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1710269988763" ID="ID_1423252413" LINK="#ID_992572632" MODIFIED="1710270061936" TEXT="Test für TempDir">
|
||||
<icon BUILTIN="pencil"/>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1710186076931" ID="ID_1533745732" MODIFIED="1710186080916" TEXT="Zufallszahlen">
|
||||
<node BACKGROUND_COLOR="#fdfdcf" COLOR="#ff0000" CREATED="1710270007654" ID="ID_1049869933" MODIFIED="1710270065664" TEXT="Abdeckung einiger Filesystem-Zusatzfunktionen">
|
||||
<icon BUILTIN="flag-pink"/>
|
||||
</node>
|
||||
</node>
|
||||
</node>
|
||||
<node BACKGROUND_COLOR="#d2beaf" COLOR="#5c4d6e" CREATED="1710186076931" FOLDED="true" ID="ID_1533745732" MODIFIED="1710269829568" TEXT="Zufallszahlen">
|
||||
<icon BUILTIN="hourglass"/>
|
||||
<node COLOR="#435e98" CREATED="1710186100840" ID="ID_588494337" MODIFIED="1710206947117" TEXT="erst mal Stanard-Lösungen sammeln">
|
||||
<arrowlink COLOR="#5c6fbb" DESTINATION="ID_1793624210" ENDARROW="Default" ENDINCLINATION="-1371;142;" ID="Arrow_ID_573303638" STARTARROW="None" STARTINCLINATION="-2119;146;"/>
|
||||
|
|
|
|||
Loading…
Reference in a new issue