Skip to content

Commit e8fb0d4

Browse files
bors[bot]asomers
andauthored
Merge #1159
1159: impl TryFrom<libc::speed_t> for BaudRate r=asomers a=asomers The old From implementation was actually falliable, and would panic on failure. Co-authored-by: Alan Somers <[email protected]>
2 parents 50374c6 + 138f4cb commit e8fb0d4

File tree

2 files changed

+60
-43
lines changed

2 files changed

+60
-43
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
3737
injection. ([#1083](https://github.com/nix-rust/nix/pull/1083))
3838

3939
### Changed
40+
- `sys::termios::BaudRate` now implements `TryFrom<speed_t>` instead of
41+
`From<speed_t>`. The old `From` implementation would panic on failure.
42+
([#1159](https://github.com/nix-rust/nix/pull/1159))
43+
4044
- `sys::socket::recvmsg` now takes a plain `Vec` instead of a `CmsgBuffer`
4145
implementor. If you were already using `cmsg_space!`, then you needn't worry.
4246
([#1156](https://github.com/nix-rust/nix/pull/1156))

src/sys/termios.rs

Lines changed: 56 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -161,11 +161,11 @@
161161
//! cfsetspeed(&mut t, 9600u32);
162162
//! # }
163163
//! ```
164-
use Result;
164+
use {Error, Result};
165165
use errno::Errno;
166166
use libc::{self, c_int, tcflag_t};
167167
use std::cell::{Ref, RefCell};
168-
use std::convert::From;
168+
use std::convert::{From, TryFrom};
169169
use std::mem;
170170
use std::os::unix::io::RawFd;
171171

@@ -376,9 +376,10 @@ libc_enum!{
376376
}
377377
}
378378

379-
impl From<libc::speed_t> for BaudRate {
380-
fn from(s: libc::speed_t) -> BaudRate {
379+
impl TryFrom<libc::speed_t> for BaudRate {
380+
type Error = Error;
381381

382+
fn try_from(s: libc::speed_t) -> Result<BaudRate> {
382383
use libc::{B0, B50, B75, B110, B134, B150, B200, B300, B600, B1200, B1800, B2400, B4800,
383384
B9600, B19200, B38400, B57600, B115200, B230400};
384385
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -398,85 +399,84 @@ impl From<libc::speed_t> for BaudRate {
398399
use libc::{B460800, B921600};
399400

400401
match s {
401-
B0 => BaudRate::B0,
402-
B50 => BaudRate::B50,
403-
B75 => BaudRate::B75,
404-
B110 => BaudRate::B110,
405-
B134 => BaudRate::B134,
406-
B150 => BaudRate::B150,
407-
B200 => BaudRate::B200,
408-
B300 => BaudRate::B300,
409-
B600 => BaudRate::B600,
410-
B1200 => BaudRate::B1200,
411-
B1800 => BaudRate::B1800,
412-
B2400 => BaudRate::B2400,
413-
B4800 => BaudRate::B4800,
402+
B0 => Ok(BaudRate::B0),
403+
B50 => Ok(BaudRate::B50),
404+
B75 => Ok(BaudRate::B75),
405+
B110 => Ok(BaudRate::B110),
406+
B134 => Ok(BaudRate::B134),
407+
B150 => Ok(BaudRate::B150),
408+
B200 => Ok(BaudRate::B200),
409+
B300 => Ok(BaudRate::B300),
410+
B600 => Ok(BaudRate::B600),
411+
B1200 => Ok(BaudRate::B1200),
412+
B1800 => Ok(BaudRate::B1800),
413+
B2400 => Ok(BaudRate::B2400),
414+
B4800 => Ok(BaudRate::B4800),
414415
#[cfg(any(target_os = "dragonfly",
415416
target_os = "freebsd",
416417
target_os = "macos",
417418
target_os = "netbsd",
418419
target_os = "openbsd"))]
419-
B7200 => BaudRate::B7200,
420-
B9600 => BaudRate::B9600,
420+
B7200 => Ok(BaudRate::B7200),
421+
B9600 => Ok(BaudRate::B9600),
421422
#[cfg(any(target_os = "dragonfly",
422423
target_os = "freebsd",
423424
target_os = "macos",
424425
target_os = "netbsd",
425426
target_os = "openbsd"))]
426-
B14400 => BaudRate::B14400,
427-
B19200 => BaudRate::B19200,
427+
B14400 => Ok(BaudRate::B14400),
428+
B19200 => Ok(BaudRate::B19200),
428429
#[cfg(any(target_os = "dragonfly",
429430
target_os = "freebsd",
430431
target_os = "macos",
431432
target_os = "netbsd",
432433
target_os = "openbsd"))]
433-
B28800 => BaudRate::B28800,
434-
B38400 => BaudRate::B38400,
435-
B57600 => BaudRate::B57600,
434+
B28800 => Ok(BaudRate::B28800),
435+
B38400 => Ok(BaudRate::B38400),
436+
B57600 => Ok(BaudRate::B57600),
436437
#[cfg(any(target_os = "dragonfly",
437438
target_os = "freebsd",
438439
target_os = "macos",
439440
target_os = "netbsd",
440441
target_os = "openbsd"))]
441-
B76800 => BaudRate::B76800,
442-
B115200 => BaudRate::B115200,
443-
B230400 => BaudRate::B230400,
442+
B76800 => Ok(BaudRate::B76800),
443+
B115200 => Ok(BaudRate::B115200),
444+
B230400 => Ok(BaudRate::B230400),
444445
#[cfg(any(target_os = "android",
445446
target_os = "freebsd",
446447
target_os = "linux",
447448
target_os = "netbsd"))]
448-
B460800 => BaudRate::B460800,
449+
B460800 => Ok(BaudRate::B460800),
449450
#[cfg(any(target_os = "android", target_os = "linux"))]
450-
B500000 => BaudRate::B500000,
451+
B500000 => Ok(BaudRate::B500000),
451452
#[cfg(any(target_os = "android", target_os = "linux"))]
452-
B576000 => BaudRate::B576000,
453+
B576000 => Ok(BaudRate::B576000),
453454
#[cfg(any(target_os = "android",
454455
target_os = "freebsd",
455456
target_os = "linux",
456457
target_os = "netbsd"))]
457-
B921600 => BaudRate::B921600,
458+
B921600 => Ok(BaudRate::B921600),
458459
#[cfg(any(target_os = "android", target_os = "linux"))]
459-
B1000000 => BaudRate::B1000000,
460+
B1000000 => Ok(BaudRate::B1000000),
460461
#[cfg(any(target_os = "android", target_os = "linux"))]
461-
B1152000 => BaudRate::B1152000,
462+
B1152000 => Ok(BaudRate::B1152000),
462463
#[cfg(any(target_os = "android", target_os = "linux"))]
463-
B1500000 => BaudRate::B1500000,
464+
B1500000 => Ok(BaudRate::B1500000),
464465
#[cfg(any(target_os = "android", target_os = "linux"))]
465-
B2000000 => BaudRate::B2000000,
466+
B2000000 => Ok(BaudRate::B2000000),
466467
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
467-
B2500000 => BaudRate::B2500000,
468+
B2500000 => Ok(BaudRate::B2500000),
468469
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
469-
B3000000 => BaudRate::B3000000,
470+
B3000000 => Ok(BaudRate::B3000000),
470471
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
471-
B3500000 => BaudRate::B3500000,
472+
B3500000 => Ok(BaudRate::B3500000),
472473
#[cfg(any(target_os = "android", all(target_os = "linux", not(target_arch = "sparc64"))))]
473-
B4000000 => BaudRate::B4000000,
474-
b => unreachable!("Invalid baud constant: {}", b),
474+
B4000000 => Ok(BaudRate::B4000000),
475+
_ => Err(Error::invalid_argument())
475476
}
476477
}
477478
}
478479

