Improve unit test infrastructure - allow control of write()
[oweals/dinit.git] / src / tests / test-includes / baseproc-sys.h
1 #ifndef BPSYS_INCLUDED
2 #define BPSYS_INCLUDED
3
4 #include <string>
5 #include <vector>
6
7 #include <sys/types.h>
8 #include <unistd.h>
9 #include <sys/uio.h>
10
11 // Mock system functions for testing.
12
13 namespace bp_sys {
14
15 class write_handler
16 {
17 public:
18     virtual ssize_t write(int fd, const void *buf, size_t count) = 0;
19     virtual ~write_handler() { }
20 };
21
22 class default_write_handler : public write_handler
23 {
24 public:
25     std::vector<char> data;
26
27     virtual ssize_t write(int fd, const void *buf, size_t count)
28     {
29         data.insert(data.end(), (char *)buf, (char *)buf + count);
30         return count;
31     }
32 };
33
34 // Test helper functions:
35
36 void init_bpsys();
37
38 // allocate a file descriptor
39 int allocfd();
40 int allocfd(write_handler *hndlr);
41
42 void supply_read_data(int fd, std::vector<char> &data);
43 void supply_read_data(int fd, std::vector<char> &&data);
44 void set_blocking(int fd);
45 void extract_written_data(int fd, std::vector<char> &data);
46
47 // Mock system calls:
48
49 // implementations elsewhere:
50 int pipe2(int pipefd[2], int flags);
51 int close(int fd);
52 int kill(pid_t pid, int sig);
53
54 inline int fcntl(int fd, int cmd, ...)
55 {
56     // This is used for setting the CLOEXEC flag, we can just return 0:
57     return 0;
58 }
59
60 inline pid_t getpgid(pid_t pid)
61 {
62     return pid;
63 }
64
65 inline int tcsetpgrp(int fd, pid_t pgid)
66 {
67     return 0;
68 }
69
70 inline pid_t getpgrp()
71 {
72     return getpid();
73 }
74
75 class exit_status
76 {
77     friend pid_t waitpid(pid_t, exit_status *, int);
78
79     bool did_exit_v;
80     bool was_signalled_v;
81     int status;
82
83     public:
84     exit_status() : did_exit_v(true), was_signalled_v(false), status(0) { }
85
86     // status_p is either the exit status or termination signal:
87     exit_status(bool did_exit_p, bool was_signalled_p, int status_p)
88         : did_exit_v(did_exit_p), was_signalled_v(was_signalled_p), status(status_p)
89     { }
90
91     explicit exit_status(int status_p)
92     {
93         throw std::string("initalised exit_status with integer argument");
94     }
95
96     bool did_exit()
97     {
98         return did_exit_v;
99     }
100
101     bool did_exit_clean()
102     {
103         return did_exit_v && status == 0;
104     }
105
106     bool was_signalled()
107     {
108         return was_signalled_v;
109     }
110
111     int get_exit_status()
112     {
113         return status;
114     }
115
116     int get_term_sig()
117     {
118         return status;
119     }
120
121     int as_int()
122     {
123         return -1;
124     }
125 };
126
127 inline pid_t waitpid(pid_t p, exit_status *statusp, int flags)
128 {
129     throw std::string("not implemented");
130 }
131
132 ssize_t read(int fd, void *buf, size_t count);
133 ssize_t write(int fd, const void *buf, size_t count);
134 ssize_t writev (int fd, const struct iovec *iovec, int count);
135
136 }
137
138 #endif