xref: /aosp_15_r20/system/librustutils/sockets.rs (revision e51878c104ea269309bae357ae559a9fff179380)
1 // Copyright (C) 2022 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 //! Provides utilities for sockets.
16 
17 use std::ffi::CString;
18 use std::os::fd::OwnedFd;
19 use thiserror::Error;
20 
21 use crate::inherited_fd;
22 
23 /// Errors this crate can generate
24 #[derive(Error, Debug)]
25 pub enum SocketError {
26     /// Invalid socket name. It could be either due to a null byte in the name, or the name refers
27     /// to a non-existing socket.
28     #[error("socket name {0} is invalid")]
29     InvalidName(String),
30 
31     /// Error when taking ownership of the socket file descriptor.
32     #[error("Failed to take file descriptor ownership: {0}")]
33     OwnershipFailed(inherited_fd::Error),
34 }
35 
36 /// Get `OwnedFd` for a Unix domain socket that init created under the name `name`. See
37 /// [Android Init Language]
38 /// (https://cs.android.com/android/platform/superproject/main/+/main:system/core/init/README.md)
39 /// for creating sockets and giving them names.
40 ///
41 /// The returned file descriptor has the flag CLOEXEC set.
42 ///
43 /// This function returns `SocketError::OwnershipFailed` if `crate::inherited_fd::init_once` was
44 /// not called very early in the process startup or this function is called multile times with the
45 /// same `name`.
android_get_control_socket(name: &str) -> Result<OwnedFd, SocketError>46 pub fn android_get_control_socket(name: &str) -> Result<OwnedFd, SocketError> {
47     let cstr = CString::new(name).map_err(|_| SocketError::InvalidName(name.to_owned()))?;
48     // SAFETY: android_get_control_socket doesn't take ownership of name
49     let fd = unsafe { cutils_bindgen::android_get_control_socket(cstr.as_ptr()) };
50     if fd < 0 {
51         return Err(SocketError::InvalidName(name.to_owned()));
52     }
53     inherited_fd::take_fd_ownership(fd).map_err(SocketError::OwnershipFailed)
54 }
55