479-
// TODO: Include `TryFrom<u32> for BaudRate` once that API stabilizes
480480
#[cfg(any(target_os = "freebsd",
481481
target_os = "dragonfly",
482482
target_os = "ios",
@@ -963,13 +963,15 @@ cfg_if!{
963963
Errno::result(res).map(drop)
964964
}
965965
} else {
966+
use std::convert::TryInto;
967+
966968
/// Get input baud rate (see
967969
/// [cfgetispeed(3p)](http://pubs.opengroup.org/onlinepubs/9699919799/functions/cfgetispeed.html)).
968970
///
969971
/// `cfgetispeed()` extracts the input baud rate from the given `Termios` structure.
970972
pub fn cfgetispeed(termios: &Termios) -> BaudRate {
971973
let inner_termios = termios.get_libc_termios();
972-
unsafe { libc::cfgetispeed(&*inner_termios) }.into()
974+
unsafe { libc::cfgetispeed(&*inner_termios) }.try_into().unwrap()
973975
}
974976

975977
/// Get output baud rate (see
@@ -978,7 +980,7 @@ cfg_if!{
978980
/// `cfgetospeed()` extracts the output baud rate from the given `Termios` structure.
979981
pub fn cfgetospeed(termios: &Termios) -> BaudRate {
980982
let inner_termios = termios.get_libc_termios();
981-
unsafe { libc::cfgetospeed(&*inner_termios) }.into()
983+
unsafe { libc::cfgetospeed(&*inner_termios) }.try_into().unwrap()
982984
}
983985

984986
/// Set input baud rate (see
@@ -1111,3 +1113,14 @@ pub fn tcgetsid(fd: RawFd) -> Result<Pid> {
11111113

11121114
Errno::result(res).map(Pid::from_raw)
11131115
}
1116+
1117+
#[cfg(test)]
1118+
mod test {
1119+
use super::*;
1120+
1121+
#[test]
1122+
fn try_from() {
1123+
assert_eq!(Ok(BaudRate::B0), BaudRate::try_from(libc::B0));
1124+
assert!(BaudRate::try_from(999999999).is_err());
1125+
}
1126+
}

0 commit comments

Comments
 (0)