Skip to content

Commit 90e3c3a

Browse files
authored
unistd: make getpeereid take AsFd rather than a raw FD (#2137)
* unistd: make getpeereid take AsFd rather than a raw FD `AsFd` returns a `BorrowedFd` that is correct by construction, meaning that this API rejects more error states at the type level (such as passing in `fd = -1`). * CHANGELOG: record changes * unistd: pass AsFd impl by value * unistd: more AsFd usage * CHANGELOG: update changes
1 parent 154a8a4 commit 90e3c3a

File tree

4 files changed

+45
-45
lines changed

4 files changed

+45
-45
lines changed

CHANGELOG.md

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,21 @@
33
All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](https://semver.org/).
55

6+
## [Unreleased] - ReleaseDate
7+
8+
### Changed
9+
10+
- The following APIs now take an implementation of `AsFd` rather than a
11+
`RawFd`:
12+
13+
- `unistd::tcgetpgrp`
14+
- `unistd::tcsetpgrp`
15+
- `unistd::fpathconf`
16+
- `unistd::ttyname`
17+
- `unistd::getpeereid`
18+
19+
([#2137](https://github.com/nix-rust/nix/pull/2137))
20+
621
## [0.27.1] - 2023-08-28
722

823
### Fixed
@@ -99,7 +114,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
99114
## [0.26.3] - 2023-08-27
100115

101116
### Fixed
102-
- Fix: send `ETH_P_ALL` in htons format
117+
- Fix: send `ETH_P_ALL` in htons format
103118
([#1925](https://github.com/nix-rust/nix/pull/1925))
104119
- Fix: `recvmsg` now sets the length of the received `sockaddr_un` field
105120
correctly on Linux platforms. ([#2041](https://github.com/nix-rust/nix/pull/2041))
@@ -187,7 +202,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
187202
([#1824](https://github.com/nix-rust/nix/pull/1824))
188203
- Workaround XNU bug causing netmasks returned by `getifaddrs` to misbehave.
189204
([#1788](https://github.com/nix-rust/nix/pull/1788))
190-
205+
191206
### Removed
192207

193208
- Removed deprecated error constants and conversions.

src/sys/socket/sockopt.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,11 @@ cfg_if! {
550550
TcpMaxSeg, GetOnly, libc::IPPROTO_TCP, libc::TCP_MAXSEG, u32);
551551
}
552552
}
553-
#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "redox")))]
553+
#[cfg(not(any(
554+
target_os = "openbsd",
555+
target_os = "haiku",
556+
target_os = "redox"
557+
)))]
554558
#[cfg(feature = "net")]
555559
sockopt_impl!(
556560
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
@@ -572,7 +576,11 @@ sockopt_impl!(
572576
libc::TCP_REPAIR,
573577
u32
574578
);
575-
#[cfg(not(any(target_os = "openbsd", target_os = "haiku", target_os = "redox")))]
579+
#[cfg(not(any(
580+
target_os = "openbsd",
581+
target_os = "haiku",
582+
target_os = "redox"
583+
)))]
576584
#[cfg(feature = "net")]
577585
sockopt_impl!(
578586
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]

src/unistd.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -366,8 +366,8 @@ feature! {
366366
/// Get the group process id (GPID) of the foreground process group on the
367367
/// terminal associated to file descriptor (FD).
368368
#[inline]
369-
pub fn tcgetpgrp(fd: c_int) -> Result<Pid> {
370-
let res = unsafe { libc::tcgetpgrp(fd) };
369+
pub fn tcgetpgrp<F: AsFd>(fd: F) -> Result<Pid> {
370+
let res = unsafe { libc::tcgetpgrp(fd.as_fd().as_raw_fd()) };
371371
Errno::result(res).map(Pid)
372372
}
373373
/// Set the terminal foreground process group (see
@@ -376,8 +376,8 @@ pub fn tcgetpgrp(fd: c_int) -> Result<Pid> {
376376
/// Get the group process id (PGID) to the foreground process group on the
377377
/// terminal associated to file descriptor (FD).
378378
#[inline]
379-
pub fn tcsetpgrp(fd: c_int, pgrp: Pid) -> Result<()> {
380-
let res = unsafe { libc::tcsetpgrp(fd, pgrp.into()) };
379+
pub fn tcsetpgrp<F: AsFd>(fd: F, pgrp: Pid) -> Result<()> {
380+
let res = unsafe { libc::tcsetpgrp(fd.as_fd().as_raw_fd(), pgrp.into()) };
381381
Errno::result(res).map(drop)
382382
}
383383
}
@@ -2192,10 +2192,10 @@ pub enum PathconfVar {
21922192
/// - `Ok(None)`: the variable has no limit (for limit variables) or is
21932193
/// unsupported (for option variables)
21942194
/// - `Err(x)`: an error occurred
2195-
pub fn fpathconf(fd: RawFd, var: PathconfVar) -> Result<Option<c_long>> {
2195+
pub fn fpathconf<F: AsFd>(fd: F, var: PathconfVar) -> Result<Option<c_long>> {
21962196
let raw = unsafe {
21972197
Errno::clear();
2198-
libc::fpathconf(fd, var as c_int)
2198+
libc::fpathconf(fd.as_fd().as_raw_fd(), var as c_int)
21992199
};
22002200
if raw == -1 {
22012201
if errno::errno() == 0 {
@@ -3913,12 +3913,12 @@ feature! {
39133913
/// Get the name of the terminal device that is open on file descriptor fd
39143914
/// (see [`ttyname(3)`](https://man7.org/linux/man-pages/man3/ttyname.3.html)).
39153915
#[cfg(not(target_os = "fuchsia"))]
3916-
pub fn ttyname(fd: RawFd) -> Result<PathBuf> {
3916+
pub fn ttyname<F: AsFd>(fd: F) -> Result<PathBuf> {
39173917
const PATH_MAX: usize = libc::PATH_MAX as usize;
39183918
let mut buf = vec![0_u8; PATH_MAX];
39193919
let c_buf = buf.as_mut_ptr() as *mut libc::c_char;
39203920

3921-
let ret = unsafe { libc::ttyname_r(fd, c_buf, buf.len()) };
3921+
let ret = unsafe { libc::ttyname_r(fd.as_fd().as_raw_fd(), c_buf, buf.len()) };
39223922
if ret != 0 {
39233923
return Err(Errno::from_i32(ret));
39243924
}
@@ -3943,11 +3943,11 @@ feature! {
39433943
target_os = "netbsd",
39443944
target_os = "dragonfly",
39453945
))]
3946-
pub fn getpeereid(fd: RawFd) -> Result<(Uid, Gid)> {
3946+
pub fn getpeereid<F: AsFd>(fd: F) -> Result<(Uid, Gid)> {
39473947
let mut uid = 1;
39483948
let mut gid = 1;
39493949

3950-
let ret = unsafe { libc::getpeereid(fd, &mut uid, &mut gid) };
3950+
let ret = unsafe { libc::getpeereid(fd.as_fd().as_raw_fd(), &mut uid, &mut gid) };
39513951

39523952
Errno::result(ret).map(|_| (Uid(uid), Gid(gid)))
39533953
}

test/test_unistd.rs

Lines changed: 8 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ fn test_acct() {
635635
fn test_fpathconf_limited() {
636636
let f = tempfile().unwrap();
637637
// AFAIK, PATH_MAX is limited on all platforms, so it makes a good test
638-
let path_max = fpathconf(f.as_raw_fd(), PathconfVar::PATH_MAX);
638+
let path_max = fpathconf(f, PathconfVar::PATH_MAX);
639639
assert!(
640640
path_max
641641
.expect("fpathconf failed")
@@ -1230,9 +1230,11 @@ fn test_ttyname() {
12301230
grantpt(&fd).expect("grantpt failed");
12311231
unlockpt(&fd).expect("unlockpt failed");
12321232
let sname = unsafe { ptsname(&fd) }.expect("ptsname failed");
1233-
let fds = open(Path::new(&sname), OFlag::O_RDWR, stat::Mode::empty())
1233+
let fds = fs::OpenOptions::new()
1234+
.read(true)
1235+
.write(true)
1236+
.open(Path::new(&sname))
12341237
.expect("open failed");
1235-
assert!(fds > 0);
12361238

12371239
let name = ttyname(fds).expect("ttyname failed");
12381240
assert!(name.starts_with("/dev"));
@@ -1242,18 +1244,7 @@ fn test_ttyname() {
12421244
#[cfg(not(any(target_os = "redox", target_os = "fuchsia")))]
12431245
fn test_ttyname_not_pty() {
12441246
let fd = File::open("/dev/zero").unwrap();
1245-
assert!(fd.as_raw_fd() > 0);
1246-
assert_eq!(ttyname(fd.as_raw_fd()), Err(Errno::ENOTTY));
1247-
}
1248-
1249-
#[test]
1250-
#[cfg(not(any(
1251-
target_os = "redox",
1252-
target_os = "fuchsia",
1253-
target_os = "haiku"
1254-
)))]
1255-
fn test_ttyname_invalid_fd() {
1256-
assert_eq!(ttyname(-1), Err(Errno::EBADF));
1247+
assert_eq!(ttyname(fd), Err(Errno::ENOTTY));
12571248
}
12581249

12591250
#[test]
@@ -1269,8 +1260,8 @@ fn test_getpeereid() {
12691260
use std::os::unix::net::UnixStream;
12701261
let (sock_a, sock_b) = UnixStream::pair().unwrap();
12711262

1272-
let (uid_a, gid_a) = getpeereid(sock_a.as_raw_fd()).unwrap();
1273-
let (uid_b, gid_b) = getpeereid(sock_b.as_raw_fd()).unwrap();
1263+
let (uid_a, gid_a) = getpeereid(sock_a).unwrap();
1264+
let (uid_b, gid_b) = getpeereid(sock_b).unwrap();
12741265

12751266
let uid = geteuid();
12761267
let gid = getegid();
@@ -1281,20 +1272,6 @@ fn test_getpeereid() {
12811272
assert_eq!(gid_a, gid_b);
12821273
}
12831274

1284-
#[test]
1285-
#[cfg(any(
1286-
target_os = "macos",
1287-
target_os = "ios",
1288-
target_os = "freebsd",
1289-
target_os = "openbsd",
1290-
target_os = "netbsd",
1291-
target_os = "dragonfly",
1292-
))]
1293-
fn test_getpeereid_invalid_fd() {
1294-
// getpeereid is not POSIX, so error codes are inconsistent between different Unices.
1295-
getpeereid(-1).expect_err("assertion failed");
1296-
}
1297-
12981275
#[test]
12991276
#[cfg(not(target_os = "redox"))]
13001277
fn test_faccessat_none_not_existing() {

0 commit comments

Comments
 (0)