Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  socket.rs

  Sprache: Rust
 

use std::io;
use std::path::Path;

use std::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};

use crate::net::{UnixDatagram, UnixListener, UnixStream};

cfg_net_unix! {
    /// A Unix socket that has not yet been converted to a [`UnixStream`], [`UnixDatagram`], or
    /// [`UnixListener`].
    ///
    /// `UnixSocket` wraps an operating system socket and enables the caller to
    /// configure the socket before establishing a connection or accepting
    /// inbound connections. The caller is able to set socket option and explicitly
    /// bind the socket with a socket address.
    ///
    /// The underlying socket is closed when the `UnixSocket` value is dropped.
    ///
    /// `UnixSocket` should only be used directly if the default configuration used
    /// by [`UnixStream::connect`], [`UnixDatagram::bind`], and [`UnixListener::bind`]
    /// does not meet the required use case.
    ///
    /// Calling `UnixStream::connect(path)` effectively performs the same function as:
    ///
    /// ```no_run
    /// use tokio::net::UnixSocket;
    /// use std::error::Error;
    ///
    /// #[tokio::main]
    /// async fn main() -> Result<(), Box<dyn Error>> {
    ///     let dir = tempfile::tempdir().unwrap();
    ///     let path = dir.path().join("bind_path");
    ///     let socket = UnixSocket::new_stream()?;
    ///
    ///     let stream = socket.connect(path).await?;
    ///
    ///     Ok(())
    /// }
    /// ```
    ///
    /// Calling `UnixDatagram::bind(path)` effectively performs the same function as:
    ///
    /// ```no_run
    /// use tokio::net::UnixSocket;
    /// use std::error::Error;
    ///
    /// #[tokio::main]
    /// async fn main() -> Result<(), Box<dyn Error>> {
    ///     let dir = tempfile::tempdir().unwrap();
    ///     let path = dir.path().join("bind_path");
    ///     let socket = UnixSocket::new_datagram()?;
    ///     socket.bind(path)?;
    ///
    ///     let datagram = socket.datagram()?;
    ///
    ///     Ok(())
    /// }
    /// ```
    ///
    /// Calling `UnixListener::bind(path)` effectively performs the same function as:
    ///
    /// ```no_run
    /// use tokio::net::UnixSocket;
    /// use std::error::Error;
    ///
    /// #[tokio::main]
    /// async fn main() -> Result<(), Box<dyn Error>> {
    ///     let dir = tempfile::tempdir().unwrap();
    ///     let path = dir.path().join("bind_path");
    ///     let socket = UnixSocket::new_stream()?;
    ///     socket.bind(path)?;
    ///
    ///     let listener = socket.listen(1024)?;
    ///
    ///     Ok(())
    /// }
    /// ```
    ///
    /// Setting socket options not explicitly provided by `UnixSocket` may be done by
    /// accessing the [`RawFd`]/[`RawSocket`] using [`AsRawFd`]/[`AsRawSocket`] and
    /// setting the option with a crate like [`socket2`].
    ///
    /// [`RawFd`]: std::os::fd::RawFd
    /// [`RawSocket`]: https://doc.rust-lang.org/std/os/windows/io/type.RawSocket.html
    /// [`AsRawFd`]: std::os::fd::AsRawFd
    /// [`AsRawSocket`]: https://doc.rust-lang.org/std/os/windows/io/trait.AsRawSocket.html
    /// [`socket2`]: https://docs.rs/socket2/
    #[derive(Debug)]
    pub struct UnixSocket {
        inner: socket2::Socket,
    }
}

impl UnixSocket {
    fn ty(&self) -> socket2::Type {
        self.inner.r#type().unwrap()
    }

    /// Creates a new Unix datagram socket.
    ///
    /// Calls `socket(2)` with `AF_UNIX` and `SOCK_DGRAM`.
    ///
    /// # Returns
    ///
    /// On success, the newly created [`UnixSocket`] is returned. If an error is
    /// encountered, it is returned instead.
    pub fn new_datagram() -> io::Result<UnixSocket> {
        UnixSocket::new(socket2::Type::DGRAM)
    }

    /// Creates a new Unix stream socket.
    ///
    /// Calls `socket(2)` with `AF_UNIX` and `SOCK_STREAM`.
    ///
    /// # Returns
    ///
    /// On success, the newly created [`UnixSocket`] is returned. If an error is
    /// encountered, it is returned instead.
    pub fn new_stream() -> io::Result<UnixSocket> {
        UnixSocket::new(socket2::Type::STREAM)
    }

