Skip to content

Commit

Permalink
fix(watcher): Only watch directories that exist.
Browse files Browse the repository at this point in the history
Attempting to watch directories that don't exist (i.e. /sys/bus/iio) crashes the system. Don't do that.
  • Loading branch information
pastaq committed Apr 21, 2024
1 parent b796faf commit e740188
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 93 deletions.
185 changes: 94 additions & 91 deletions src/input/manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1087,105 +1087,108 @@ impl Manager {
let (watcher_tx, mut watcher_rx) = mpsc::channel(BUFFER_SIZE);

// Start watcher thread to listen for hidraw device changes
let tx = watcher_tx.clone();
tokio::task::spawn_blocking(move || {
log::debug!("Started watcher thread");
watcher::watch(DEV_PATH.into(), tx)
});

// Start watcher thread to listen for event device changes
let tx = watcher_tx.clone();
tokio::task::spawn_blocking(move || {
log::debug!("Started watcher thread");
watcher::watch(INPUT_PATH.into(), tx)
});

// Start watcher thread to listen for iio device changes
let tx = watcher_tx.clone();
tokio::task::spawn_blocking(move || {
log::debug!("Started watcher thread");
watcher::watch(IIO_PATH.into(), tx)
});

log::debug!("Performing initial input device discovery");
// Perform an initial hidraw device discovery
let paths = std::fs::read_dir(DEV_PATH)?;
for entry in paths {
if let Err(e) = entry {
log::warn!("Unable to read from directory: {:?}", e);
continue;
}
let path = entry.unwrap().file_name();
let path = path.into_string().ok();
let Some(path) = path else {
continue;
};
if !path.starts_with("hidraw") {
continue;
}
log::debug!("Discovered hidraw device: {:?}", path);
let result = watcher_tx
.send(watcher::WatchEvent::Create {
name: path,
base_path: DEV_PATH.into(),
})
.await;
if let Err(e) = result {
log::error!("Unable to send command: {:?}", e);
if std::path::Path::new(DEV_PATH).exists() {
let tx = watcher_tx.clone();
tokio::task::spawn_blocking(move || {
log::debug!("Started watcher thread");
watcher::watch(DEV_PATH.into(), tx)
});
log::debug!("Performing initial input device discovery");
// Perform an initial hidraw device discovery
let paths = std::fs::read_dir(DEV_PATH)?;
for entry in paths {
if let Err(e) = entry {
log::warn!("Unable to read from directory: {:?}", e);
continue;
}
let path = entry.unwrap().file_name();
let path = path.into_string().ok();
let Some(path) = path else {
continue;
};
if !path.starts_with("hidraw") {
continue;
}
log::debug!("Discovered hidraw device: {:?}", path);
let result = watcher_tx
.send(watcher::WatchEvent::Create {
name: path,
base_path: DEV_PATH.into(),
})
.await;
if let Err(e) = result {
log::error!("Unable to send command: {:?}", e);
}
}
}

// Perform an initial event device discovery
let paths = std::fs::read_dir(INPUT_PATH)?;
for entry in paths {
if let Err(e) = entry {
log::warn!("Unable to read from directory: {:?}", e);
continue;
}
let path = entry.unwrap().file_name();
let path = path.into_string().ok();
let Some(path) = path else {
continue;
};
if !path.starts_with("event") {
continue;
}
log::debug!("Discovered event device: {:?}", path);
let result = watcher_tx
.send(watcher::WatchEvent::Create {
name: path,
base_path: INPUT_PATH.into(),
})
.await;
if let Err(e) = result {
log::error!("Unable to send command: {:?}", e);
// Start watcher thread to listen for event device changes
if std::path::Path::new(INPUT_PATH).exists() {
let tx = watcher_tx.clone();
tokio::task::spawn_blocking(move || {
log::debug!("Started watcher thread");
watcher::watch(INPUT_PATH.into(), tx)
});
// Perform an initial event device discovery
let paths = std::fs::read_dir(INPUT_PATH)?;
for entry in paths {
if let Err(e) = entry {
log::warn!("Unable to read from directory: {:?}", e);
continue;
}
let path = entry.unwrap().file_name();
let path = path.into_string().ok();
let Some(path) = path else {
continue;
};
if !path.starts_with("event") {
continue;
}
log::debug!("Discovered event device: {:?}", path);
let result = watcher_tx
.send(watcher::WatchEvent::Create {
name: path,
base_path: INPUT_PATH.into(),
})
.await;
if let Err(e) = result {
log::error!("Unable to send command: {:?}", e);
}
}
}

// Perform an initial iio device discovery
let paths = std::fs::read_dir(IIO_PATH)?;
for entry in paths {
if let Err(e) = entry {
log::warn!("Unable to read from directory: {:?}", e);
continue;
}
let path = entry.unwrap().file_name();
let path = path.into_string().ok();
let Some(path) = path else {
continue;
};
log::debug!("Discovered iio device: {:?}", path);
let result = watcher_tx
.send(watcher::WatchEvent::Create {
name: path,
base_path: IIO_PATH.into(),
})
.await;
if let Err(e) = result {
log::error!("Unable to send command: {:?}", e);
// Start watcher thread to listen for iio device changes
if std::path::Path::new(IIO_PATH).exists() {
let tx = watcher_tx.clone();
tokio::task::spawn_blocking(move || {
log::debug!("Started watcher thread");
watcher::watch(IIO_PATH.into(), tx)
});

// Perform an initial iio device discovery
let paths = std::fs::read_dir(IIO_PATH)?;
for entry in paths {
if let Err(e) = entry {
log::warn!("Unable to read from directory: {:?}", e);
continue;
}
let path = entry.unwrap().file_name();
let path = path.into_string().ok();
let Some(path) = path else {
continue;
};
log::debug!("Discovered iio device: {:?}", path);
let result = watcher_tx
.send(watcher::WatchEvent::Create {
name: path,
base_path: IIO_PATH.into(),
})
.await;
if let Err(e) = result {
log::error!("Unable to send command: {:?}", e);
}
}
}

log::debug!("Initial input device discovery complete");

// Start a task to dispatch filesystem watch events to the `run()` loop
Expand Down
10 changes: 8 additions & 2 deletions src/watcher/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,16 @@ pub enum WatchEvent {
pub fn watch(path: String, tx: Sender<WatchEvent>) {
let mut inotify = Inotify::init().expect("Failed to initialize inotify");

inotify
if let Err(e) = inotify
.watches()
.add(path.clone(), WatchMask::CREATE | WatchMask::DELETE)
.expect("Failed to add inotify watch");
{
log::error!(
"Unable to add inotify wather for path: {path}. Got error {:?}",
e
);
return;
}

// Listen for watch events
let mut buffer = [0u8; 4096];
Expand Down

0 comments on commit e740188

Please sign in to comment.