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