9 #include "baseproc-sys.h"
13 std::vector<bool> usedfds = {true, true, true};
17 read_result(int errcode_p) : errcode(errcode_p) {}
19 read_result(std::vector<char> &data_p) : errcode(0), data(data_p) {}
20 read_result(std::vector<char> &&data_p) : errcode(0), data(std::move(data_p)) {}
22 int errcode; // errno return
23 std::vector<char> data; // data (if errcode == 0)
26 class read_cond : public std::vector<read_result>
29 using vector<read_result>::vector;
31 // if blocking, return EAGAIN rather than end-of-file:
32 bool is_blocking = false;
35 // map of fd to read results to supply for reads of that fd
36 std::map<int,read_cond> read_data;
38 // map of data written to each fd
39 std::map<int,std::vector<char>> written_data;
45 int last_sig_sent = -1; // last signal number sent, accessible for tests.
46 pid_t last_forked_pid = 1; // last forked process id (incremented each 'fork')
48 // Test helper methods:
50 // Allocate a file descriptor
53 auto f = std::find(usedfds.begin(), usedfds.end(), false);
54 if (f == usedfds.end()) {
55 int r = usedfds.size();
56 usedfds.push_back(true);
61 return f - usedfds.begin();
64 // Supply data to be returned by read()
65 void supply_read_data(int fd, std::vector<char> &data)
67 read_data[fd].emplace_back(data);
70 void supply_read_data(int fd, std::vector<char> &&data)
72 read_data[fd].emplace_back(std::move(data));
75 void set_blocking(int fd)
77 read_data[fd].is_blocking = true;
80 // retrieve data written via write()
81 void extract_written_data(int fd, std::vector<char> &data)
83 data = std::move(written_data[fd]);
87 // Mock implementations of system calls:
89 int pipe2(int fds[2], int flags)
98 if (size_t(fd) >= usedfds.size()) abort();
104 int kill(pid_t pid, int sig)
110 ssize_t read(int fd, void *buf, size_t count)
112 read_cond & rrs = read_data[fd];
114 if (rrs.is_blocking) {
121 read_result &rr = rrs.front();
122 if (rr.errcode != 0) {
124 // Remove the result record:
125 auto i = rrs.begin();
127 rrs.erase(rrs.begin(), i);
131 auto dsize = rr.data.size();
132 if (dsize <= count) {
133 // Consume entire result:
134 std::copy_n(rr.data.begin(), dsize, (char *)buf);
135 // Remove the result record:
136 rrs.erase(rrs.begin());
140 // Consume partial result:
141 std::copy_n(rr.data.begin(), count, (char *)buf);
142 rr.data.erase(rr.data.begin(), rr.data.begin() + count);
146 ssize_t write(int fd, const void *buf, size_t count)
148 std::vector<char> &wd = written_data[fd];
149 wd.insert(wd.end(), (char *)buf, (char *)buf + count);