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