LINUX.ORG.RU

Почему ifstream не читает нормальные значения из sysfs?

 


0

1
#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
#include <unordered_map>
#include "log_entry.h"

const auto delta = std::chrono::seconds(5);

std::filesystem::path FindHwmonByName(const std::string& mon_name) {
  std::optional<std::filesystem::path> mon_path;
  for (auto& p : std::filesystem::directory_iterator("/sys/class/hwmon")) {
    std::string path = p.path() / "name";
    std::ifstream ifs(path);
    if (!ifs.is_open()) {
      std::ostringstream ss;
      ss << "Failed to open " << path << " for read";
      throw std::runtime_error(ss.str());
    }
    std::string name;
    ifs >> name;
    if (name == mon_name) {
      mon_path = p.path();
      break;
    }
  }
  if (!mon_path) {
    std::ostringstream ss;
    ss << "No hwmon with name " << mon_name;
    throw std::runtime_error(ss.str());
  }
  return mon_path.value();
}

int main(int argc, char** argv) {
  try {
    if (argc != 4) {
      std::ostringstream ss;
      ss << "Usage: " << argv[0] << " [OUTPUT FILE] [HWMON NAME] [INPUT NAME]";
      throw std::runtime_error(ss.str());
    }
    auto mon_path = FindHwmonByName(argv[2]);
    std::string input_path = mon_path / argv[3];
    std::cerr << input_path << std::endl;
    while (true) {
      std::ifstream ifs(input_path);
      if (!ifs.is_open()) {
        std::ostringstream ss;
        ss << "Failed to open " << input_path;
        throw std::runtime_error(ss.str());
      }
      int input_value;
      if (!ifs >> input_value) {
        std::ostringstream ss;
        ss << "Failed to read value from " << input_path;
        throw std::runtime_error(ss.str());
      }
      std::cout << input_value << std::endl; // !!!!!!!!!!!!
    }
  } catch (const std::exception& e) {
    std::cerr << e.what() << std::endl;
    return 1;
  }
  return 0;
}
$ ./hwmon_logger /dev/stdout amdgpu temp1_input | head -10
/sys/class/hwmon/hwmon1/temp1_input
0
0
0
0
0
0
0
0
0
0
$ cat /sys/class/hwmon/hwmon1/temp1_input
44000

Иногда просто какой-то мусор выводит, типа 32766.

Что такого делает cat, чего не умеет ifstream?


Ответ на: комментарий от DELIRIUM
execve("./hwmon_logger", ["./hwmon_logger", "/dev/stdout", "amdgpu", "temp1_input"], 0x7fffecd2c4f8 /* 34 vars */) = 0
brk(NULL)                               = 0x556922eb5000

[ обрезано ]

openat(AT_FDCWD, "/sys/class/hwmon", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 3
fstat(3, {st_mode=S_IFDIR|0755, st_size=0, ...}) = 0
getdents64(3, /* 9 entries */, 32768)   = 272
openat(AT_FDCWD, "/sys/class/hwmon/hwmon6/name", O_RDONLY) = 4
read(4, "iwlwifi_1\n", 8191)            = 10
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon4/name", O_RDONLY) = 4
read(4, "k10temp\n", 8191)              = 8
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon2/name", O_RDONLY) = 4
read(4, "AC\n", 8191)                   = 3
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon0/name", O_RDONLY) = 4
read(4, "nvme\n", 8191)                 = 5
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon5/name", O_RDONLY) = 4
read(4, "BAT0\n", 8191)                 = 5
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon3/name", O_RDONLY) = 4
read(4, "thinkpad\n", 8191)             = 9
close(4)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/name", O_RDONLY) = 4
read(4, "amdgpu\n", 8191)               = 7
close(4)                                = 0
close(3)                                = 0
write(2, "/sys/class/hwmon/hwmon1/temp1_in"..., 35) = 35
write(2, "\n", 1)                       = 1
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
fstat(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = 2
close(3)                                = 0
openat(AT_FDCWD, "/sys/class/hwmon/hwmon1/temp1_input", O_RDONLY) = 3
write(1, "0\n", 2)                      = -1 EPIPE (Broken pipe)
--- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=44980, si_uid=1000} ---
+++ killed by SIGPIPE +++

Вот это прикол. А где вообще read?

tsmx
() автор топика
Последнее исправление: tsmx (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.