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