Packages
nerves_runtime
0.9.3
0.13.13
0.13.12
0.13.11
retired
0.13.10
0.13.9
0.13.8
0.13.7
0.13.6
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.12.0
0.11.10
0.11.9
0.11.8
0.11.7
0.11.6
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.3
0.10.2
0.10.1
0.10.0
retired
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.0
0.7.0
0.6.5
0.6.4
0.6.3
0.6.2
0.6.1
0.6.0
0.5.3
0.5.2
0.5.1
0.5.0
0.4.4
0.4.3
0.4.2
0.4.1
0.4.0
0.3.1
0.3.0
0.2.0
0.1.2
0.1.1
0.1.0
Small, general runtime utilities for Nerves devices
Current section
Files
Jump to
Current section
Files
lib/nerves_runtime/device.ex
defmodule Nerves.Runtime.Device do
@moduledoc """
This is a utility module for triggering UEvents from the Linux kernel. You
don't need to use it directly. See the README.md for receiving events when
devices are added or removed from the system.
"""
@doc """
Send an "add" request to all existing devices so that the UEvent handler
can know about them.
"""
@spec discover() :: :ok
def discover() do
"/sys/devices"
|> find_all_uevent()
|> Enum.each(&invoke_uevent_action(&1, "add"))
end
defp find_all_uevent(dir), do: find_all_uevent(dir, safe_ls(dir), [])
defp find_all_uevent(_dir, [], acc), do: acc
defp find_all_uevent(dir, ["uevent" | rest], acc) do
abs_path = Path.join(dir, "uevent")
find_all_uevent(dir, rest, [abs_path | acc])
end
defp find_all_uevent(dir, [filename | rest], acc) do
abs_path = Path.join(dir, filename)
next_acc =
if true_dir?(abs_path) do
find_all_uevent(abs_path, safe_ls(abs_path), acc)
else
acc
end
find_all_uevent(dir, rest, next_acc)
end
defp true_dir?(path) do
# File.dir?/1 follows symlinks. true_dir?/1 does not.
case File.lstat(path) do
{:ok, stat} -> stat.type == :directory
_ -> false
end
end
defp safe_ls(path) do
case File.ls(path) do
{:ok, files} -> files
_ -> []
end
end
defp invoke_uevent_action(uevent, action) do
File.write(uevent, action)
end
end