#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2023 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License #ifndef NUCLEX_SUPPORT_PLATFORM_POSIXPROCESSAPI_H #define NUCLEX_SUPPORT_PLATFORM_POSIXPROCESSAPI_H #include "Nuclex/Support/Config.h" #if !defined(NUCLEX_SUPPORT_WINDOWS) #include "PosixApi.h" #include // for assert() #include // for std::chrono::milliseconds #include // for ::pid_t namespace Nuclex { namespace Support { namespace Platform { // ------------------------------------------------------------------------------------------- // /// Sets up a pipe that can be used for inter-process communication class Pipe { /// Opens a new pipe public: Pipe(); /// Closes whatever end(s) of the pipe have not been used yet public: ~Pipe(); /// Closes one end of the pipe /// Which end of the pipe to close public: void CloseOneEnd(int whichEnd); /// Relinquishes ownership of the file number for one end of the pipe /// For which end of the pipe ownership will be released /// The file number of the relinquished end of the pipe public: int ReleaseOneEnd(int whichEnd); /// Enabled non-blocking IO for one end of the pipe /// For which end non-blocking IO will be enabled public: void SetEndNonBlocking(int whichEnd); /// Fetches the file number of one end of the pipe /// /// Index of the pipe end (0 or 1) whose file number will be returned /// /// The file number for the requested end of the pipe public: int GetOneEnd(int whichEnd) const { assert(((whichEnd == 0) || (whichEnd == 1)) && u8"whichEnd is either 0 or 1"); return this->ends[whichEnd]; } /// File numbers for each end of the pipe private: int ends[2]; }; // ------------------------------------------------------------------------------------------- // /// Wraps the Posix process and inter-process communication API class PosixProcessApi { /// Sends the SIGTERM signal to the process, requesting it to exit /// Id of the process that will be requested to quit /// /// This is the nice way of asking a process to exit. If the process does not /// explicitly handle SIGTERM, it will be caught by its standard library and usually /// do the equivalent of an ::exit(1). /// public: static void RequestProcessTermination(::pid_t processId); /// Sends the SIGKILL signal to the process to end it forcefully /// Id of the process that will be killed /// /// SIGKILL cannot be ignored by the process and will kill it (if the caller has /// sufficient rights). Only use this as a last resort. /// public: static void KillProcess(::pid_t processId); /// Determines the path of the running executable /// Target string to store the executable path in public: static void GetOwnExecutablePath(std::string &target); /// Locates an executable by emulating the search of ::LoadLibrary() /// Target string to store the executable path in /// Executable, with or without path /// /// /// Posix' exec*() methods already have a well-defined search order (use the PATH /// environment variable unless the string contains a slash, in which case it's /// relative to the current working directory), but we want to alter it slightly /// to offer consistent behavior on both Linux and Windows /// /// /// Namely, the running application's own install directory should be search first /// for any executables that do not contain a path (or a relative path). /// This method guarantees that behavior by looking in the directory holding /// the running application's executable and only then fall back to Posix behavior. /// /// public: static void GetAbsoluteExecutablePath( std::string &target, const std::string &executable ); /// Determines the absolute path of the working directory /// String into which the working directory will be written /// Working directory as specified by the user /// /// This either keeps the working directory as-is (if it's an absolute path) or /// interprets it relative to the executable's path for consistent behavior. /// public: static void GetAbsoluteWorkingDirectory( std::string &target, const std::string &workingDirectory ); /// Searches for an executable using the PATH environment variable /// String into which the absolute path will be written /// Relative path to the executable that will be searched private: static void searchExecutableInPath( std::string &target, const std::string &executable ); }; // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Support::Platform #endif // !defined(NUCLEX_SUPPORT_WINDOWS) #endif // NUCLEX_SUPPORT_PLATFORM_POSIXPROCESSAPI_H