+// Get the service name for a given handle, by querying the daemon.
+static std::string get_service_name(int socknum, cpbuffer_t &rbuffer, handle_t handle)
+{
+ auto m = membuf()
+ .append((char) DINIT_CP_QUERYSERVICENAME)
+ .append((char) 0)
+ .append(handle);
+ write_all_x(socknum, m);
+
+ wait_for_reply(rbuffer, socknum);
+
+ if (rbuffer[0] != DINIT_RP_SERVICENAME) {
+ throw cp_read_exception{0};
+ }
+
+ // 1 byte reserved
+ // uint16_t size
+ fill_buffer_to(rbuffer, socknum, 2 + sizeof(uint16_t));
+ uint16_t namesize;
+ rbuffer.extract(&namesize, 2, sizeof(uint16_t));
+ rbuffer.consume(2 + sizeof(uint16_t));
+
+ std::string name;
+
+ do {
+ if (rbuffer.get_length() == 0) {
+ rbuffer.fill(socknum);
+ }
+
+ size_t to_extract = std::min(size_t(rbuffer.get_length()), namesize - name.length());
+ size_t contiguous_len = rbuffer.get_contiguous_length(rbuffer.get_ptr(0));
+ if (contiguous_len <= to_extract) {
+ name.append(rbuffer.get_ptr(0), contiguous_len);
+ rbuffer.consume(contiguous_len);
+ name.append(rbuffer.get_ptr(0), to_extract - contiguous_len);
+ rbuffer.consume(to_extract - contiguous_len);
+ }
+ else {
+ name.append(rbuffer.get_ptr(0), to_extract);
+ rbuffer.consume(to_extract);
+ break;
+ }
+
+ } while (name.length() < namesize);
+
+ return name;
+}
+