7#include "udevqtclient.h"
10#include "devices_debug.h"
12#include <QSocketNotifier>
13#include <qplatformdefs.h>
17ClientPrivate::ClientPrivate(Client *q_)
21 , monitorNotifier(nullptr)
25ClientPrivate::~ClientPrivate()
28 delete monitorNotifier;
31 udev_monitor_unref(monitor);
35void ClientPrivate::init(
const QStringList &subsystemList, ListenToWhat what)
39 if (what != ListenToNone) {
40 setWatchedSubsystems(subsystemList);
44void ClientPrivate::setWatchedSubsystems(
const QStringList &subsystemList)
47 struct udev_monitor *newM = udev_monitor_new_from_netlink(udev,
"udev");
50 qWarning(
"UdevQt: unable to create udev monitor connection");
55 for (
const QString &subsysDevtype : subsystemList) {
56 int ix = subsysDevtype.indexOf(
"/");
61 udev_monitor_filter_add_match_subsystem_devtype(newM, subsystem.
constData(), devType.
constData());
63 udev_monitor_filter_add_match_subsystem_devtype(newM, subsysDevtype.toLatin1().constData(),
nullptr);
68 udev_monitor_enable_receiving(newM);
70 QObject::connect(sn, SIGNAL(activated(
int)), q, SLOT(_uq_monitorReadyRead(
int)));
73 delete monitorNotifier;
75 udev_monitor_unref(monitor);
81 watchedSubsystems = subsystemList;
84void ClientPrivate::_uq_monitorReadyRead(
int fd)
87 monitorNotifier->setEnabled(
false);
88 struct udev_device *dev = udev_monitor_receive_device(monitor);
89 monitorNotifier->setEnabled(
true);
95 Device device(
new DevicePrivate(dev,
false));
97 QByteArray action(udev_device_get_action(dev));
98 if (action ==
"add") {
99 Q_EMIT q->deviceAdded(device);
100 }
else if (action ==
"remove") {
101 Q_EMIT q->deviceRemoved(device);
102 }
else if (action ==
"change") {
103 Q_EMIT q->deviceChanged(device);
104 }
else if (action ==
"online") {
105 Q_EMIT q->deviceOnlined(device);
106 }
else if (action ==
"offline") {
107 Q_EMIT q->deviceOfflined(device);
108 }
else if (action ==
"bind") {
109 Q_EMIT q->deviceBound(device);
110 }
else if (action ==
"unbind") {
111 Q_EMIT q->deviceUnbound(device);
113 qCDebug(Solid::Frontend::DeviceManager::DEVICEMANAGER) <<
"UdevQt: unhandled action:" << action.constData() <<
"for device:" << device.sysfsPath();
117DeviceList ClientPrivate::deviceListFromEnumerate(
struct udev_enumerate *en)
120 struct udev_list_entry *
list;
121 struct udev_list_entry *entry;
123 udev_enumerate_scan_devices(en);
124 list = udev_enumerate_get_list_entry(en);
125 udev_list_entry_foreach(entry, list)
127 struct udev_device *ud = udev_device_new_from_syspath(udev_enumerate_get_udev(en), udev_list_entry_get_name(entry));
133 ret << Device(
new DevicePrivate(ud,
false));
136 udev_enumerate_unref(en);
143 , d(new ClientPrivate(this))
145 d->init(
QStringList(), ClientPrivate::ListenToNone);
150 , d(new ClientPrivate(this))
152 d->init(subsystemList, ClientPrivate::ListenToList);
163 if (!d->watchedSubsystems.isEmpty()) {
164 return d->watchedSubsystems;
174 struct udev_enumerate *en = udev_enumerate_new(d->udev);
175 udev_enumerate_scan_subsystems(en);
176 QStringList s = listFromListEntry(udev_enumerate_get_list_entry(en));
177 udev_enumerate_unref(en);
181void Client::setWatchedSubsystems(
const QStringList &subsystemList)
183 d->setWatchedSubsystems(subsystemList);
186DeviceList Client::devicesByProperty(
const QString &property,
const QVariant &value)
188 struct udev_enumerate *en = udev_enumerate_new(d->udev);
196 return d->deviceListFromEnumerate(en);
199DeviceList Client::allDevices()
201 struct udev_enumerate *en = udev_enumerate_new(d->udev);
202 return d->deviceListFromEnumerate(en);
205DeviceList Client::devicesBySubsystem(
const QString &subsystem)
207 struct udev_enumerate *en = udev_enumerate_new(d->udev);
210 return d->deviceListFromEnumerate(en);
213DeviceList Client::devicesBySubsystemsAndProperties(
const QStringList &subsystems,
const QVariantMap &properties)
215 struct udev_enumerate *en = udev_enumerate_new(d->udev);
217 for (
const QString &subsystem : subsystems) {
222 if (it.value().isValid()) {
223 udev_enumerate_add_match_property(en, it.key().toLatin1().constData(), it.value().toString().toLatin1().constData());
225 udev_enumerate_add_match_property(en, it.key().toLatin1().constData(),
nullptr);
229 return d->deviceListFromEnumerate(en);
232Device Client::deviceByDeviceFile(
const QString &deviceFile)
240 struct udev_device *ud =
nullptr;
242 if (S_ISBLK(sb.st_mode)) {
243 ud = udev_device_new_from_devnum(d->udev,
'b', sb.st_rdev);
244 }
else if (S_ISCHR(sb.st_mode)) {
245 ud = udev_device_new_from_devnum(d->udev,
'c', sb.st_rdev);
252 return Device(
new DevicePrivate(ud,
false));
255Device Client::deviceBySysfsPath(
const QString &sysfsPath)
257 struct udev_device *ud = udev_device_new_from_syspath(d->udev, sysfsPath.
toLatin1().
constData());
263 return Device(
new DevicePrivate(ud,
false));
266Device Client::deviceBySubsystemAndName(
const QString &subsystem,
const QString &name)
268 struct udev_device *ud = udev_device_new_from_subsystem_sysname(d->udev,
276 return Device(
new DevicePrivate(ud,
false));
281#include "moc_udevqtclient.cpp"
KIOCORE_EXPORT QStringList list(const QString &fileClass)
const QList< QKeySequence > & end()
QString name(StandardShortcut id)
const char * constData() const const
QByteArray left(qsizetype len) const const
QByteArray mid(qsizetype pos, qsizetype len) const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QByteArray toLatin1() const const
bool isValid() const const
QString toString() const const