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
|
#pragma once
///@file
#include "lix/libutil/error.hh"
#include "lix/libutil/generator.hh"
#include <sys/resource.h>
namespace nix {
struct Sink;
struct Source;
/**
* Return the limit of open files on this system.
*/
rlimit getOpenFilesLimit();
/**
* Read a line from a file descriptor.
*/
std::string readLine(int fd);
/**
* Read the contents of a file into a string.
*/
std::string readFile(int fd);
/**
* Wrappers arount read()/write() that read/write exactly the
* requested number of bytes.
*/
void readFull(int fd, char * buf, size_t count);
void writeFull(int fd, std::string_view s, bool allowInterrupts = true);
/**
* Read a file descriptor until EOF occurs.
*/
std::string drainFD(int fd, bool block = true, const size_t reserveSize=0);
/*
* Will attempt to guess *A* path associated that might lead to the same file as used by this
* file descriptor.
*
* The returned string should NEVER be used as a valid path.
*/
std::string guessOrInventPathFromFD(int fd);
Generator<Bytes> drainFDSource(int fd, bool block = true);
class AutoCloseFD
{
int fd;
public:
AutoCloseFD();
explicit AutoCloseFD(int fd);
AutoCloseFD(const AutoCloseFD & fd) = delete;
AutoCloseFD(AutoCloseFD&& fd);
~AutoCloseFD();
AutoCloseFD& operator =(const AutoCloseFD & fd) = delete;
AutoCloseFD& operator =(AutoCloseFD&& fd) noexcept(false);
int get() const;
/*
* Will attempt to guess *A* path associated that might lead to the same file as used by this
* file descriptor.
*
* The returned string should NEVER be used as a valid path.
*/
std::string guessOrInventPath() const { return guessOrInventPathFromFD(fd); }
explicit operator bool() const;
int release();
void close();
void fsync();
void reset() { *this = {}; }
};
class Pipe
{
public:
AutoCloseFD readSide, writeSide;
void create();
void close();
};
struct SocketPair
{
/** The two sides of the socket pair. */
AutoCloseFD a, b;
/** Create a unix stream socket pair with the `O_CLOEXEC` set on both ends. */
static SocketPair stream();
private:
SocketPair(AutoCloseFD a, AutoCloseFD b) : a(std::move(a)), b(std::move(b)) {}
};
/**
* Set or clear the close-on-exec flag for the given file descriptor.
*/
void closeOnExec(int fd, bool doClose = true);
enum class FdBlockingState : int {};
/**
* Make the given file descriptor non-blocking. Returns the old flag set; this
* can be passed to resetBlockingState to return the fd to its original state.
*/
FdBlockingState makeNonBlocking(int fd);
/**
* Make the given file descriptor blocking. Returns the old flag set; it can
* be passed to `resetBlockingState` to return the fd to its original state.
*/
FdBlockingState makeBlocking(int fd);
/**
* Undo a `makeNonBlocking` or `makeBlocking` call.
*/
void resetBlockingState(int fd, FdBlockingState prevState);
MakeError(EndOfFile, Error);
}
|