Stroika Library 3.0d25
 
Loading...
Searching...
No Matches
Module.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Execution_Module_h_
5#define _Stroika_Foundation_Execution_Module_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <array>
10#include <cstdint>
11#include <filesystem>
12#include <optional>
13#include <span>
14
15#if qStroika_Platform_POSIX
16#include <unistd.h>
17#endif
18
19#include "Stroika/Foundation/Characters/SDKString.h"
20#include "Stroika/Foundation/Common/Common.h"
21#include "Stroika/Foundation/Common/Property.h"
22#include "Stroika/Foundation/Containers/Mapping.h"
23#include "Stroika/Foundation/Containers/Sequence.h"
24#include "Stroika/Foundation/Execution/LazyInitialized.h"
25
27
28#if qStroika_Platform_POSIX
29 using pid_t = ::pid_t;
30#elif qStroika_Platform_Windows
31 using pid_t = DWORD;
32#else
33 using pid_t = int;
34#endif
35
36 /**
37 * The directory where the executable that is running this code is located. If this code is compiled into a DLL,
38 * this returns the executable directory for the underlying process/executable (not the DLL/so file).
39 */
40 filesystem::path GetEXEDir ();
41
42 /**
43 * The path where the executable that is running this code is located. If this code is compiled into a DLL,
44 * this returns the executable for the underlying process/executable (not the DLL/so file).
45 */
46 filesystem::path GetEXEPath ();
47
48 /**
49 * Return the full path to the given process (throws if not found).
50 *
51 * NYI for WINDOWS.
52 */
53 filesystem::path GetEXEPath (pid_t processID);
54
55 /**
56 * \brief Is all of s in memory that is read-only for as long as the program runs - so a pointer into it may be kept, rather
57 * than its bytes copied?
58 *
59 * That memory is the main executable's read-only image, where its string literals and other constant data are (and
60 * Stroika's own, since Stroika is linked statically). Another module's read-only image does not count: it can be unloaded.
61 *
62 * \returns true if so; false if not - s may yet be read-only (another module's, or a read-only mapping) but nothing promises
63 * it lasts; nullopt if Stroika cannot tell on this platform (it can on Linux, MacOS and Windows). An empty s is false.
64 *
65 * Cheap: a few comparisons, once the image has been examined (at first use).
66 */
67 optional<bool> IsAddressReadOnlyAppLifetime (span<const byte> s);
68
69 /**
70 * The set of system locations to look for an executable (note order matters, which is why this is a Sequence)
71 */
72 extern const LazyInitialized<Containers::Sequence<filesystem::path>> kPath;
73
74#if qStroika_Platform_Windows
75 /**
76 * The set of system extensions to try for a given file to see if its an executable (note order matters, which is why this is a Sequence)
77 *
78 * https://wiki.tcl-lang.org/page/PATHEXT
79 */
80 extern const LazyInitialized<Containers::Sequence<filesystem::path>> kPathEXT;
81#endif
82
83 /**
84 * \brief convert getenv() to a Mapping of SDKString (in case some issue with charactor set conversion)
85 *
86 * \note LazyInitialized so if not used, nearly zero cost
87 */
88 extern const LazyInitialized<Containers::Mapping<Characters::SDKString, Characters::SDKString>> kRawEnvironment;
89
90 /**
91 * \brief convert getenv() to a Mapping of Strings for easier access
92 *
93 * \note LazyInitialized so if not used, nearly zero cost
94 */
95 extern const LazyInitialized<Containers::Mapping<Characters::String, Characters::String>> kEnvironment;
96
97 /**
98 * \brief If fn refers to an executable - return it (using kPATH, and kPathEXT as appropriate)
99 *
100 * If fn is an absolute path, use that (possibly with suffixes appended).
101 * If fn is not absolute, try appending it to each path from kPATH, and redo
102 * same check.
103 *
104 * On Windows, if ext is missing, also check kPathEXT
105 *
106 * If no matches, return nullopt.
107 *
108 * \par Example Usage
109 * \code
110 * if (optional<filesystem::path> pp = FindExecutableInPath ("bash"sv)) {
111 * fArgs_ += String{*pp};
112 * }
113 * else {
114 * Throw (IO::FileSystem::Exception{make_error_code (errc::no_such_file_or_directory), filesystem::path{"bash"sv}});
115 * }
116 * \endcode
117 */
118 optional<filesystem::path> FindExecutableInPath (const filesystem::path& fn);
119
120}
121
122/*
123 ********************************************************************************
124 ***************************** Implementation Details ***************************
125 ********************************************************************************
126 */
127#include "Module.inl"
128
129#endif /*_Stroika_Foundation_Execution_Module_h_*/
optional< bool > IsAddressReadOnlyAppLifetime(span< const byte > s)
Is all of s in memory that is read-only for as long as the program runs - so a pointer into it may be...
Definition Module.inl:23
const LazyInitialized< Containers::Mapping< Characters::String, Characters::String > > kEnvironment
convert getenv() to a Mapping of Strings for easier access
Definition Module.cpp:323
const LazyInitialized< Containers::Sequence< filesystem::path > > kPath
Definition Module.cpp:235
const LazyInitialized< Containers::Mapping< Characters::SDKString, Characters::SDKString > > kRawEnvironment
convert getenv() to a Mapping of SDKString (in case some issue with charactor set conversion)
Definition Module.cpp:271
filesystem::path GetEXEDir()
Definition Module.cpp:47
optional< filesystem::path > FindExecutableInPath(const filesystem::path &fn)
If fn refers to an executable - return it (using kPATH, and kPathEXT as appropriate)
Definition Module.cpp:336
filesystem::path GetEXEPath()
Definition Module.cpp:57