Как получить информацию об оборудовании в Linux с использованием C++
мне нужно получить спецификации жесткого диска на обеих машинах Win и *nix. Я использовал <hdreg.h>
в Linux так:
static struct hd_driveid hd;
int device;
if ((device = open("/dev/sda", O_RDONLY | O_NONBLOCK)) < 0)
{
cerr << "ERROR: Cannot open device /dev/sda n";
exit(1);
}
if (!ioctl(device, HDIO_GET_IDENTITY, &hd))
{
cout << hd.model << endl;
cout << hd.serial_no << endl;
cout << hd.heads << endl;
}
мне нужно hd_driveid
рассказать мне больше информации о диске. Я хочу знать:
- номер секции
- спецификации каждого раздела (формат, ярлык, флаги, размер, начальная точка, количество следов etc.)
- количество дорожек на цилиндр
- общее количество треков
- максимум размер блока
- минимальный размер блока
- размер блока по умолчанию
- общий размер устройства
мои вопросы:
- есть ли общий (независимый от платформы) способ подключить оборудование? Я хотел бы использовать тот же код для win и *nix. (хотя другого выхода не было. встраивание кода сборки в cpp)
- если нет, как я могу получить вышеуказанную информацию в *nix?
5 ответов
почти все в вашем списке не имеет ничего общего с "спецификации жесткого диска":
- количество разделов зависит от чтения таблицы разделов, и если у вас есть какие-либо расширенные разделы, таблицы разделов этих разделов. ОС обычно делает этот бит для вас, когда загружается драйвер устройства.
- информация о разделе (а именно метка тома) обычно недоступна в таблице разделов. Вам нужно угадать тип файловой системы и проанализируйте заголовок файловой системы. Единственное, что в таблице разделов-это байт "тип", который не говорит вам так много, и начало/размер.
- жесткие диски не дадут вам "реальную" информацию CHS. Кроме того, информация CHS, которую предоставляет диск, является "неправильной" с точки зрения BIOS (BIOS делает свою собственную выдумку).
- жесткие диски имеют фиксированный размер сектора, который вы можете получить с
hd_driveid.sector_bytes
(обычно 512, но некоторые современные диски используют 4096). Я не знаю максимум "размер блока", который является свойством системы. Я также не уверен, почему это полезно. -
общий размер в секторах, в
hd_driveid.lba_capacity_2
. Кроме того, размер в байтах, вероятно, может быть получен с чем-то вроде#define _FILE_OFFSET_BITS 64 #include <sys/types.h> #include <unistd.h> ... off_t size_in_bytes = lseek(device, 0, SEEK_END); if (size_in_bytes == (off_t)-1) { ... error, error code in ERRNO ... }
обратите внимание, что в обоих случаях это, вероятно, будет на несколько мегабайт больше, чем размеры, рассчитанные C×H×S.
Это может помочь, если вы расскажете, почему вы хотели эту информацию...
нет, нет независимого от платформы способа. Нет даже никакого способа. Есть только способ Linux.
в Linux вся соответствующая информация доступна в различных файлах в /proc
файловой системы. The /proc/devices
расскажет вам, какие устройства есть (файлы /dev/
может существовать даже тогда, когда устройства недоступны, хотя их открытие в этом случае не удастся),/proc/partitions
расскажет вам, какие разделы доступны на каждом диске и чем вам придется искать в разных подкаталоги для информации. Просто посмотрите вокруг на какой-то системе linux, где это то, что вам нужно.
//-------------------------------------------------
// Without Boost LIB usage
//-------------------------------------------------
#include <sys/statvfs.h>
#include <sys/sysinfo.h>
//-------------------------------------------------
stringstream strStream;
unsigned long hdd_size;
unsigned long hdd_free;
ostringstream strConvert;
//---
struct sysinfo info;
sysinfo( &info );
//---
struct statvfs fsinfo;
statvfs("/", &fsinfo);
//---
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
strStream << cpu_freq.rdbuf();
std::string cpufrequency = strStream.str();
//---
strStream.str("");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
strStream << cpu_temp.rdbuf();
strConvert<< fixed << setprecision(2) << std::stof(strStream.str());
std::string cputemp = strConvert.str();
//---
std::string mem_size = to_string( (size_t)info.totalram * (size_t)info.mem_unit );
//---
hdd_size = fsinfo.f_frsize * fsinfo.f_blocks;
hdd_free = fsinfo.f_bsize * fsinfo.f_bfree;
//---
std::cout << "CPU core number ==" << num_cpu << endl;
std::cout << "CPU core speed ==" << cpufrequency << endl;
std::cout << "CPU temperature (C) ==" << cputemp << endl;
//---
std::cout << "Memory size ==" << mem_size << endl;
//---
std::cout << "Disk, filesystem size ==" << hdd_size << endl;
std::cout << "Disk free space ==" << hdd_free << endl;
//---
//Piece of code working for me with Boost LIB usage
//-----------------------------------------------------
#include <sys/sysinfo.h>
#include <boost/filesystem.hpp>
//---
using namespace boost::filesystem;
//---
struct sysinfo info;
sysinfo( &info );
//---
space_info si = space(".");
//---
unsigned num_cpu = std::thread::hardware_concurrency();
//---
ifstream cpu_freq("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq");
ifstream cpu_temp("/sys/class/thermal/thermal_zone0/temp");
//---
std::string cpunumber = to_string(num_cpu);
std::string cpufrequency = cpu_freq.str();
std::string cputemp = cpu_temp.str();
std::string mem_size = to_string( (size_t)info.totalram * (size_t)info.mem_unit );
std::string disk_available = to_string(si.available);
std::string fslevel = to_string( (si.available/si.capacity)*100 );
//---