gio/
unix_socket_address.rs

1// Copyright 2013-2018, The Gtk-rs Project Developers.
2// See the COPYRIGHT file at the top-level directory of this distribution.
3// Licensed under the MIT license, see the LICENSE file or <http://opensource.org/licenses/MIT>
4
5use gio_sys;
6use glib::object::{Cast, IsA};
7use glib::translate::*;
8use libc;
9use std::ffi::OsStr;
10#[cfg(unix)]
11use std::os::unix::ffi::OsStrExt;
12use std::path;
13use std::ptr;
14use std::slice;
15use SocketAddress;
16use UnixSocketAddress;
17use UnixSocketAddressExt;
18use UnixSocketAddressType;
19
20#[derive(Debug)]
21pub enum UnixSocketAddressPath<'a> {
22    Path(&'a path::Path),
23    Anonymous,
24    Abstract(&'a [u8]),
25    AbstractPadded(&'a [u8]),
26}
27
28impl<'a> UnixSocketAddressPath<'a> {
29    fn to_type(&self) -> UnixSocketAddressType {
30        use self::UnixSocketAddressPath::*;
31
32        match *self {
33            Path(_) => UnixSocketAddressType::Path,
34            Anonymous => UnixSocketAddressType::Anonymous,
35            Abstract(_) => UnixSocketAddressType::Abstract,
36            AbstractPadded(_) => UnixSocketAddressType::AbstractPadded,
37        }
38    }
39}
40
41impl UnixSocketAddress {
42    pub fn new(path: &path::Path) -> UnixSocketAddress {
43        unsafe {
44            SocketAddress::from_glib_full(gio_sys::g_unix_socket_address_new(path.to_glib_none().0))
45                .unsafe_cast()
46        }
47    }
48
49    pub fn new_with_type(address_type: UnixSocketAddressPath) -> Self {
50        use self::UnixSocketAddressPath::*;
51
52        let type_ = address_type.to_type();
53        let (path, len) = match address_type {
54            Path(path) => (path.to_glib_none().0, path.as_os_str().len()),
55            Abstract(path) | AbstractPadded(path) => {
56                (path.to_glib_none().0 as *mut libc::c_char, path.len())
57            }
58            Anonymous => (ptr::null_mut(), 0),
59        };
60        unsafe {
61            SocketAddress::from_glib_full(gio_sys::g_unix_socket_address_new_with_type(
62                path,
63                len as i32,
64                type_.to_glib(),
65            ))
66            .unsafe_cast()
67        }
68    }
69}
70
71pub trait UnixSocketAddressExtManual {
72    fn get_path(&self) -> Option<UnixSocketAddressPath>;
73}
74
75impl<O: IsA<UnixSocketAddress>> UnixSocketAddressExtManual for O {
76    fn get_path(&self) -> Option<UnixSocketAddressPath> {
77        use self::UnixSocketAddressPath::*;
78
79        let path = unsafe {
80            let path = gio_sys::g_unix_socket_address_get_path(self.as_ref().to_glib_none().0);
81            if path.is_null() {
82                &[]
83            } else {
84                slice::from_raw_parts(path as *const u8, self.get_path_len())
85            }
86        };
87        match self.get_address_type() {
88            UnixSocketAddressType::Anonymous => Some(Anonymous),
89            #[cfg(not(feature = "dox"))]
90            UnixSocketAddressType::Path => Some(Path(path::Path::new(OsStr::from_bytes(path)))),
91            #[cfg(feature = "dox")]
92            UnixSocketAddressType::Path => unreachable!(),
93            UnixSocketAddressType::Abstract => Some(Abstract(path)),
94            UnixSocketAddressType::AbstractPadded => Some(AbstractPadded(path)),
95            UnixSocketAddressType::Invalid | UnixSocketAddressType::__Unknown(_) => None,
96        }
97    }
98}