3 // Client library for Dinit clients
6 using handle_t = uint32_t;
8 class read_cp_exception
12 read_cp_exception(int err) : errcode(err) { }
15 // Fill a circular buffer from a file descriptor, until it contains at least _rlength_ bytes.
16 // Throws read_cp_exception if the requested number of bytes cannot be read, with:
17 // errcode = 0 if end of stream (remote end closed)
18 // errcode = errno if another error occurred
19 // Note that EINTR is ignored (i.e. the read will be re-tried).
20 inline void fill_buffer_to(cpbuffer<1024> *buf, int fd, int rlength)
23 int r = buf->fill_to(fd, rlength);
26 throw read_cp_exception(errno);
30 throw read_cp_exception(0);
39 // Wait for a reply packet, skipping over any information packets that are received in the meantime.
40 inline void wait_for_reply(cpbuffer<1024> &rbuffer, int fd)
42 fill_buffer_to(&rbuffer, fd, 1);
44 while (rbuffer[0] >= 100) {
45 // Information packet; discard.
46 fill_buffer_to(&rbuffer, fd, 2);
47 int pktlen = (unsigned char) rbuffer[1];
49 rbuffer.consume(1); // Consume one byte so we'll read one byte of the next packet
50 fill_buffer_to(&rbuffer, fd, pktlen);
51 rbuffer.consume(pktlen - 1);
55 // Wait for an info packet. If any other reply packet comes, throw a read_cp_exception.
56 inline void wait_for_info(cpbuffer<1024> &rbuffer, int fd)
58 fill_buffer_to(&rbuffer, fd, 2);
60 if (rbuffer[0] < 100) {
61 throw read_cp_exception(0);
64 int pktlen = (unsigned char) rbuffer[1];
65 fill_buffer_to(&rbuffer, fd, pktlen);
68 // Write *all* the requested buffer and re-try if necessary until
69 // the buffer is written or an unrecoverable error occurs.
70 inline int write_all(int fd, const void *buf, size_t count)
72 const char *cbuf = static_cast<const char *>(buf);
75 int r = write(fd, cbuf, count);
77 if (errno == EINTR) continue;