fix(linux): a bare node name opens under /dev

`sg3` (or `sr0` with no sg node) was opened relative to the current
directory. It now opens /dev/sg3, as the full path does.
This commit is contained in:
Matthew Jackson
2026-10-07 00:33:15 -07:00
parent 959800adec
commit 6acc55b246
3 changed files with 25 additions and 0 deletions
+1
View File
@@ -3,6 +3,7 @@
## [Unreleased]
- Windows: a bare drive letter (`E`) opens that drive, as `E:` does; it was opened as `\\.\E`, which does not exist (E1000).
- Linux: a bare node name (`sg3`, `sr0`) opens `/dev/sg3` / `/dev/sr0`; it was opened relative to the current directory.
## [1.8.1] — 2026-10-07
+8
View File
@@ -235,6 +235,14 @@ impl SgIoTransport {
/// Resolve /dev/sr* -> /dev/sg* via sysfs. If already sg, returns as-is.
/// Falls back to the original path if resolution fails.
fn resolve_to_sg(device: &Path) -> std::path::PathBuf {
// A bare node name (`sr0`, `sg3`) is that node under /dev, as `/dev/sr0` is.
let dev_path;
let device = if device.parent() == Some(Path::new("")) {
dev_path = Path::new("/dev").join(device);
dev_path.as_path()
} else {
device
};
let dev_name = match device.file_name().and_then(|n| n.to_str()) {
Some(n) => n,
None => return device.to_path_buf(),
+16
View File
@@ -10,3 +10,19 @@ fn open_errno_maps_to_its_real_cause() {
assert!(matches!(map(libc::EMFILE), Error::IoError { .. }));
assert!(matches!(map(libc::EBUSY), Error::IoError { .. }));
}
#[test]
fn a_bare_node_name_opens_under_dev() {
assert_eq!(
SgIoTransport::resolve_to_sg(Path::new("sg3")),
Path::new("/dev/sg3")
);
assert_eq!(
SgIoTransport::resolve_to_sg(Path::new("/dev/sg3")),
Path::new("/dev/sg3")
);
assert_eq!(
SgIoTransport::resolve_to_sg(Path::new("./sg3")),
Path::new("./sg3")
);
}