1 // Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include <brillo/udev/udev_monitor.h>
6
7 #include <libudev.h>
8
9 #include <base/logging.h>
10 #include <base/strings/stringprintf.h>
11 #include <brillo/udev/udev_device.h>
12
13 using base::StringPrintf;
14
15 namespace brillo {
16
UdevMonitor()17 UdevMonitor::UdevMonitor() : monitor_(nullptr) {}
18
UdevMonitor(udev_monitor * monitor)19 UdevMonitor::UdevMonitor(udev_monitor* monitor) : monitor_(monitor) {
20 CHECK(monitor_);
21
22 udev_monitor_ref(monitor_);
23 }
24
~UdevMonitor()25 UdevMonitor::~UdevMonitor() {
26 if (monitor_) {
27 udev_monitor_unref(monitor_);
28 monitor_ = nullptr;
29 }
30 }
31
EnableReceiving()32 bool UdevMonitor::EnableReceiving() {
33 int result = udev_monitor_enable_receiving(monitor_);
34 if (result == 0)
35 return true;
36
37 VLOG(2) << StringPrintf("udev_monitor_enable_receiving(%p) returned %d.",
38 monitor_, result);
39 return false;
40 }
41
GetFileDescriptor() const42 int UdevMonitor::GetFileDescriptor() const {
43 int file_descriptor = udev_monitor_get_fd(monitor_);
44 if (file_descriptor >= 0)
45 return file_descriptor;
46
47 VLOG(2) << StringPrintf("udev_monitor_get_fd(%p) returned %d.", monitor_,
48 file_descriptor);
49 return kInvalidFileDescriptor;
50 }
51
ReceiveDevice()52 std::unique_ptr<UdevDevice> UdevMonitor::ReceiveDevice() {
53 udev_device* received_device = udev_monitor_receive_device(monitor_);
54 if (received_device) {
55 auto device = std::make_unique<UdevDevice>(received_device);
56 // udev_monitor_receive_device increases the reference count of the returned
57 // udev_device struct, while UdevDevice also holds a reference count of the
58 // udev_device struct. Thus, decrease the reference count of the udev_device
59 // struct.
60 udev_device_unref(received_device);
61 return device;
62 }
63
64 VLOG(2) << StringPrintf("udev_monitor_receive_device(%p) returned nullptr.",
65 monitor_);
66 return nullptr;
67 }
68
FilterAddMatchSubsystemDeviceType(const char * subsystem,const char * device_type)69 bool UdevMonitor::FilterAddMatchSubsystemDeviceType(const char* subsystem,
70 const char* device_type) {
71 int result = udev_monitor_filter_add_match_subsystem_devtype(
72 monitor_, subsystem, device_type);
73 if (result == 0)
74 return true;
75
76 VLOG(2) << StringPrintf(
77 "udev_monitor_filter_add_match_subsystem_devtype (%p, \"%s\", \"%s\") "
78 "returned %d.",
79 monitor_, subsystem, device_type, result);
80 return false;
81 }
82
FilterAddMatchTag(const char * tag)83 bool UdevMonitor::FilterAddMatchTag(const char* tag) {
84 int result = udev_monitor_filter_add_match_tag(monitor_, tag);
85 if (result == 0)
86 return true;
87
88 VLOG(2) << StringPrintf(
89 "udev_monitor_filter_add_tag (%p, \"%s\") returned %d.", monitor_, tag,
90 result);
91 return false;
92 }
93
FilterUpdate()94 bool UdevMonitor::FilterUpdate() {
95 int result = udev_monitor_filter_update(monitor_);
96 if (result == 0)
97 return true;
98
99 VLOG(2) << StringPrintf("udev_monitor_filter_update(%p) returned %d.",
100 monitor_, result);
101 return false;
102 }
103
FilterRemove()104 bool UdevMonitor::FilterRemove() {
105 int result = udev_monitor_filter_remove(monitor_);
106 if (result == 0)
107 return true;
108
109 VLOG(2) << StringPrintf("udev_monitor_filter_remove(%p) returned %d.",
110 monitor_, result);
111 return false;
112 }
113
114 } // namespace brillo
115