1 // Copyright 2018 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <errno.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <string.h>
9 #include <sys/socket.h>
10 #include <sys/types.h>
11 #include <sys/un.h>
12 #include <unistd.h>
13 
14 #include <xdc-host-utils/client.h>
15 #include <xdc-host-utils/conn.h>
16 
17 #include <utility>
18 
19 namespace xdc {
20 
GetStream(uint32_t stream_id,fbl::unique_fd * out_fd)21 zx_status_t GetStream(uint32_t stream_id, fbl::unique_fd* out_fd) {
22     fbl::unique_fd fd(socket(AF_UNIX, SOCK_STREAM, 0));
23     if (!fd) {
24         fprintf(stderr, "Could not create socket, err: %s\n", strerror(errno));
25         return ZX_ERR_IO;
26     }
27     // Connect to the host xdc server.
28     struct sockaddr_un server = {};
29     server.sun_family = AF_UNIX;
30     strncpy(server.sun_path, XDC_SOCKET_PATH, sizeof(server.sun_path));
31     if (connect(fd.get(), (struct sockaddr *)&server, sizeof(server)) < 0) {
32         fprintf(stderr, "Could not connect to server: %s, err: %s\n",
33                 XDC_SOCKET_PATH, strerror(errno));
34         return ZX_ERR_IO;
35     }
36     // Register the stream id.
37     ssize_t n = send(fd.get(), &stream_id, sizeof(stream_id), MSG_WAITALL);
38     if (n != sizeof(stream_id)) {
39         fprintf(stderr, "Write failed, expected %lu written, got %ld, err: %s\n",
40                 sizeof(stream_id), n, strerror(errno));
41         return ZX_ERR_IO;
42     }
43     // Wait for the server registration response.
44     RegisterStreamResponse connected_resp;
45     n = recv(fd.get(), &connected_resp, sizeof(connected_resp), MSG_WAITALL);
46     if (n != sizeof(connected_resp)) {
47         fprintf(stderr, "Read failed, expected %lu read, got %ld, err: %s\n",
48                 sizeof(connected_resp), n, strerror(errno));
49         return ZX_ERR_IO;
50     }
51     if (!connected_resp) {
52         fprintf(stderr, "Stream id %u was already taken, exiting\n", stream_id);
53         return ZX_ERR_ALREADY_BOUND;
54     }
55     *out_fd = std::move(fd);
56     return ZX_OK;
57 }
58 
59 }  // namespace xdc
60