    fn new(ty: socket2::Type) -> io::Result<UnixSocket> {
        #[cfg(any(
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "linux",
            target_os = "netbsd",
            target_os = "openbsd"
        ))]
        let ty = ty.nonblocking();
        let inner = socket2::Socket::new(socket2::Domain::UNIX, ty, None)?;
        #[cfg(not(any(
            target_os = "android",
            target_os = "dragonfly",
            target_os = "freebsd",
            target_os = "fuchsia",
            target_os = "illumos",
            target_os = "linux",
            target_os = "netbsd",
            target_os = "openbsd"
        )))]
        inner.set_nonblocking(true)?;
        Ok(UnixSocket { inner })
    }

    /// Binds the socket to the given address.
    ///
    /// This calls the `bind(2)` operating-system function.
    pub fn bind(&self, path: impl AsRef<Path>) -> io::Result<()> {
        let addr = socket2::SockAddr::unix(path)?;
        self.inner.bind(&addr)
    }

    /// Converts the socket into a `UnixListener`.
    ///
    /// `backlog` defines the maximum number of pending connections are queued
    /// by the operating system at any given time. Connection are removed from
    /// the queue with [`UnixListener::accept`]. When the queue is full, the
    /// operating-system will start rejecting connections.
    ///
    /// Calling this function on a socket created by [`new_datagram`] will return an error.
    ///
    /// This calls the `listen(2)` operating-system function, marking the socket
    /// as a passive socket.
    ///
    /// [`new_datagram`]: `UnixSocket::new_datagram`
    pub fn listen(self, backlog: u32) -> io::Result<UnixListener> {
        if self.ty() == socket2::Type::DGRAM {
            return Err(io::Error::new(
                io::ErrorKind::Other,
                "listen cannot be called on a datagram socket",
            ));
        }

        self.inner.listen(backlog as i32)?;
        let mio = {
            use std::os::unix::io::{FromRawFd, IntoRawFd};

            let raw_fd = self.inner.into_raw_fd();
            unsafe { mio::net::UnixListener::from_raw_fd(raw_fd) }
        };

        UnixListener::new(mio)
    }

    /// Establishes a Unix connection with a peer at the specified socket address.
    ///
    /// The `UnixSocket` is consumed. Once the connection is established, a
    /// connected [`UnixStream`] is returned. If the connection fails, the
    /// encountered error is returned.
    ///
    /// Calling this function on a socket created by [`new_datagram`] will return an error.
    ///
    /// This calls the `connect(2)` operating-system function.
    ///
    /// [`new_datagram`]: `UnixSocket::new_datagram`
    pub async fn connect(self, path: impl AsRef<Path>) -> io::Result<UnixStream> {
        if self.ty() == socket2::Type::DGRAM {
            return Err(io::Error::new(
                io::ErrorKind::Other,
                "connect cannot be called on a datagram socket",
            ));
        }

        let addr = socket2::SockAddr::unix(path)?;
        if let Err(err) = self.inner.connect(&addr) {
            if err.raw_os_error() != Some(libc::EINPROGRESS) {
                return Err(err);
            }
        }
        let mio = {
            use std::os::unix::io::{FromRawFd, IntoRawFd};

            let raw_fd = self.inner.into_raw_fd();
            unsafe { mio::net::UnixStream::from_raw_fd(raw_fd) }
        };

        UnixStream::connect_mio(mio).await
    }

    /// Converts the socket into a [`UnixDatagram`].
    ///
    /// Calling this function on a socket created by [`new_stream`] will return an error.
    ///
    /// [`new_stream`]: `UnixSocket::new_stream`
    pub fn datagram(self) -> io::Result<UnixDatagram> {
        if self.ty() == socket2::Type::STREAM {
            return Err(io::Error::new(
                io::ErrorKind::Other,
                "datagram cannot be called on a stream socket",
            ));
        }
        let mio = {
            use std::os::unix::io::{FromRawFd, IntoRawFd};

            let raw_fd = self.inner.into_raw_fd();
            unsafe { mio::net::UnixDatagram::from_raw_fd(raw_fd) }
        };

        UnixDatagram::from_mio(mio)
    }
}

impl AsRawFd for UnixSocket {
    fn as_raw_fd(&self) -> RawFd {
        self.inner.as_raw_fd()
    }
}

impl AsFd for UnixSocket {
    fn as_fd(&self) -> BorrowedFd<'_> {
        unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
    }
}

impl FromRawFd for UnixSocket {
    unsafe fn from_raw_fd(fd: RawFd) -> UnixSocket {
        let inner = socket2::Socket::from_raw_fd(fd);
        UnixSocket { inner }
    }
}

impl IntoRawFd for UnixSocket {
    fn into_raw_fd(self) -> RawFd {
        self.inner.into_raw_fd()
    }
}

Messung V0.5 in Prozent
C=51 H=94 G=75

¤ Dauer der Verarbeitung: 0.8 Sekunden  (vorverarbeitet am  2026-06-18) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik