1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#pragma once
///@file

#include "lix/libstore/gc-store.hh"
#include "lix/libutil/args.hh"
#include "lix/libutil/args/root.hh"
#include "lix/libmain/common-args.hh"
#include "lix/libstore/path.hh"
#include "lix/libstore/derived-path.hh"
#include "lix/libutil/processes.hh"
#include "lix/libutil/strings.hh"

#include <kj/function.h>

namespace nix {

int handleExceptions(const std::string & programName, std::function<int()> fun);

/**
 * Don't forget to call initPlugins() after settings are initialized!
 */
void initNix();

void printVersion(const std::string & programName);

/**
 * Ugh.  No better place to put this.
 */
void printGCWarning();

class Store;

kj::Promise<Result<void>> printMissing(
    ref<Store> store,
    const std::vector<DerivedPath> & paths,
    Verbosity lvl = lvlInfo);

kj::Promise<Result<void>> printMissing(ref<Store> store, const StorePathSet & willBuild,
    const StorePathSet & willSubstitute, const StorePathSet & unknown,
    uint64_t downloadSize, uint64_t narSize, Verbosity lvl = lvlInfo);

std::string getArg(const std::string & opt,
    Strings::iterator & i, const Strings::iterator & end);

template<class N> N getIntArg(const std::string & opt,
    Strings::iterator & i, const Strings::iterator & end, bool allowUnit)
{
    ++i;
    if (i == end) throw UsageError("'%1%' requires an argument", opt);
    return string2IntWithUnitPrefix<N>(*i);
}


struct LegacyArgs : public MixCommonArgs, public RootArgs
{
    AsyncIoRoot & aio_;
    AsyncIoRoot & aio() override { return aio_; }

    std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg;

    LegacyArgs(AsyncIoRoot & aio, const std::string & programName,
        std::function<bool(Strings::iterator & arg, const Strings::iterator & end)> parseArg);

    bool processFlag(Strings::iterator & pos, Strings::iterator end) override;

    bool processArgs(const Strings & args, bool finish) override;
};


/**
 * Show the manual page for the specified program.
 */
void showManPage(const std::string & name);

/**
 * Represents a running pager if paging is available, or stdout if not.
 */
class Pager
{
protected:
    Pager() = default;

public:
    /**
     * Writes some data to the pager (or stdout). Only the provided data
     * is written, with no newlines are added or any formatting applied.
     */
    virtual Pager & operator<<(std::string_view data) = 0;
};

/**
 * Starts a pager if standard output is a terminal and $PAGER is set. The
 * pager is provided as an argument to the callback; only data written to
 * that object will be sent to the pager program. If no pager is started,
 * e.g. if $PAGER is cleared, the pager object writes directly to stdout.
 */
void withPager(kj::Function<void(Pager &)> fn);

/* GC helpers. */

std::string showBytes(uint64_t bytes);

struct GCResults;

struct PrintFreed
{
    GCOptions::GCAction action;

    const GCResults & results;
    PrintFreed(GCOptions::GCAction action, const GCResults & results)
        : action(action)
        , results(results)
    {
    }
    ~PrintFreed();
};


/**
 * Install a SIGSEGV handler to detect stack overflows. See also registerCrashHandler().
 */
void detectStackOverflow();

/**
 * Pluggable behavior to run in case of a stack overflow.
 *
 * Default value: defaultStackOverflowHandler.
 *
 * This is called by the handler installed by detectStackOverflow().
 *
 * This gives Lix library consumers a limit opportunity to report the error
 * condition. The handler should exit the process.
 * See defaultStackOverflowHandler() for a reference implementation.
 *
 * NOTE: Use with diligence, because this runs in the signal handler, with very
 * limited stack space and a potentially a corrupted heap, all while the failed
 * thread is blocked indefinitely. All functions called must be reentrant.
 */
extern std::function<void(siginfo_t * info, void * ctx)> stackOverflowHandler;

/**
 * The default, robust implementation of stackOverflowHandler.
 *
 * Prints an error message directly to stderr using a syscall instead of the
 * logger. Exits the process immediately after.
 */
void defaultStackOverflowHandler(siginfo_t * info, void * ctx);

}