sysctl.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2022, Alex Major
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause
  6. */
  7. #include <LibCore/ArgsParser.h>
  8. #include <LibCore/DirIterator.h>
  9. #include <LibCore/File.h>
  10. #include <LibMain/Main.h>
  11. static bool s_set_variable = false;
  12. static DeprecatedString get_variable(StringView name)
  13. {
  14. auto path = DeprecatedString::formatted("/sys/kernel/variables/{}", name);
  15. auto file = Core::File::open(path, Core::File::OpenMode::Read);
  16. if (file.is_error()) {
  17. warnln("Failed to open {}: {}", path, file.error());
  18. return {};
  19. }
  20. auto buffer = file.value()->read_until_eof();
  21. if (buffer.is_error()) {
  22. warnln("Failed to read {}: {}", path, buffer.error());
  23. return {};
  24. }
  25. return { (char const*)buffer.value().data(), buffer.value().size(), Chomp };
  26. }
  27. static bool read_variable(StringView name)
  28. {
  29. auto value = get_variable(name);
  30. if (value.is_null())
  31. return false;
  32. outln("{} = {}", name, value);
  33. return true;
  34. }
  35. static bool write_variable(StringView name, StringView value)
  36. {
  37. auto old_value = get_variable(name);
  38. if (old_value.is_null())
  39. return false;
  40. auto path = DeprecatedString::formatted("/sys/kernel/variables/{}", name);
  41. auto file = Core::File::open(path, Core::File::OpenMode::Write);
  42. if (file.is_error()) {
  43. warnln("Failed to open {}: {}", path, file.error());
  44. return false;
  45. }
  46. if (auto result = file.value()->write_until_depleted(value.bytes()); result.is_error()) {
  47. warnln("Failed to write {}: {}", path, result.error());
  48. return false;
  49. }
  50. outln("{}: {} -> {}", name, old_value, value);
  51. return true;
  52. }
  53. static int handle_variables(Vector<StringView> const& variables)
  54. {
  55. bool success = false;
  56. for (auto const& variable : variables) {
  57. auto maybe_index = variable.find('=');
  58. if (!maybe_index.has_value()) {
  59. success = read_variable(variable);
  60. continue;
  61. }
  62. auto equal_index = maybe_index.release_value();
  63. auto name = variable.substring_view(0, equal_index);
  64. auto value = variable.substring_view(equal_index + 1, variable.length() - equal_index - 1);
  65. if (name.is_empty())
  66. warnln("Malformed setting '{}'", variable);
  67. else if (!s_set_variable)
  68. warnln("Must specify '-w' to set variables");
  69. else
  70. success = write_variable(name, value);
  71. }
  72. return success ? 0 : 1;
  73. }
  74. static int handle_show_all()
  75. {
  76. Core::DirIterator di("/sys/kernel/variables", Core::DirIterator::SkipDots);
  77. if (di.has_error()) {
  78. outln("DirIterator: {}", di.error());
  79. return 1;
  80. }
  81. bool success = false;
  82. while (di.has_next()) {
  83. auto name = di.next_path();
  84. success = read_variable(name);
  85. }
  86. return success ? 0 : 1;
  87. }
  88. ErrorOr<int> serenity_main(Main::Arguments arguments)
  89. {
  90. bool show_all = false;
  91. Vector<StringView> variables;
  92. Core::ArgsParser args_parser;
  93. args_parser.set_general_help("Show or modify system-internal values. This requires root, and can crash your system.");
  94. args_parser.add_option(show_all, "Show all variables", "all", 'a');
  95. args_parser.add_option(s_set_variable, "Set variables", "write", 'w');
  96. args_parser.add_positional_argument(variables, "variable[=value]", "variables", Core::ArgsParser::Required::No);
  97. args_parser.parse(arguments);
  98. if (!show_all && variables.is_empty()) {
  99. args_parser.print_usage(stdout, arguments.strings[0]);
  100. return 1;
  101. }
  102. if (show_all) {
  103. // Ignore `variables`, even if they are supplied. Just like the real procps does.
  104. return handle_show_all();
  105. }
  106. return handle_variables(variables);
  107. }