// Copyright 2019 The Chromium OS Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. use std::io; use std::os::unix::io::{AsRawFd, RawFd}; use sys_util::{net::UnixSeqpacket, ScmSocket}; use data_model::DataInit; const CRAS_SERVER_SOCKET_PATH: &str = "/run/cras/.cras_socket"; /// A socket connecting to the CRAS audio server. pub struct CrasServerSocket { socket: UnixSeqpacket, } impl CrasServerSocket { pub fn new() -> io::Result { let socket = UnixSeqpacket::connect(CRAS_SERVER_SOCKET_PATH)?; Ok(CrasServerSocket { socket }) } /// Sends a sized and packed server messge to the server socket. The message /// must implement `Sized` and `DataInit`. /// # Arguments /// * `message` - A sized and packed message. /// * `fds` - A slice of fds to send. /// /// # Returns /// * Length of written bytes in `usize`. /// /// # Errors /// Return error if the socket fails to write message to server. pub fn send_server_message_with_fds( &self, message: &M, fds: &[RawFd], ) -> io::Result { match fds.len() { 0 => self.socket.send(message.as_slice()), _ => match self.send_with_fds(message.as_slice(), fds) { Ok(len) => Ok(len), Err(err) => Err(io::Error::new(io::ErrorKind::Other, format!("{}", err))), }, } } /// Creates a clone of the underlying socket. The returned clone can also be /// used to communicate with the cras server. pub fn try_clone(&self) -> io::Result { let new_sock = self.socket.try_clone()?; Ok(CrasServerSocket { socket: new_sock }) } } // For using `recv_with_fds` and `send_with_fds`. impl ScmSocket for CrasServerSocket { fn socket_fd(&self) -> RawFd { self.socket.as_raw_fd() } } // For using `PollContex`. impl AsRawFd for CrasServerSocket { fn as_raw_fd(&self) -> RawFd { self.socket.as_raw_fd() } }