| // Copyright 2018 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <errno.h> |
| #include <stdint.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <sys/un.h> |
| #include <unistd.h> |
| |
| #include <xdc-host-utils/client.h> |
| #include <xdc-host-utils/conn.h> |
| |
| #include <utility> |
| |
| namespace xdc { |
| |
| zx_status_t GetStream(uint32_t stream_id, fbl::unique_fd* out_fd) { |
| fbl::unique_fd fd(socket(AF_UNIX, SOCK_STREAM, 0)); |
| if (!fd) { |
| fprintf(stderr, "Could not create socket, err: %s\n", strerror(errno)); |
| return ZX_ERR_IO; |
| } |
| // Connect to the host xdc server. |
| struct sockaddr_un server = {}; |
| server.sun_family = AF_UNIX; |
| strncpy(server.sun_path, XDC_SOCKET_PATH, sizeof(server.sun_path)); |
| if (connect(fd.get(), (struct sockaddr*)&server, sizeof(server)) < 0) { |
| fprintf(stderr, "Could not connect to server: %s, err: %s\n", XDC_SOCKET_PATH, strerror(errno)); |
| return ZX_ERR_IO; |
| } |
| // Register the stream id. |
| ssize_t n = send(fd.get(), &stream_id, sizeof(stream_id), MSG_WAITALL); |
| if (n != sizeof(stream_id)) { |
| fprintf(stderr, "Write failed, expected %lu written, got %ld, err: %s\n", sizeof(stream_id), n, |
| strerror(errno)); |
| return ZX_ERR_IO; |
| } |
| // Wait for the server registration response. |
| RegisterStreamResponse connected_resp; |
| n = recv(fd.get(), &connected_resp, sizeof(connected_resp), MSG_WAITALL); |
| if (n != sizeof(connected_resp)) { |
| fprintf(stderr, "Read failed, expected %lu read, got %ld, err: %s\n", sizeof(connected_resp), n, |
| strerror(errno)); |
| return ZX_ERR_IO; |
| } |
| if (!connected_resp) { |
| fprintf(stderr, "Stream id %u was already taken, exiting\n", stream_id); |
| return ZX_ERR_ALREADY_BOUND; |
| } |
| *out_fd = std::move(fd); |
| return ZX_OK; |
| } |
| |
| } // namespace xdc |