Files
lix/src/libutil/processes.hh
T
Lulu 43e79f4434 Fix gcc warning -Wmissing-field-initializers
The approach that was taken here was to add default values to the type
definitions rather than specify them whenever they are missing.

Now the only remaining warning is '-Wunused-parameter' which @jade said
is usually counterproductive and that we can just disable it:
https://git.lix.systems/lix-project/lix/issues/456#issuecomment-6617

So this change adds the flags '-Wall', '-Wextra' and
'-Wno-unused-parameter', so that all warnings are enabled except for
'-Wunused-parameter'.

Change-Id: Ic223a964d67ab429e8da804c0721ba5e25d53012
2024-10-08 01:44:38 +00:00

136 lines
2.8 KiB
C++

#pragma once
///@file
#include "types.hh"
#include "error.hh"
#include "file-descriptor.hh"
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <unistd.h>
#include <signal.h>
#include <functional>
#include <map>
#include <optional>
namespace nix {
struct Sink;
struct Source;
class Pid
{
pid_t pid = -1;
bool separatePG = false;
int killSignal = SIGKILL;
public:
Pid();
explicit Pid(pid_t pid): pid(pid) {}
Pid(Pid && other);
Pid & operator=(Pid && other);
~Pid() noexcept(false);
explicit operator bool() const { return pid != -1; }
int kill();
int wait();
void setSeparatePG(bool separatePG);
void setKillSignal(int signal);
pid_t release();
pid_t get() const { return pid; }
};
/**
* Kill all processes running under the specified uid by sending them
* a SIGKILL.
*/
void killUser(uid_t uid);
/**
* Fork a process that runs the given function, and return the child
* pid to the caller.
*/
struct ProcessOptions
{
std::string errorPrefix = "";
bool dieWithParent = true;
bool runExitHandlers = false;
/**
* use clone() with the specified flags (Linux only)
*/
int cloneFlags = 0;
};
[[nodiscard]]
Pid startProcess(std::function<void()> fun, const ProcessOptions & options = ProcessOptions());
/**
* Run a program and return its stdout in a string (i.e., like the
* shell backtick operator).
*/
std::string runProgram(Path program, bool searchPath = false,
const Strings & args = Strings(), bool isInteractive = false);
struct RunOptions
{
Path program;
bool searchPath = true;
Strings args = {};
std::optional<uid_t> uid = {};
std::optional<uid_t> gid = {};
std::optional<Path> chdir = {};
std::optional<std::map<std::string, std::string>> environment = {};
bool captureStdout = false;
bool mergeStderrToStdout = false;
bool isInteractive = false;
};
struct [[nodiscard("you must call RunningProgram::wait()")]] RunningProgram
{
friend RunningProgram runProgram2(const RunOptions & options);
private:
Path program;
Pid pid;
std::unique_ptr<Source> stdoutSource;
AutoCloseFD stdout_;
RunningProgram(PathView program, Pid pid, AutoCloseFD stdout);
public:
RunningProgram() = default;
~RunningProgram();
void wait();
Source * getStdout() const { return stdoutSource.get(); };
};
std::pair<int, std::string> runProgram(RunOptions && options);
RunningProgram runProgram2(const RunOptions & options);
class ExecError : public Error
{
public:
int status;
template<typename... Args>
ExecError(int status, const Args & ... args)
: Error(args...), status(status)
{ }
};
/**
* Convert the exit status of a child as returned by wait() into an
* error string.
*/
std::string statusToString(int status);
bool statusOk(int status);
}