Build device structure in TDE hardware library

Repair potential segfault in same due to ptrlist copying
pull/16/head
Timothy Pearson 13 years ago
parent a713cc823c
commit 8fb2978ca0

@ -44,6 +44,7 @@ TDEGenericDevice::TDEGenericDevice(TDEGenericDeviceType::TDEGenericDeviceType dt
m_deviceType = dt; m_deviceType = dt;
m_deviceName = dn; m_deviceName = dn;
m_parentDevice = 0;
m_blacklistedForUpdate = false; m_blacklistedForUpdate = false;
} }
@ -123,6 +124,14 @@ void TDEGenericDevice::setModelID(TQString id) {
m_modelID = id; m_modelID = id;
} }
void TDEGenericDevice::setParentDevice(TDEGenericDevice* pd) {
m_parentDevice = pd;
}
TDEGenericDevice* TDEGenericDevice::parentDevice() {
return m_parentDevice;
}
bool TDEGenericDevice::blacklistedForUpdate() { bool TDEGenericDevice::blacklistedForUpdate() {
return m_blacklistedForUpdate; return m_blacklistedForUpdate;
} }
@ -514,6 +523,7 @@ void TDEHardwareDevices::rescanDeviceInformation(TDEGenericDevice* hwdevice) {
struct udev_device *dev; struct udev_device *dev;
dev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii()); dev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
classifyUnknownDevice(dev, hwdevice, false); classifyUnknownDevice(dev, hwdevice, false);
updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
udev_device_unref(dev); udev_device_unref(dev);
} }
@ -572,6 +582,7 @@ void TDEHardwareDevices::processHotPluggedHardware() {
if (device) { if (device) {
m_deviceList.append(device); m_deviceList.append(device);
updateParentDeviceInformation(device); // Update parent/child tables for this device
emit hardwareAdded(device); emit hardwareAdded(device);
} }
} }
@ -612,6 +623,7 @@ void TDEHardwareDevices::processHotPluggedHardware() {
if (hwdevice->systemPath() == systempath) { if (hwdevice->systemPath() == systempath) {
if (!hwdevice->blacklistedForUpdate()) { if (!hwdevice->blacklistedForUpdate()) {
classifyUnknownDevice(dev, hwdevice, false); classifyUnknownDevice(dev, hwdevice, false);
updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
emit hardwareUpdated(hwdevice); emit hardwareUpdated(hwdevice);
} }
break; break;
@ -813,7 +825,6 @@ TDEDiskDeviceType::TDEDiskDeviceType classifyDiskType(udev_device* dev, const TQ
if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_VCD")) == "1") || (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_SDVD")) == "1")) { if ((TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_VCD")) == "1") || (TQString(udev_device_get_property_value(dev, "ID_CDROM_MEDIA_SDVD")) == "1")) {
disktype = disktype | TDEDiskDeviceType::CDVideo; disktype = disktype | TDEDiskDeviceType::CDVideo;
} }
disktype = disktype | TDEDiskDeviceType::Optical;
} }
// Detect RAM and Loop devices, since udev can't seem to... // Detect RAM and Loop devices, since udev can't seem to...
@ -846,7 +857,10 @@ TDEGenericDeviceType::TDEGenericDeviceType readGenericDeviceTypeFromString(TQStr
TDEGenericDeviceType::TDEGenericDeviceType ret = TDEGenericDeviceType::Other; TDEGenericDeviceType::TDEGenericDeviceType ret = TDEGenericDeviceType::Other;
// Keep this in sync with the TDEGenericDeviceType definition in the header // Keep this in sync with the TDEGenericDeviceType definition in the header
if (query == "CPU") { if (query == "Root") {
ret = TDEGenericDeviceType::Root;
}
else if (query == "CPU") {
ret = TDEGenericDeviceType::CPU; ret = TDEGenericDeviceType::CPU;
} }
else if (query == "GPU") { else if (query == "GPU") {
@ -1182,7 +1196,7 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
if (devicevendorid.isNull() || devicemodelid.isNull()) { if (devicevendorid.isNull() || devicemodelid.isNull()) {
bool done = false; bool done = false;
TQString current_path = systempath; TQString current_path = systempath;
TQString modalias_string = TQString::null;; TQString modalias_string = TQString::null;
while (done == false) { while (done == false) {
TQString malnodename = current_path; TQString malnodename = current_path;
@ -1374,6 +1388,22 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
disktype = sdevice->diskType(); // The type can be overridden by an external rule disktype = sdevice->diskType(); // The type can be overridden by an external rule
} }
if ((disktype & TDEDiskDeviceType::CDROM)
|| (disktype & TDEDiskDeviceType::CDRW)
|| (disktype & TDEDiskDeviceType::DVDROM)
|| (disktype & TDEDiskDeviceType::DVDRAM)
|| (disktype & TDEDiskDeviceType::DVDRW)
|| (disktype & TDEDiskDeviceType::BDROM)
|| (disktype & TDEDiskDeviceType::BDRW)
|| (disktype & TDEDiskDeviceType::CDAudio)
|| (disktype & TDEDiskDeviceType::CDVideo)
|| (disktype & TDEDiskDeviceType::DVDVideo)
|| (disktype & TDEDiskDeviceType::BDVideo)
) {
// These drives are guaranteed to be optical
disktype = disktype | TDEDiskDeviceType::Optical;
}
if (disktype & TDEDiskDeviceType::Floppy) { if (disktype & TDEDiskDeviceType::Floppy) {
// Floppy drives don't work well under udev // Floppy drives don't work well under udev
// I have to look for the block device name manually // I have to look for the block device name manually
@ -1549,6 +1579,7 @@ bool TDEHardwareDevices::queryHardwareInformation() {
// Prepare the device list for repopulation // Prepare the device list for repopulation
m_deviceList.clear(); m_deviceList.clear();
addCoreSystemDevices();
struct udev_enumerate *enumerate; struct udev_enumerate *enumerate;
struct udev_list_entry *devices, *dev_list_entry; struct udev_list_entry *devices, *dev_list_entry;
@ -1589,11 +1620,95 @@ bool TDEHardwareDevices::queryHardwareInformation() {
// Free the enumerator object // Free the enumerator object
udev_enumerate_unref(enumerate); udev_enumerate_unref(enumerate);
// Update parent/child tables for all devices
updateParentDeviceInformation();
return true; return true;
} }
TDEGenericHardwareList &TDEHardwareDevices::listAllPhysicalDevices() { void TDEHardwareDevices::updateParentDeviceInformation(TDEGenericDevice* hwdevice) {
return m_deviceList; // Scan for the first path up the sysfs tree that is available in the main hardware table
bool done = false;
TQString current_path = hwdevice->systemPath();
TDEGenericDevice* parentdevice = 0;
if (current_path.endsWith("/")) {
current_path.truncate(current_path.findRev("/"));
}
while (done == false) {
current_path.truncate(current_path.findRev("/"));
if (current_path.startsWith("/sys/devices")) {
if (current_path.endsWith("/")) {
current_path.truncate(current_path.findRev("/"));
}
parentdevice = findBySystemPath(current_path);
if (parentdevice) {
done = true;
}
}
else {
// Abort!
done = true;
}
}
hwdevice->setParentDevice(parentdevice);
}
void TDEHardwareDevices::updateParentDeviceInformation() {
TDEGenericDevice *hwdevice;
// We can't use m_deviceList directly as m_deviceList can only have one iterator active against it at any given time
TDEGenericHardwareList devList = listAllPhysicalDevices();
for ( hwdevice = devList.first(); hwdevice; hwdevice = devList.next() ) {
updateParentDeviceInformation(hwdevice);
}
}
void TDEHardwareDevices::addCoreSystemDevices() {
// Add core top-level devices in /sys/devices to the hardware listing
TQStringList holdingDeviceNodes;
TQString devicesnodename = "/sys/devices";
TQDir devicesdir(devicesnodename);
devicesdir.setFilter(TQDir::All);
TQString nodename;
TDEGenericDevice *hwdevice;
const TQFileInfoList *dirlist = devicesdir.entryInfoList();
if (dirlist) {
TQFileInfoListIterator devicesdirit(*dirlist);
TQFileInfo *dirfi;
while ( (dirfi = devicesdirit.current()) != 0 ) {
nodename = dirfi->fileName();
if (nodename != "." && nodename != "..") {
hwdevice = new TDEGenericDevice(TDEGenericDeviceType::Root);
hwdevice->setSystemPath(dirfi->absFilePath());
m_deviceList.append(hwdevice);
}
++devicesdirit;
}
}
}
TQPtrList<TDEGenericDevice> TDEHardwareDevices::listByDeviceClass(TDEGenericDeviceType::TDEGenericDeviceType cl) {
TDEGenericHardwareList ret;
ret.setAutoDelete(false);
TDEGenericDevice *hwdevice;
for ( hwdevice = m_deviceList.first(); hwdevice; hwdevice = m_deviceList.next() ) {
if (hwdevice->type() == cl) {
ret.append(hwdevice);
}
}
return ret;
}
TDEGenericHardwareList TDEHardwareDevices::listAllPhysicalDevices() {
TDEGenericHardwareList ret = m_deviceList;
ret.setAutoDelete(false);
return ret;
} }
#include "tdehardwaredevices.moc" #include "tdehardwaredevices.moc"

@ -41,6 +41,7 @@
// Keep readGenericDeviceTypeFromString() in tdehardwaredevices.cpp in sync with this enum // Keep readGenericDeviceTypeFromString() in tdehardwaredevices.cpp in sync with this enum
namespace TDEGenericDeviceType { namespace TDEGenericDeviceType {
enum TDEGenericDeviceType { enum TDEGenericDeviceType {
Root,
CPU, CPU,
GPU, GPU,
RAM, RAM,
@ -269,6 +270,16 @@ class TDECORE_EXPORT TDEGenericDevice
*/ */
TQString &modelID(); TQString &modelID();
/**
* @param a TDEGenericDevice* with the parent device, if any
*/
void setParentDevice(TDEGenericDevice* pd);
/**
* @return a TDEGenericDevice* with the parent device, if any
*/
TDEGenericDevice* parentDevice();
/** /**
* @param a TQString with the model ID, if any * @param a TQString with the model ID, if any
*/ */
@ -286,6 +297,7 @@ class TDECORE_EXPORT TDEGenericDevice
TQString m_vendorID; TQString m_vendorID;
TQString m_modelID; TQString m_modelID;
bool m_blacklistedForUpdate; bool m_blacklistedForUpdate;
TDEGenericDevice* m_parentDevice;
// Internal use only! // Internal use only!
TQStringList m_externalSubtype; TQStringList m_externalSubtype;
@ -506,7 +518,14 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
* List all hardware capabilities on all devices * List all hardware capabilities on all devices
* @return TQPtrList<TDEGenericDevice> containing all known hardware devices * @return TQPtrList<TDEGenericDevice> containing all known hardware devices
*/ */
TQPtrList<TDEGenericDevice> &listAllPhysicalDevices(); TQPtrList<TDEGenericDevice> listAllPhysicalDevices();
/**
* List all hardware capabilities on all devices
* @param a TDEGenericDeviceType::TDEGenericDeviceType specifying the device class
* @return TQPtrList<TDEGenericDevice> containing all known hardware devices
*/
TQPtrList<TDEGenericDevice> listByDeviceClass(TDEGenericDeviceType::TDEGenericDeviceType cl);
/** /**
* Return the device with system path @arg syspath, or 0 if no device exists for that path * Return the device with system path @arg syspath, or 0 if no device exists for that path
@ -544,6 +563,11 @@ class TDECORE_EXPORT TDEHardwareDevices : public TQObject
TDEGenericDevice *classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice=0, bool force_full_classification=true); TDEGenericDevice *classifyUnknownDevice(udev_device* dev, TDEGenericDevice* existingdevice=0, bool force_full_classification=true);
TDEGenericDevice *classifyUnknownDeviceByExternalRules(udev_device* dev, TDEGenericDevice* existingdevice=0, bool classifySubDevices=false); TDEGenericDevice *classifyUnknownDeviceByExternalRules(udev_device* dev, TDEGenericDevice* existingdevice=0, bool classifySubDevices=false);
void updateParentDeviceInformation();
void updateParentDeviceInformation(TDEGenericDevice* hwdevice);
void addCoreSystemDevices();
struct udev *m_udevStruct; struct udev *m_udevStruct;
struct udev_monitor *m_udevMonitorStruct; struct udev_monitor *m_udevMonitorStruct;
TDEGenericHardwareList m_deviceList; TDEGenericHardwareList m_deviceList;

Loading…
Cancel
Save