Skip to content

Commit

Permalink
Add kernel config parser
Browse files Browse the repository at this point in the history
  • Loading branch information
fhunleth committed Jul 7, 2020
1 parent fdfb38b commit c9ccd3b
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions lib/vintage_net/diagnostics/kernel.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
defmodule VintageNet.Diagnostics.Kernel do
@type config_value :: :built_in | :module | String.t()
@type config_map :: %{String.t() => config_value()}

@doc """
Return the kernel configuration as a map
Only enabled options are returned. Like in the kernel, the symbols are listed
without the `CONFIG_` prefix.
In order to use this function,
the Linux kernel on the device needs to have `IKCONFIG=y` and `IKCONFIG_PROC=y` in
the configuration. Otherwise `/proc/config.gz` doesn't exist.
"""
@spec config(Path.t()) :: {:ok, config_map()} | {:error, File.posix()}
def config(path \\ "/proc/config.gz") do
with {:ok, fd} <- File.open(path, [:compressed]),
{:ok, kv_pairs} <- read_all(fd, []) do
_ = File.close(fd)
{:ok, Map.new(kv_pairs)}
end
end

defp read_all(fd, acc) do
case IO.binread(fd, :line) do
"CONFIG_" <> setting ->
[k, v] = String.split(setting, "=", parts: 2)
read_all(fd, [{k, option(v)} | acc])

:eof ->
{:ok, acc}

{:error, _reason} = error ->
error

_other ->
read_all(fd, acc)
end
end

defp option("y" <> _rest), do: :built_in
defp option("m" <> _rest), do: :module
defp option(other), do: String.trim(other)
end

0 comments on commit c9ccd3b

Please sign in to comment.