Skip to content

Commit 52f4380

Browse files
authored
unistd: allow linkat to take multiple path types (#2582)
Other places in the crate take independent types in use cases like this, so bring `linkat` into line with them. Signed-off-by: Hank Donnay <hdonnay@gmail.com>
1 parent 34bb802 commit 52f4380

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

changelog/2582.changed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
linkat: allow distinct types for path arguments

src/unistd.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,11 +1577,11 @@ impl LinkatFlags {
15771577
/// # References
15781578
/// See also [linkat(2)](https://pubs.opengroup.org/onlinepubs/9699919799/functions/linkat.html)
15791579
#[cfg(not(target_os = "redox"))] // Redox does not have this yet
1580-
pub fn linkat<Fd1: std::os::fd::AsFd, Fd2: std::os::fd::AsFd, P: ?Sized + NixPath>(
1580+
pub fn linkat<Fd1: std::os::fd::AsFd, Fd2: std::os::fd::AsFd, P1: ?Sized + NixPath, P2: ?Sized + NixPath>(
15811581
olddirfd: Fd1,
1582-
oldpath: &P,
1582+
oldpath: &P1,
15831583
newdirfd: Fd2,
1584-
newpath: &P,
1584+
newpath: &P2,
15851585
flag: AtFlags,
15861586
) -> Result<()> {
15871587
use std::os::fd::AsRawFd;

test/test_unistd.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,40 @@ fn test_linkat_file() {
927927
assert!(newfilepath.exists());
928928
}
929929

930+
#[test]
931+
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
932+
/// This test is the same as [test_linkat_file], but ensures that two different types can be used
933+
/// as the path arguments.
934+
fn test_linkat_pathtypes() {
935+
use nix::fcntl::AtFlags;
936+
937+
let tempdir = tempdir().unwrap();
938+
let oldfilename = "foo.txt";
939+
let oldfilepath = tempdir.path().join(oldfilename);
940+
941+
let newfilename = "bar.txt";
942+
let newfilepath = tempdir.path().join(newfilename);
943+
944+
// Create file
945+
File::create(oldfilepath).unwrap();
946+
947+
// Get file descriptor for base directory
948+
let dirfd =
949+
fcntl::open(tempdir.path(), fcntl::OFlag::empty(), stat::Mode::empty())
950+
.unwrap();
951+
952+
// Attempt hard link file at relative path
953+
linkat(
954+
&dirfd,
955+
PathBuf::from(oldfilename).as_path(),
956+
&dirfd,
957+
newfilename,
958+
AtFlags::AT_SYMLINK_FOLLOW,
959+
)
960+
.unwrap();
961+
assert!(newfilepath.exists());
962+
}
963+
930964
#[test]
931965
#[cfg(not(any(target_os = "redox", target_os = "haiku")))]
932966
fn test_linkat_olddirfd_none() {

0 commit comments

Comments
 (0)