Commit 4aed7262 authored by Bryant's avatar Bryant

Merge branch 'musl_list_ports' into 'master'

Implement available_ports() for the remaining Linux targets

Closes #63

See merge request susurrus/serialport-rs!72
parents 50a7c566 4d091b6b
......@@ -9,6 +9,8 @@ and this project adheres to http://semver.org/[Semantic Versioning].
==== Changed
==== Added
* Added `send_break()` to `TTYPort`
* Enable `available_ports()` for Linux musl targets and those without the `libudev`
feature enabled by scanning `/sys/` for ports.
==== Fixed
==== Removed
......
......@@ -3,43 +3,47 @@ extern crate serialport;
use serialport::SerialPortType;
fn main() {
if let Ok(ports) = serialport::available_ports() {
match ports.len() {
0 => println!("No ports found."),
1 => println!("Found 1 port:"),
n => println!("Found {} ports:", n),
};
for p in ports {
println!(" {}", p.port_name);
match p.port_type {
SerialPortType::UsbPort(info) => {
println!(" Type: USB");
println!(" VID:{:04x} PID:{:04x}", info.vid, info.pid);
println!(
" Serial Number: {}",
info.serial_number.as_ref().map_or("", String::as_str)
);
println!(
" Manufacturer: {}",
info.manufacturer.as_ref().map_or("", String::as_str)
);
println!(
" Product: {}",
info.product.as_ref().map_or("", String::as_str)
);
}
SerialPortType::BluetoothPort => {
println!(" Type: Bluetooth");
}
SerialPortType::PciPort => {
println!(" Type: PCI");
}
SerialPortType::Unknown => {
println!(" Type: Unknown");
match serialport::available_ports() {
Ok(ports) => {
match ports.len() {
0 => println!("No ports found."),
1 => println!("Found 1 port:"),
n => println!("Found {} ports:", n),
};
for p in ports {
println!(" {}", p.port_name);
match p.port_type {
SerialPortType::UsbPort(info) => {
println!(" Type: USB");
println!(" VID:{:04x} PID:{:04x}", info.vid, info.pid);
println!(
" Serial Number: {}",
info.serial_number.as_ref().map_or("", String::as_str)
);
println!(
" Manufacturer: {}",
info.manufacturer.as_ref().map_or("", String::as_str)
);
println!(
" Product: {}",
info.product.as_ref().map_or("", String::as_str)
);
}
SerialPortType::BluetoothPort => {
println!(" Type: Bluetooth");
}
SerialPortType::PciPort => {
println!(" Type: PCI");
}
SerialPortType::Unknown => {
println!(" Type: Unknown");
}
}
}
}
} else {
print!("Error listing serial ports");
Err(e) => {
eprintln!("{:?}", e);
eprintln!("Error listing serial ports");
}
}
}
......@@ -584,13 +584,13 @@ pub fn open_with_settings<T: AsRef<OsStr> + ?Sized>(
/// It is not guaranteed that these ports exist or are available even if they're
/// returned by this function.
pub fn available_ports() -> Result<Vec<SerialPortInfo>> {
#[cfg(all(unix, not(target_env = "musl")))]
#[cfg(unix)]
return crate::posix::available_ports();
#[cfg(windows)]
return crate::windows::available_ports();
#[cfg(any(not(any(unix, windows)), target_env = "musl"))]
#[cfg(not(any(unix, windows)))]
Err(Error::new(
ErrorKind::Unknown,
"available_ports() not implemented for platform",
......
......@@ -23,7 +23,7 @@ use crate::posix::ioctl::{self, SerialLines};
#[cfg(any(
target_os = "freebsd",
target_os = "ios",
all(target_os = "linux", not(target_env = "musl"), feature = "libudev"),
target_os = "linux",
target_os = "macos"
))]
use crate::SerialPortType;
......@@ -1256,14 +1256,39 @@ cfg_if! {
}
Ok(vec)
}
} else if #[cfg(all(target_os = "linux", not(target_env = "musl")))] {
} else if #[cfg(target_os = "linux")] {
use std::fs::File;
use std::io::Read;
/// Enumerating serial ports on non-Linux POSIX platforms is disabled by disabled the "libudev"
/// default feature.
pub fn available_ports() -> Result<Vec<SerialPortInfo>> {
Err(Error::new(
ErrorKind::Unknown,
"Serial port enumeration disabled (to enable compile with the 'libudev' feature)",
))
let mut vec = Vec::new();
let sys_path = Path::new("/sys/class/tty/");
let mut s;
for path in sys_path.read_dir().expect("/sys/class/tty/ doesn't exist on this system") {
let raw_path = path?.path().clone();
let mut path = raw_path.clone();
path.push("device");
if !path.is_dir() {
continue;
}
path.push("driver_override");
if path.is_file() {
s = String::new();
File::open(path)?.read_to_string(&mut s)?;
if &s == "(null)\n" {
continue;
}
}
vec.push(SerialPortInfo {
port_name: raw_path.to_string_lossy().to_string(),
port_type: SerialPortType::Unknown,
});
}
Ok(vec)
}
} else if #[cfg(target_os = "freebsd")] {
/// Scans the system for serial ports and returns a list of them.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment