Skip to main content

FileResolver

Struct FileResolver 

Source
pub struct FileResolver { /* private fields */ }
Expand description

Manages /etc/resolver/<domain> files.

§Lifecycle

  1. register writes a resolver file.
  2. macOS picks it up immediately (no restart needed).
  3. unregister removes the file on shutdown.

§Crash recovery

If the process exits without calling unregister, the file persists. On next startup, call cleanup_orphaned to remove files whose creating PID is no longer running.

§Permissions

/etc/resolver/ requires root. The caller must handle elevation.

§Example

use macos_resolver::{FileResolver, ResolverConfig};

let resolver = FileResolver::new("myapp");
resolver.register(&ResolverConfig::new("myapp.local", "127.0.0.1", 5553))?;
// ...
resolver.unregister("myapp.local")?;

Implementations§

Source§

impl FileResolver

Source

pub fn new(prefix: &str) -> Self

Creates a resolver targeting the default /etc/resolver directory.

prefix is used for two purposes:

  1. Marker comment — files are tagged with # managed by <prefix>.
  2. Environment variable namespace{PREFIX}_RESOLVER_DIR overrides the default /etc/resolver directory (prefix is uppercased, -_).
Source

pub fn with_marker(marker: impl Into<String>) -> Self

Creates a resolver with an exact marker string (written as-is).

Use this when you need full control over the marker comment.

Source

pub fn dir(self, resolver_dir: impl Into<PathBuf>) -> Self

Overrides the resolver directory (useful for testing).

Source

pub fn resolver_dir(&self) -> &Path

Returns the resolver directory path.

Source

pub fn marker(&self) -> &str

Returns the marker string used to identify managed files.

Source

pub fn register(&self, config: &ResolverConfig) -> Result<()>

Writes /etc/resolver/<domain> with the given configuration.

The file contains a marker with the current PID for orphan detection. Calling this again for the same domain overwrites the previous file.

§Errors

Returns ResolverError::Io if the directory cannot be created or the file cannot be written.

Source

pub fn register_permanent(&self, config: &ResolverConfig) -> Result<()>

Writes /etc/resolver/<domain> as a permanent (static) entry.

Unlike register, this does not embed a PID in the marker comment. The file is therefore immune to cleanup_orphaned (which skips files without a PID) and survives daemon restarts.

Intended for one-time installation commands (e.g. sudo myapp dns install).

§Errors

Returns ResolverError::Io if the directory cannot be created or the file cannot be written.

Source

pub fn unregister(&self, domain: &str) -> Result<()>

Removes /etc/resolver/<domain>.

Only removes files that contain the ownership marker. Files created by other tools are left untouched and a ResolverError::NotManaged error is returned.

If the file does not exist, this is a no-op.

§Errors

Returns ResolverError::Io on I/O failure, or ResolverError::NotManaged if the file belongs to another tool.

Source

pub fn list(&self) -> Result<Vec<String>>

Lists all domains with a managed resolver file.

Returns an empty vec if the directory does not exist.

§Errors

Returns ResolverError::Io if the directory cannot be read.

Source

pub fn is_registered(&self, domain: &str) -> bool

Returns true if domain has a managed resolver file on disk.

Source

pub fn cleanup_orphaned(&self) -> Result<usize>

Removes resolver files whose creating PID is no longer running.

Returns the number of files removed. Non-managed files and files belonging to still-alive processes are left untouched. Permanent files (no PID) are also left untouched.

§Errors

Returns ResolverError::Io if the directory cannot be read.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more