pub struct ServerOptions { /* private fields */ }
net
only.Expand description
A builder structure for construct a named pipe with named pipe-specific options. This is required to use for named pipe servers who wants to modify pipe-related options.
Implementations§
Source§impl ServerOptions
impl ServerOptions
Sourcepub fn new() -> ServerOptions
pub fn new() -> ServerOptions
Creates a new named pipe builder with the default settings.
use tokio::net::windows::named_pipe::ServerOptions;
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-new";
let server = ServerOptions::new().create(PIPE_NAME)?;
Sourcepub fn pipe_mode(&mut self, pipe_mode: PipeMode) -> &mut Self
pub fn pipe_mode(&mut self, pipe_mode: PipeMode) -> &mut Self
The pipe mode.
The default pipe mode is PipeMode::Byte
. See PipeMode
for
documentation of what each mode means.
This corresponds to specifying PIPE_TYPE_
and PIPE_READMODE_
in dwPipeMode
.
Sourcepub fn access_inbound(&mut self, allowed: bool) -> &mut Self
pub fn access_inbound(&mut self, allowed: bool) -> &mut Self
The flow of data in the pipe goes from client to server only.
This corresponds to setting PIPE_ACCESS_INBOUND
.
§Errors
Server side prevents connecting by denying inbound access, client errors
with std::io::ErrorKind::PermissionDenied
when attempting to create
the connection.
use std::io;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound-err1";
let _server = ServerOptions::new()
.access_inbound(false)
.create(PIPE_NAME)?;
let e = ClientOptions::new()
.open(PIPE_NAME)
.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Disabling writing allows a client to connect, but errors with
std::io::ErrorKind::PermissionDenied
if a write is attempted.
use std::io;
use tokio::io::AsyncWriteExt;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound-err2";
let server = ServerOptions::new()
.access_inbound(false)
.create(PIPE_NAME)?;
let mut client = ClientOptions::new()
.write(false)
.open(PIPE_NAME)?;
server.connect().await?;
let e = client.write(b"ping").await.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
§Examples
A unidirectional named pipe that only supports server-to-client communication.
use std::io;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-inbound";
let mut server = ServerOptions::new()
.access_inbound(false)
.create(PIPE_NAME)?;
let mut client = ClientOptions::new()
.write(false)
.open(PIPE_NAME)?;
server.connect().await?;
let write = server.write_all(b"ping");
let mut buf = [0u8; 4];
let read = client.read_exact(&mut buf);
let ((), read) = tokio::try_join!(write, read)?;
assert_eq!(read, 4);
assert_eq!(&buf[..], b"ping");
Sourcepub fn access_outbound(&mut self, allowed: bool) -> &mut Self
pub fn access_outbound(&mut self, allowed: bool) -> &mut Self
The flow of data in the pipe goes from server to client only.
This corresponds to setting PIPE_ACCESS_OUTBOUND
.
§Errors
Server side prevents connecting by denying outbound access, client
errors with std::io::ErrorKind::PermissionDenied
when attempting to
create the connection.
use std::io;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound-err1";
let server = ServerOptions::new()
.access_outbound(false)
.create(PIPE_NAME)?;
let e = ClientOptions::new()
.open(PIPE_NAME)
.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
Disabling reading allows a client to connect, but attempting to read
will error with std::io::ErrorKind::PermissionDenied
.
use std::io;
use tokio::io::AsyncReadExt;
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound-err2";
let server = ServerOptions::new()
.access_outbound(false)
.create(PIPE_NAME)?;
let mut client = ClientOptions::new()
.read(false)
.open(PIPE_NAME)?;
server.connect().await?;
let mut buf = [0u8; 4];
let e = client.read(&mut buf).await.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
§Examples
A unidirectional named pipe that only supports client-to-server communication.
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::windows::named_pipe::{ClientOptions, ServerOptions};
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-access-outbound";
let mut server = ServerOptions::new()
.access_outbound(false)
.create(PIPE_NAME)?;
let mut client = ClientOptions::new()
.read(false)
.open(PIPE_NAME)?;
server.connect().await?;
let write = client.write_all(b"ping");
let mut buf = [0u8; 4];
let read = server.read_exact(&mut buf);
let ((), read) = tokio::try_join!(write, read)?;
println!("done reading and writing");
assert_eq!(read, 4);
assert_eq!(&buf[..], b"ping");
Sourcepub fn first_pipe_instance(&mut self, first: bool) -> &mut Self
pub fn first_pipe_instance(&mut self, first: bool) -> &mut Self
If you attempt to create multiple instances of a pipe with this flag
set, creation of the first server instance succeeds, but creation of any
subsequent instances will fail with
std::io::ErrorKind::PermissionDenied
.
This option is intended to be used with servers that want to ensure that they are the only process listening for clients on a given named pipe. This is accomplished by enabling it for the first server instance created in a process.
This corresponds to setting FILE_FLAG_FIRST_PIPE_INSTANCE
.
§Errors
If this option is set and more than one instance of the server for a
given named pipe exists, calling create
will fail with
std::io::ErrorKind::PermissionDenied
.
use std::io;
use tokio::net::windows::named_pipe::ServerOptions;
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-first-instance-error";
let server1 = ServerOptions::new()
.first_pipe_instance(true)
.create(PIPE_NAME)?;
// Second server errs, since it's not the first instance.
let e = ServerOptions::new()
.first_pipe_instance(true)
.create(PIPE_NAME)
.unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
§Examples
use std::io;
use tokio::net::windows::named_pipe::ServerOptions;
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-first-instance";
let mut builder = ServerOptions::new();
builder.first_pipe_instance(true);
let server = builder.create(PIPE_NAME)?;
let e = builder.create(PIPE_NAME).unwrap_err();
assert_eq!(e.kind(), io::ErrorKind::PermissionDenied);
drop(server);
// OK: since, we've closed the other instance.
let _server2 = builder.create(PIPE_NAME)?;
Sourcepub fn write_dac(&mut self, requested: bool) -> &mut Self
pub fn write_dac(&mut self, requested: bool) -> &mut Self
Requests permission to modify the pipe’s discretionary access control list.
This corresponds to setting WRITE_DAC
in dwOpenMode.
§Examples
use std::{io, os::windows::prelude::AsRawHandle, ptr};
use tokio::net::windows::named_pipe::ServerOptions;
use windows_sys::{
Win32::Foundation::ERROR_SUCCESS,
Win32::Security::DACL_SECURITY_INFORMATION,
Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
};
const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe";
let mut pipe_template = ServerOptions::new();
pipe_template.write_dac(true);
let pipe = pipe_template.create(PIPE_NAME)?;
unsafe {
assert_eq!(
ERROR_SUCCESS,
SetSecurityInfo(
pipe.as_raw_handle() as _,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
)
);
}
use std::{io, os::windows::prelude::AsRawHandle, ptr};
use tokio::net::windows::named_pipe::ServerOptions;
use windows_sys::{
Win32::Foundation::ERROR_ACCESS_DENIED,
Win32::Security::DACL_SECURITY_INFORMATION,
Win32::Security::Authorization::{SetSecurityInfo, SE_KERNEL_OBJECT},
};
const PIPE_NAME: &str = r"\\.\pipe\write_dac_pipe_fail";
let mut pipe_template = ServerOptions::new();
pipe_template.write_dac(false);
let pipe = pipe_template.create(PIPE_NAME)?;
unsafe {
assert_eq!(
ERROR_ACCESS_DENIED,
SetSecurityInfo(
pipe.as_raw_handle() as _,
SE_KERNEL_OBJECT,
DACL_SECURITY_INFORMATION,
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
ptr::null_mut(),
)
);
}
Sourcepub fn write_owner(&mut self, requested: bool) -> &mut Self
pub fn write_owner(&mut self, requested: bool) -> &mut Self
Requests permission to modify the pipe’s owner.
This corresponds to setting WRITE_OWNER
in dwOpenMode.
Sourcepub fn access_system_security(&mut self, requested: bool) -> &mut Self
pub fn access_system_security(&mut self, requested: bool) -> &mut Self
Requests permission to modify the pipe’s system access control list.
This corresponds to setting ACCESS_SYSTEM_SECURITY
in dwOpenMode.
Sourcepub fn reject_remote_clients(&mut self, reject: bool) -> &mut Self
pub fn reject_remote_clients(&mut self, reject: bool) -> &mut Self
Indicates whether this server can accept remote clients or not. Remote clients are disabled by default.
This corresponds to setting PIPE_REJECT_REMOTE_CLIENTS
.
Sourcepub fn max_instances(&mut self, instances: usize) -> &mut Self
pub fn max_instances(&mut self, instances: usize) -> &mut Self
The maximum number of instances that can be created for this pipe. The first instance of the pipe can specify this value; the same number must be specified for other instances of the pipe. Acceptable values are in the range 1 through 254. The default value is unlimited.
This corresponds to specifying nMaxInstances
.
§Errors
The same numbers of max_instances
have to be used by all servers. Any
additional servers trying to be built which uses a mismatching value
might error.
use std::io;
use tokio::net::windows::named_pipe::{ServerOptions, ClientOptions};
use windows_sys::Win32::Foundation::ERROR_PIPE_BUSY;
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-max-instances";
let mut server = ServerOptions::new();
server.max_instances(2);
let s1 = server.create(PIPE_NAME)?;
let c1 = ClientOptions::new().open(PIPE_NAME);
let s2 = server.create(PIPE_NAME)?;
let c2 = ClientOptions::new().open(PIPE_NAME);
// Too many servers!
let e = server.create(PIPE_NAME).unwrap_err();
assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));
// Still too many servers even if we specify a higher value!
let e = server.max_instances(100).create(PIPE_NAME).unwrap_err();
assert_eq!(e.raw_os_error(), Some(ERROR_PIPE_BUSY as i32));
§Panics
This function will panic if more than 254 instances are specified. If you do not wish to set an instance limit, leave it unspecified.
use tokio::net::windows::named_pipe::ServerOptions;
let builder = ServerOptions::new().max_instances(255);
Sourcepub fn out_buffer_size(&mut self, buffer: u32) -> &mut Self
pub fn out_buffer_size(&mut self, buffer: u32) -> &mut Self
The number of bytes to reserve for the output buffer.
This corresponds to specifying nOutBufferSize
.
Sourcepub fn in_buffer_size(&mut self, buffer: u32) -> &mut Self
pub fn in_buffer_size(&mut self, buffer: u32) -> &mut Self
The number of bytes to reserve for the input buffer.
This corresponds to specifying nInBufferSize
.
Sourcepub fn create(&self, addr: impl AsRef<OsStr>) -> Result<NamedPipeServer>
pub fn create(&self, addr: impl AsRef<OsStr>) -> Result<NamedPipeServer>
Creates the named pipe identified by addr
for use as a server.
This uses the CreateNamedPipe
function.
§Errors
This errors if called outside of a Tokio Runtime, or in a runtime that has not enabled I/O, or if any OS-specific I/O errors occur.
§Examples
use tokio::net::windows::named_pipe::ServerOptions;
const PIPE_NAME: &str = r"\\.\pipe\tokio-named-pipe-create";
let server = ServerOptions::new().create(PIPE_NAME)?;
Sourcepub unsafe fn create_with_security_attributes_raw(
&self,
addr: impl AsRef<OsStr>,
attrs: *mut c_void,
) -> Result<NamedPipeServer>
pub unsafe fn create_with_security_attributes_raw( &self, addr: impl AsRef<OsStr>, attrs: *mut c_void, ) -> Result<NamedPipeServer>
Creates the named pipe identified by addr
for use as a server.
This is the same as create
except that it supports providing the raw
pointer to a structure of SECURITY_ATTRIBUTES
which will be passed
as the lpSecurityAttributes
argument to CreateFile
.
§Errors
This errors if called outside of a Tokio Runtime, or in a runtime that has not enabled I/O, or if any OS-specific I/O errors occur.
§Safety
The attrs
argument must either be null or point at a valid instance of
the SECURITY_ATTRIBUTES
structure. If the argument is null, the
behavior is identical to calling the create
method.
Trait Implementations§
Source§impl Clone for ServerOptions
impl Clone for ServerOptions
Source§fn clone(&self) -> ServerOptions
fn clone(&self) -> ServerOptions
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreAuto Trait Implementations§
impl Freeze for ServerOptions
impl RefUnwindSafe for ServerOptions
impl Send for ServerOptions
impl Sync for ServerOptions
impl Unpin for ServerOptions
impl UnwindSafe for ServerOptions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)Layout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...)
attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 24 bytes