diff options
| author | Lexi Winter <lexi@le-fay.org> | 2025-07-02 00:33:19 +0100 |
|---|---|---|
| committer | Lexi Winter <lexi@le-fay.org> | 2025-07-02 00:33:19 +0100 |
| commit | 8c9688fff4446a1b0f5fe9a9be0c50084726cc4d (patch) | |
| tree | ca9a10be5795d976c0cbc73ad1111517bb4e22bf /nihil.posix/progname.ccm | |
| parent | 47999457e647352ae7e71d43c65e7b39ae5ca567 (diff) | |
| download | nihil-8c9688fff4446a1b0f5fe9a9be0c50084726cc4d.tar.gz nihil-8c9688fff4446a1b0f5fe9a9be0c50084726cc4d.tar.bz2 | |
CLI cleanups; fix the FreeBSD build
Diffstat (limited to 'nihil.posix/progname.ccm')
| -rw-r--r-- | nihil.posix/progname.ccm | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/nihil.posix/progname.ccm b/nihil.posix/progname.ccm new file mode 100644 index 0000000..127b972 --- /dev/null +++ b/nihil.posix/progname.ccm @@ -0,0 +1,68 @@ +// This source code is released into the public domain. +module; + +// progname: wrappers for getprogname and setprogname. +// +// setprogname() doesn't copy the provided name, which makes it awkward to provide +// dynamic values (e.g., std::string). We solve this by making setprogname a guard +// object which resets the previous progname when it's destroyed. This also happens +// to be useful in cases like nihil.cli where we want to temporarily set the progname. + +#include <stdlib.h> // NOLINT + +export module nihil.posix:progname; + +import nihil.std; + +namespace nihil { + +// Get the current program name. We could return std::string_view here, but since +// the current program name can change unexpectedly, we don't. +export [[nodiscard]] auto getprogname() -> std::optional<std::string> +{ + if (auto const *progname = ::getprogname(); progname != nullptr) + return {progname}; + return {}; +} + +// Set the progname name to a new value for the lifetime of this object. +// Reset it to the previous value when the object is destroyed. +export struct setprogname final +{ + // Set the program name. + explicit setprogname(std::string_view const progname) + : m_progname(progname) + , m_old_progname(::getprogname()) + { + ::setprogname(m_progname.data()); + } + + // Restore the old name on destruction. + ~setprogname() + { + if (m_old_progname != nullptr) + ::setprogname(m_old_progname); + } + + // Restore the old program name immediately. + auto release() -> void + { + if (m_old_progname != nullptr) { + ::setprogname(m_old_progname); + m_old_progname = nullptr; + } + } + + // Not copyable. + setprogname(setprogname const &) = delete; + auto operator=(setprogname const &) -> setprogname & = delete; + + // Not movable. + setprogname(setprogname &&) = delete; + auto operator=(setprogname &&) -> setprogname & = delete; + +private: + std::string m_progname; + char const *m_old_progname; +}; +} // namespace nihil |
