cdns-rs 2.0.0-next.0

A native Sync/Async Rust implementation of client DNS resolver.
Documentation
/*-
 * cdns-rs - a simple sync/async DNS query library
 * 
 * Copyright (C) 2021  Aleksandr Morozov
 * Copyright (C) 2025  Aleksandr Morozov
 * Copyright (C) 2026  Aleksandr Morozov, 4neko.org
 * 
 * The syslog-rs crate can be redistributed and/or modified
 * under the terms of either of the following licenses:
 *
 *   1. the Mozilla Public License Version 2.0 (the “MPL”) OR
 *
 *   2. The MIT License (MIT)
 *                     
 *   3. EUROPEAN UNION PUBLIC LICENCE v. 1.2 EUPL © the European Union 2007, 2016
 */

use std::{os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd}, path::Path};

use nix::sys::inotify::{AddWatchFlags, InitFlags, Inotify, WatchDescriptor};

use crate::{CDnsErrorType, CDnsResult, internal_error_map};

#[derive(Debug)]
pub struct FileNotifyDescr(WatchDescriptor);

#[derive(Debug)]
pub struct FileNotify
{
    notif: Inotify,
}

impl AsFd for FileNotify
{
    fn as_fd(&self) -> BorrowedFd<'_> 
    {
        return self.notif.as_fd();
    }
}

impl AsRawFd for FileNotify
{
    fn as_raw_fd(&self) -> RawFd 
    {
        return self.notif.as_fd().as_raw_fd();
    }
}

impl FileNotify
{
    pub 
    fn init() -> CDnsResult<Self>
    {
        let notif = 
            Inotify::init(InitFlags::IN_CLOEXEC | InitFlags::IN_NONBLOCK)
                .map_err(|e|
                    internal_error_map!(CDnsErrorType::IoError, "Inotify init error '{}'", e)
                )?;

        return Ok(
            Self{ notif: notif }
        );
    }

    pub 
    fn add(&self, path: &Path) -> CDnsResult<FileNotifyDescr>
    {
        let wd = 
            self.notif.add_watch(path, AddWatchFlags::IN_MODIFY)
                .map_err(|e|
                    internal_error_map!(CDnsErrorType::IoError, "Inotify add_watch() file: '{}' error '{}'",  
                        path.display(), e)
                )?;

        return Ok(FileNotifyDescr(wd));
    }

    pub 
    fn read_events(&self) -> CDnsResult<Vec<FileNotifyDescr>>
    {
        return 
            self.notif.read_events()
                .map_err(|e|
                    internal_error_map!(CDnsErrorType::IoError, "Inotify read_events() error '{}'",  
                        e)
                )
                .map(|inf_vec|
                    inf_vec.into_iter().map(|inf| FileNotifyDescr(inf.wd) ).collect()
                );
    }
}