1 // Copyright 2019 The Chromium OS 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 use std::io; 5 use std::os::unix::io::{AsRawFd, RawFd}; 6 7 use sys_util::{net::UnixSeqpacket, ScmSocket}; 8 9 use data_model::DataInit; 10 11 const CRAS_SERVER_SOCKET_PATH: &str = "/run/cras/.cras_socket"; 12 /// A socket connecting to the CRAS audio server. 13 pub struct CrasServerSocket { 14 socket: UnixSeqpacket, 15 } 16 17 impl CrasServerSocket { new() -> io::Result<CrasServerSocket>18 pub fn new() -> io::Result<CrasServerSocket> { 19 let socket = UnixSeqpacket::connect(CRAS_SERVER_SOCKET_PATH)?; 20 Ok(CrasServerSocket { socket }) 21 } 22 23 /// Sends a sized and packed server messge to the server socket. The message 24 /// must implement `Sized` and `DataInit`. 25 /// # Arguments 26 /// * `message` - A sized and packed message. 27 /// * `fds` - A slice of fds to send. 28 /// 29 /// # Returns 30 /// * Length of written bytes in `usize`. 31 /// 32 /// # Errors 33 /// Return error if the socket fails to write message to server. send_server_message_with_fds<M: Sized + DataInit>( &self, message: &M, fds: &[RawFd], ) -> io::Result<usize>34 pub fn send_server_message_with_fds<M: Sized + DataInit>( 35 &self, 36 message: &M, 37 fds: &[RawFd], 38 ) -> io::Result<usize> { 39 match fds.len() { 40 0 => self.socket.send(message.as_slice()), 41 _ => match self.send_with_fds(message.as_slice(), fds) { 42 Ok(len) => Ok(len), 43 Err(err) => Err(io::Error::new(io::ErrorKind::Other, format!("{}", err))), 44 }, 45 } 46 } 47 48 /// Creates a clone of the underlying socket. The returned clone can also be 49 /// used to communicate with the cras server. try_clone(&self) -> io::Result<CrasServerSocket>50 pub fn try_clone(&self) -> io::Result<CrasServerSocket> { 51 let new_sock = self.socket.try_clone()?; 52 Ok(CrasServerSocket { socket: new_sock }) 53 } 54 } 55 56 // For using `recv_with_fds` and `send_with_fds`. 57 impl ScmSocket for CrasServerSocket { socket_fd(&self) -> RawFd58 fn socket_fd(&self) -> RawFd { 59 self.socket.as_raw_fd() 60 } 61 } 62 63 // For using `PollContex`. 64 impl AsRawFd for CrasServerSocket { as_raw_fd(&self) -> RawFd65 fn as_raw_fd(&self) -> RawFd { 66 self.socket.as_raw_fd() 67 } 68 } 69