Home » Developing U++ » UppHub » [SysInfo - Improvement - Koldo] Better way to find distribution version & more
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #40954 is a reply to message #40953] |
Sun, 13 October 2013 01:22   |
 |
Klugier
Messages: 1117 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Hello Koldo,
Following two lines of code are tricky:
for (FindFile ff(AppendFileName("/etc/", "*-release")); ff; ff.Next())
release += LoadFile_Safe(ff.GetPath());
This means, that find all files, that have "release" chain in their names. File "lsb-release" dosen't contain full version information, so we need to scan other files with "release" in their names.
************************************************************ ************************************************************ **
Here is the output (Ubuntu 13.04):
DISTRIB_VERSION=13.04
VERSION=13.04, Raring Ringtail
VERSION can be replaced with VERSION_ID (And even DISTRIB_VERSION to ID):
VERSION_ID=13.04
ID=ubuntu
************************************************************ ************************************************************ **
You can type following command in your terminal: "cat /etc/*-release":
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=13.04
DISTRIB_CODENAME=raring
DISTRIB_DESCRIPTION="Ubuntu 13.04"
NAME="Ubuntu"
VERSION="13.04, Raring Ringtail"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 13.04"
VERSION_ID="13.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
Personally, I think we can add more information about distribution to SysInfo.
************************************************************ ************************************************************ **
P.S.
I uploaded old file (It doesn't compile!!!).
*I enclose newer version with lowercase fix.
Sincerely,
Klugier
-
Attachment: os.cpp
(Size: 14.31KB, Downloaded 712 times)
U++ - one framework to rule them all.
[Updated on: Sun, 13 October 2013 13:06] Report message to a moderator
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #40955 is a reply to message #40954] |
Sun, 13 October 2013 01:58   |
 |
Klugier
Messages: 1117 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Here is the final version of the function:
static bool GetOsInfoCheckRelease(String &distro, String &distVersion)
{
StringParse release;
for (FindFile ff(AppendFileName("/etc/", "*-release")); ff; ff.Next())
release += LoadFile_Safe(ff.GetPath());
if (release.IsEmpty())
return false;
if (!release.GoAfter("DISTRIB_ID="))
return false;
distro = ToLower(release.GetText());
if (distro.IsEmpty())
return false;
release.GoAfter_Init("DISTRIB_RELEASE=");
distVersion = release.GetText();
return true;
}
I don't want to change current functionality, so i decided to stay with old qualifiers. In the future we can get more informations about distribution (with my extension). It is up to you.
P.S.
Moreover, you can change LoadFile_Safe function (Functions4U) to:
String LoadFile_Safe(const String& fileName);
insted of:
String LoadFile_Safe(String fileName);
U++ - one framework to rule them all.
[Updated on: Sun, 13 October 2013 13:06] Report message to a moderator
|
|
|
|
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41002 is a reply to message #41001] |
Sat, 19 October 2013 00:37   |
 |
Klugier
Messages: 1117 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Hello Koldo,
Moreover, I wrote better handling for measuring cpu temperature on GNU/Linux (POSIX?). Now, SysInfo should use "hwmon" when "acpi" fails. Let's look at code:
static double GetCpuTemperatureViaAcpi()
{
FindFile ff;
if(ff.Search("/proc/acpi/thermal_zone/*")) {
do {
if (ff.IsDirectory()) {
String name = ff.GetName();
if (name != "." && name != "..") {
StringParse str = LoadFile_Safe(AppendFileName(AppendFileName("/proc/acpi/thermal_zone", name), "temperature"));
str.GoAfter("temperature:");
return str.GetDouble();
}
}
} while(ff.Next());
}
return Null;
}
static double GetCpuTemperatureViaHwmon()
{
Vector <double> temps;
for (FindFile ff(AppendFileName("/sys/class/hwmon/hwmon0/device", "*input")); ff; ff.Next()) {
if (!ff.IsHidden()) {
String temp = LoadFile_Safe(ff.GetPath());
if (!temp.IsEmpty())
temps.Add((double)StrInt(temp) / 1000.0);
}
}
double sumTemps = 0.0;
for (int i = 0; i < temps.GetCount(); i++)
sumTemps += temps[i];
if (!temps.IsEmpty())
return sumTemps / (double)temps.GetCount();
else
return Null;
}
double GetCpuTemperature()
{
double temp = Null;
if (temp == (double)Null) temp = GetCpuTemperatureViaAcpi();
if (temp == (double)Null) temp = GetCpuTemperatureViaHwmon();
return temp;
}
* in this case "static" means that function should be use only in file where it was declared.
P.S.
Toomorow, I will enclose source file with above improvement.
Sincerely,
Klugier
U++ - one framework to rule them all.
[Updated on: Sat, 19 October 2013 00:50] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41014 is a reply to message #41002] |
Sun, 20 October 2013 12:36   |
Zbych
Messages: 332 Registered: July 2009
|
Senior Member |
|
|
| klugier wrote on Sat, 19 October 2013 00:37 |
static double GetCpuTemperatureViaHwmon()
{
Vector <double> temps;
for (FindFile ff(AppendFileName("/sys/class/hwmon/hwmon0/device", "*input")); ff; ff.Next()) {
|
Unfortunately it will not work on all systems. I checked some computers in my office:
1. intel, ubuntu 12.04, kernel 3.2, temperature location: /sys/class/hwmon/hwmon0/temp1_input (no device sub-dir)
2. intel, ubuntu 12.04, kernel 3.8, temperature location: /sys/devices/platform/coretemp.0/temp*_input
3. AMD, ubuntu 12.04, kernel 3.2, temperature location: /sys/class/hwmon/hwmon0/device/temp1_input
Maybe we should check libsensors to find out how it locates cpu temperature files.
|
|
|
|
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41045 is a reply to message #41030] |
Wed, 23 October 2013 22:46   |
 |
Klugier
Messages: 1117 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Hello Koldo,
Koldo, please noticed that libsensor is GPL library. It means that all applications which are linking to SysInfo should also use GPL license. Only the latest version of libsensors use LGPL license. I do not think that people linking their programs with libsensors want to risk so much.
To use my trick with temperature you don't need to link with libsensors, beacuse I read only system file. In this way, you can also get more information about the computer sensors state. The main problem of this solution is how to find appropriate path on certain linux version.
More information about libsensors licence you can find on official site.
Sincerely,
Klugier
U++ - one framework to rule them all.
[Updated on: Thu, 24 October 2013 01:55] Report message to a moderator
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41109 is a reply to message #41093] |
Thu, 31 October 2013 17:01   |
 |
Klugier
Messages: 1117 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Hello Koldo,
Alternative paths, can be done in this way:
static double GetCpuTemperatureHWMON()
{
FindFile ff;
double sumTemps = 0.0;
int count = 0;
String path = "/sys/class/hwmon/";
if (ff.Search(AppendFileName(path, "device"))) {
path += ff.GetName() + "/";
}
else {
String tempPath;
for (ff.Search(AppendFileName(path, "hwmon*")); ff; ff.Next()) {
FindFile hwmonFF;
tempPath = path;
tempPath += ff.GetName() + "/";
if (hwmonFF.Search(AppendFileName(tempPath, "device"))) {
tempPath += hwmonFF.GetName() + "/";
}
if (hwmonFF.Search(AppendFileName(tempPath, "*input"))) {
if (!hwmonFF.IsDirectory()) {
path = tempPath;
break;
}
}
}
if (!tempPath.IsEmpty() && tempPath != path)
path = tempPath;
}
for (ff.Search(AppendFileName(path, "*input")); ff; ff.Next()) {
if (!ff.IsHidden()) {
String temp = LoadFile_Safe(ff.GetPath());
if (!temp.IsEmpty()) {
sumTemps += static_cast <double> ((StrInt(temp))) / 1000.0;
count++;
}
}
}
if (count == 0)
return Null;
return sumTemps / count;
}
* Additional changes:
- change casting method to more safer.
- changed "0." to "0.0" (Are you sure that 0. is more readable than 0.0???)
* TODO:
- create function static String "findHWMONInputFilesPath()" - ALTERNATIVE METHOD
Sincerely,
Klugier
U++ - one framework to rule them all.
[Updated on: Thu, 31 October 2013 19:01] Report message to a moderator
|
|
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #41122 is a reply to message #41121] |
Fri, 01 November 2013 23:37   |
 |
Klugier
Messages: 1117 Registered: September 2012 Location: Poland, Kraków
|
Senior Contributor |
|
|
Hello Koldo,
Using sensors command is the easiest solution and safe solution, but not efficient one. Calling external program always associated with the overhead time. In addition we can check where are input files only once per program to optimize the algorithm.
| Quote: |
To get CPU temperature is more complicated than expected, and more difficult than checking folders.
|
I am almost sure that we can do this in above way (Open sources projects like "Conky" do this in simillar way).
Sincerely,
Klugier
U++ - one framework to rule them all.
[Updated on: Fri, 01 November 2013 23:45] Report message to a moderator
|
|
|
|
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43154 is a reply to message #41091] |
Tue, 20 May 2014 12:59   |
kasome
Messages: 78 Registered: July 2008 Location: Taiwan
|
Member |
|
|
Hello Koldo,
There is a bug in upp\bazaar\SysInfo\SysInfo.cpp
Here is the original code
Array<NetAdapter> GetAdapterInfo()
{
Array<NetAdapter> res;
Index<String> macs;
int sck = socket(PF_INET, SOCK_DGRAM, 0);
if(sck < 0)
return res;
int bufSize = 4096;
struct ifconf ifc = { 0 };
byte buf[bufSize];
for(int iTry = 0; iTry < 4; iTry++) {
ifc.ifc_len = bufSize;
ifc.ifc_buf = (__caddr_t)buf;
if (ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
close(sck);
return res;
}
if(ifc.ifc_len != bufSize)
break;
bufSize *= 2;
if(iTry >= 3) {
close(sck);
return res;
}
}
int nIfaces = ifc.ifc_len / sizeof(struct ifreq);
struct ifreq *iface = ifc.ifc_req;
for(int iIface = 0; iIface < nIfaces; iIface++) {
String MAC;
#ifdef SIOCGIFHWADDR
if(ioctl(sck, SIOCGIFHWADDR, iface) < 0)
continue;
MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
(byte)iface->ifr_hwaddr.sa_data[0],
(byte)iface->ifr_hwaddr.sa_data[1],
(byte)iface->ifr_hwaddr.sa_data[2],
(byte)iface->ifr_hwaddr.sa_data[3],
(byte)iface->ifr_hwaddr.sa_data[4],
(byte)iface->ifr_hwaddr.sa_data[5]
);
#elif SIOCGENADDR
if (ioctl(sck, SIOCGENADDR, iface) < 0)
continue;
MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
(byte)iface->ifr_enaddr[0],
(byte)iface->ifr_enaddr[1],
(byte)iface->ifr_enaddr[2],
(byte)iface->ifr_enaddr[3],
(byte)iface->ifr_enaddr[4],
(byte)iface->ifr_enaddr[5]
);
#elif __MACH__ || __NetBSD__ || __OpenBSD__ || __FreeBSD__
int mib[6];
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
mib[5] = if_nametoindex(iface->ifr_name);
if (mib[5] == 0) // nameless interface ? skip
continue;
int len = 0;
if (sysctl(mib, 6, NULL, (size_t*)&len, NULL, 0) != 0)
continue; // sysctl error, just leave MAC empty
char macbuf[len];
if (!macbuf) // can't allocat buffer, skip this MAC
continue;
if (sysctl(mib, 6, macbuf, (size_t*)&len, NULL, 0) != 0)
continue;
struct if_msghdr *ifm = (struct if_msghdr *)macbuf;
struct sockaddr_dl *sdl = (struct sockaddr_dl *)(ifm + 1);
byte ptr[] = (byte **)LLADDR(sdl);
MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
#else
#error OS Distribution Not Recognized
#endif
if(MAC == "00:00:00:00:00:00")
MAC.Clear();
if(!MAC.IsEmpty() && macs.Find(MAC) >= 0)
continue;
macs.Add(MAC);
NetAdapter &adapter = res.Add();
adapter.mac = MAC;
adapter.fullname = iface->ifr_name;
// set interface type from name
if(adapter.fullname.StartsWith("eth"))
adapter.type = "ETHERNET";
else if(adapter.fullname.StartsWith("lo"))
adapter.type = "SOFTWARE_LOOPBACK";
else if(adapter.fullname.StartsWith("ppp"))
adapter.type = "MODEM";
else if(adapter.fullname.StartsWith("hci"))
adapter.type = "BLUETOOTH";
else if(adapter.fullname.StartsWith("tr"))
adapter.type = "TOKENRING";
else if(adapter.fullname.StartsWith("vbox") || adapter.fullname.StartsWith("wifi") ||
adapter.fullname.StartsWith("ath"))
adapter.type = "VIRTUALBOX";
else if(adapter.fullname.StartsWith("wlan"))
adapter.type = "IEEE80211";
else if(adapter.fullname.StartsWith("vmnet"))
adapter.type = "VMWARE";
else
adapter.type = "OTHER";
adapter.description = adapter.fullname;
if (!ioctl(sck, SIOCGIFADDR, iface))
continue;
adapter.ip4 = inet_ntoa(((struct sockaddr_in *)&(iface->ifr_addr))->sin_addr);
iface++;
}
close(sck);
return res;
}
Here is the fixed code
Array<NetAdapter> GetAdapterInfo()
{
Array<NetAdapter> res;
Index<String> macs;
int sck = socket(PF_INET, SOCK_DGRAM, 0);
if(sck < 0)
return res;
int bufSize = 4096;
struct ifconf ifc = { 0 };
byte buf[bufSize];
for(int iTry = 0; iTry < 4; iTry++) {
ifc.ifc_len = bufSize;
ifc.ifc_buf = (__caddr_t)buf;
if (ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
close(sck);
return res;
}
if(ifc.ifc_len != bufSize)
break;
bufSize *= 2;
if(iTry >= 3) {
close(sck);
return res;
}
}
int nIfaces = ifc.ifc_len / sizeof(struct ifreq);
struct ifreq *iface = ifc.ifc_req;
for(int iIface = 0; iIface < nIfaces; iIface++) {
String MAC;
#ifdef SIOCGIFHWADDR
if(ioctl(sck, SIOCGIFHWADDR, iface) < 0)
continue;
MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
(byte)iface->ifr_hwaddr.sa_data[0],
(byte)iface->ifr_hwaddr.sa_data[1],
(byte)iface->ifr_hwaddr.sa_data[2],
(byte)iface->ifr_hwaddr.sa_data[3],
(byte)iface->ifr_hwaddr.sa_data[4],
(byte)iface->ifr_hwaddr.sa_data[5]
);
#elif SIOCGENADDR
if (ioctl(sck, SIOCGENADDR, iface) < 0)
continue;
MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
(byte)iface->ifr_enaddr[0],
(byte)iface->ifr_enaddr[1],
(byte)iface->ifr_enaddr[2],
(byte)iface->ifr_enaddr[3],
(byte)iface->ifr_enaddr[4],
(byte)iface->ifr_enaddr[5]
);
#elif __MACH__ || __NetBSD__ || __OpenBSD__ || __FreeBSD__
int mib[6];
mib[0] = CTL_NET;
mib[1] = AF_ROUTE;
mib[2] = 0;
mib[3] = AF_LINK;
mib[4] = NET_RT_IFLIST;
mib[5] = if_nametoindex(iface->ifr_name);
if (mib[5] == 0) // nameless interface ? skip
continue;
int len = 0;
if (sysctl(mib, 6, NULL, (size_t*)&len, NULL, 0) != 0)
continue; // sysctl error, just leave MAC empty
char macbuf[len];
if (!macbuf) // can't allocat buffer, skip this MAC
continue;
if (sysctl(mib, 6, macbuf, (size_t*)&len, NULL, 0) != 0)
continue;
struct if_msghdr *ifm = (struct if_msghdr *)macbuf;
struct sockaddr_dl *sdl = (struct sockaddr_dl *)(ifm + 1);
byte ptr[] = (byte **)LLADDR(sdl);
MAC = Format("%02x:%02x:%02x:%02x:%02x:%02x",
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]);
#else
#error OS Distribution Not Recognized
#endif
if(MAC == "00:00:00:00:00:00")
MAC.Clear();
if(!MAC.IsEmpty() && macs.Find(MAC) >= 0)
continue;
macs.Add(MAC);
NetAdapter &adapter = res.Add();
adapter.mac = MAC;
adapter.fullname = iface->ifr_name;
// set interface type from name
if(adapter.fullname.StartsWith("eth"))
adapter.type = "ETHERNET";
else if(adapter.fullname.StartsWith("lo"))
adapter.type = "SOFTWARE_LOOPBACK";
else if(adapter.fullname.StartsWith("ppp"))
adapter.type = "MODEM";
else if(adapter.fullname.StartsWith("hci"))
adapter.type = "BLUETOOTH";
else if(adapter.fullname.StartsWith("tr"))
adapter.type = "TOKENRING";
else if(adapter.fullname.StartsWith("vbox") || adapter.fullname.StartsWith("wifi") ||
adapter.fullname.StartsWith("ath"))
adapter.type = "VIRTUALBOX";
else if(adapter.fullname.StartsWith("wlan"))
adapter.type = "IEEE80211";
else if(adapter.fullname.StartsWith("vmnet"))
adapter.type = "VMWARE";
else
adapter.type = "OTHER";
adapter.description = adapter.fullname;
if (ioctl(sck, SIOCGIFADDR, iface) < 0) {
iface++;
continue;
}
adapter.ip4 = inet_ntoa(((struct sockaddr_in *)&(iface->ifr_addr))->sin_addr);
iface++;
}
close(sck);
return res;
}
Hope that helps.
|
|
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43374 is a reply to message #43155] |
Mon, 14 July 2014 10:26   |
kasome
Messages: 78 Registered: July 2008 Location: Taiwan
|
Member |
|
|
Hello Koldo,
There is a few memory leak in function GetWMIInfo of upp\bazaar\SysInfo\SysInfo.cpp
find
bool GetWMIInfo(String system, Array <String> &data, Array <Value> *ret[], String nameSpace = "root\\cimv2")
and modify
for (int col = 0; col < data.GetCount(); ++col) {
VARIANT vProp;
BSTR strClassProp = SysAllocString(data[col].ToWString());
hRes = pClassObject->Get(strClassProp, 0, &vProp, 0, 0);
if(hRes != S_OK){
pWbemServices->Release();
pIWbemLocator->Release();
pEnumerator->Release();
pClassObject->Release();
CoUninitialize();
return false;
}
SysFreeString(strClassProp);
ret[col]->Add(GetVARIANT(vProp));
rt = true;
}
to
for (int col = 0; col < data.GetCount(); ++col) {
VARIANT vProp;
VariantInit( &vProp );
BSTR strClassProp = SysAllocString(data[col].ToWString());
hRes = pClassObject->Get(strClassProp, 0, &vProp, 0, 0);
if(hRes != S_OK){
pWbemServices->Release();
pIWbemLocator->Release();
pEnumerator->Release();
pClassObject->Release();
CoUninitialize();
return false;
}
SysFreeString(strClassProp);
ret[col]->Add(GetVARIANT(vProp));
VariantClear( &vProp );
|
|
|
|
| Re: [SysInfo - Improvement - Koldo] Better way to find distribution version & more [message #43375 is a reply to message #43374] |
Mon, 14 July 2014 10:33   |
kasome
Messages: 78 Registered: July 2008 Location: Taiwan
|
Member |
|
|
About the functiion Shutdown in linux platform,
is there missing sync() function call when action == "shutdown" or action == "reboot" >
#ifdef PLATFORM_POSIX
bool Shutdown(String action)
{
if (action == "logoff") {
kill(1, SIGTSTP);
sync();
signal(SIGTERM, SIG_IGN);
setpgrp();
kill(-1, SIGTERM);
sleep(1);
kill(-1, SIGHUP); //* Force PPPD's down, too *
sleep(1);
kill(-1, SIGKILL);
sync();
sleep(1);
} else if (action == "shutdown") {
sync();
sleep(1);
#if __GNU_LIBRARY__ > 5
reboot(0xCDEF0123);
#else
reboot(0xfee1dead, 672274793, 0xCDEF0123);
#endif
} else if (action == "reboot") { // LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2
sync();
sleep(1);
#if __GNU_LIBRARY__ > 5
reboot(0x01234567);
#else
reboot(0xfee1dead, 672274793, 0x01234567);
#endif
}
exit(0);
return true;
}
#endif
|
|
|
|
|
|
|
|
|
|
Goto Forum:
Current Time: Sun Apr 26 01:52:51 GMT+2 2026
Total time taken to generate the page: 0.00862 seconds
|