From c0230a9b3b7bbc7c18cf0ff66e86a4dabdbcf820 Mon Sep 17 00:00:00 2001 From: Luca BRUNO Date: Thu, 22 Jul 2021 07:49:59 +0000 Subject: [PATCH] sys/stat: add a safe wrapper for mknodat(2) This introduces a new `mknodat` helper. Ref: https://pubs.opengroup.org/onlinepubs/9699919799/functions/mknod.html --- CHANGELOG.md | 2 ++ src/sys/stat.rs | 25 +++++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c4bcaf244..df4683bd90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Added `IPV6_V6ONLY` sockopt. (#[1470](https://github.com/nix-rust/nix/pull/1470)) +- Added `mknodat`. + (#[1473](https://github.com/nix-rust/nix/pull/1473)) ### Changed diff --git a/src/sys/stat.rs b/src/sys/stat.rs index 15451e7876..c797576e52 100644 --- a/src/sys/stat.rs +++ b/src/sys/stat.rs @@ -9,6 +9,7 @@ use std::os::unix::io::RawFd; use crate::sys::time::{TimeSpec, TimeVal}; libc_bitflags!( + /// "File type" flags for `mknod` and related functions. pub struct SFlag: mode_t { S_IFIFO; S_IFCHR; @@ -22,6 +23,7 @@ libc_bitflags!( ); libc_bitflags! { + /// "File mode / permissions" flags. pub struct Mode: mode_t { S_IRWXU; S_IRUSR; @@ -41,11 +43,26 @@ libc_bitflags! { } } +/// Create a special or ordinary file, by pathname. pub fn mknod(path: &P, kind: SFlag, perm: Mode, dev: dev_t) -> Result<()> { - let res = path.with_nix_path(|cstr| { - unsafe { - libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) - } + let res = path.with_nix_path(|cstr| unsafe { + libc::mknod(cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) + })?; + + Errno::result(res).map(drop) +} + +/// Create a special or ordinary file, relative to a given directory. +#[cfg(not(any(target_os = "ios", target_os = "macos", target_os = "redox")))] +pub fn mknodat( + dirfd: RawFd, + path: &P, + kind: SFlag, + perm: Mode, + dev: dev_t, +) -> Result<()> { + let res = path.with_nix_path(|cstr| unsafe { + libc::mknodat(dirfd, cstr.as_ptr(), kind.bits | perm.bits() as mode_t, dev) })?; Errno::result(res).map(drop)