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:
Fischlurch 2024-03-12 20:14:29 +01:00
parent b426ea4921
commit a1832b1cb9
10 changed files with 237 additions and 12 deletions

View file

@ -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*/

View file

@ -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");

View file

@ -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

View file

@ -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; }

View file

@ -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"
}

View file

@ -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");
}
};

View file

@ -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>

View file

@ -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"

View file

@ -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));

View file

@ -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&#xf6;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 &#10233; <b>kein</b>&#160;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&#xdf;en ein bestehendes Directory zu &#xfc;bernehmen">
<icon BUILTIN="button_ok"/>
</node>
<node CREATED="1710263058838" ID="ID_1049837870" MODIFIED="1710263079639" TEXT="kann nicht verhindern, da&#xdf; jemand anders unser Directory nachtr&#xe4;glich &#xfc;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 &#x27f9; true"/>
<node CREATED="1710266029270" ID="ID_20326045" MODIFIED="1710266050247" TEXT="dir existiert bereits (egal ob erzeugt werden kann) &#x27f9; false"/>
<node CREATED="1710266058142" ID="ID_676406433" MODIFIED="1710266085429" TEXT="dir existiert nicht kann aber nicht erzeugt werden &#x27f9; &#xd83d;&#xddf2;"/>
<node CREATED="1710266144038" ID="ID_107534916" MODIFIED="1710266165920" TEXT="parent-dir existiert nicht &#x27f9; &#xd83d;&#xddf2;"/>
</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&#xf6;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&#xe4;lligen Namen generieren">
<icon BUILTIN="button_ok"/>
<node CREATED="1710269468016" ID="ID_1037664888" MODIFIED="1710269476002" TEXT="Pr&#xe4;fix &quot;Lux&quot;">
<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 &#xbb;Prozess&#xab; ist nicht portabel"/>
<node CREATED="1710269523471" ID="ID_970699149" MODIFIED="1710269534326" TEXT="man k&#xf6;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&#246;nnte.... aber welches Risiko soll damit adressiert werden (da es ja nun doch zus&#228;tzliche Kosten in der Form von Nonportabilit&#228;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>
&#10233; <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&#252;ckgabewert von create_directory
</p>
<p>
+ weitere Eigenschaften pr&#252;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&#xfc;hsam">
<icon BUILTIN="smiley-angry"/>
</node>
<node CREATED="1710269947604" ID="ID_1418089221" MODIFIED="1710269962399" TEXT="Hilfsfunktion hierf&#xfc;r &#x27f6; 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&#xfc;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&#xf6;sungen sammeln">
<arrowlink COLOR="#5c6fbb" DESTINATION="ID_1793624210" ENDARROW="Default" ENDINCLINATION="-1371;142;" ID="Arrow_ID_573303638" STARTARROW="None" STARTINCLINATION="-2119;146;"/>