+static int do_cmd(const pid_t pid,
+ const struct ustcomm_header *req_header,
+ const char *req_data,
+ struct ustcomm_header *res_header,
+ char **res_data)
+{
+ int app_fd, result, saved_errno = 0;
+ char *recv_buf;
+
+ if (ustcomm_connect_app(pid, &app_fd)) {
+ ERR("could not connect to PID %u", (unsigned int) pid);
+ errno = ENOTCONN;
+ return -1;
+ }
+
+ recv_buf = zmalloc(USTCOMM_BUFFER_SIZE);
+ if (!recv_buf) {
+ saved_errno = ENOMEM;
+ goto close_app_fd;
+ }
+
+ result = ustcomm_req(app_fd, req_header, req_data, res_header, recv_buf);
+ if (result > 0) {
+ saved_errno = -res_header->result;
+ if (res_header->size == 0 || saved_errno > 0) {
+ free(recv_buf);
+ } else {
+ if (res_data) {
+ *res_data = recv_buf;
+ } else {
+ free(recv_buf);
+ }
+ }
+ } else {
+ ERR("ustcomm req failed");
+ if (result == 0) {
+ saved_errno = ENOTCONN;
+ } else {
+ saved_errno = -result;
+ }
+ free(recv_buf);
+ }
+
+close_app_fd:
+ close(app_fd);
+
+ errno = saved_errno;
+
+ if (errno) {
+ return -1;
+ }
+
+ return 0;
+}
+