1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::io;
15 
16 use libc::c_int;
17 
socket_new(domain: c_int, socket_type: c_int) -> io::Result<c_int>18 pub(crate) fn socket_new(domain: c_int, socket_type: c_int) -> io::Result<c_int> {
19     #[cfg(target_os = "linux")]
20     let socket_type = socket_type | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
21     let socket = syscall!(socket(domain, socket_type, 0))?;
22 
23     #[cfg(target_os = "macos")]
24     set_non_block(socket)?;
25     Ok(socket)
26 }
27 
28 #[cfg(target_os = "macos")]
set_non_block(socket: c_int) -> io::Result<()>29 pub(crate) fn set_non_block(socket: c_int) -> io::Result<()> {
30     if let Err(e) = syscall!(setsockopt(
31         socket,
32         libc::SOL_SOCKET,
33         libc::SO_NOSIGPIPE,
34         &1 as *const libc::c_int as *const libc::c_void,
35         std::mem::size_of::<libc::c_int>() as libc::socklen_t
36     )) {
37         let _ = syscall!(close(socket));
38         return Err(e);
39     }
40 
41     if let Err(e) = syscall!(fcntl(socket, libc::F_SETFL, libc::O_NONBLOCK)) {
42         let _ = syscall!(close(socket));
43         return Err(e);
44     }
45 
46     if let Err(e) = syscall!(fcntl(socket, libc::F_SETFD, libc::FD_CLOEXEC)) {
47         let _ = syscall!(close(socket));
48         return Err(e);
49     }
50     Ok(())
51 }
52