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.h>
6
7 #include <libudev.h>
8
9 #include <base/format_macros.h>
10 #include <base/logging.h>
11 #include <base/strings/stringprintf.h>
12 #include <brillo/udev/udev_device.h>
13 #include <brillo/udev/udev_enumerate.h>
14 #include <brillo/udev/udev_monitor.h>
15
16 using base::StringPrintf;
17
18 namespace brillo {
19
Udev(struct udev * udev)20 Udev::Udev(struct udev* udev) : udev_(udev) {}
21
~Udev()22 Udev::~Udev() {
23 if (udev_) {
24 udev_unref(udev_);
25 udev_ = nullptr;
26 }
27 }
28
29 // static
Create()30 std::unique_ptr<Udev> Udev::Create() {
31 struct udev* udev = udev_new();
32 if (!udev)
33 return nullptr;
34
35 return std::unique_ptr<Udev>(new Udev(udev));
36 }
37
38 // static
CreateDevice(udev_device * device)39 std::unique_ptr<UdevDevice> Udev::CreateDevice(udev_device* device) {
40 auto device_to_return = std::make_unique<UdevDevice>(device);
41
42 // UdevDevice increases the reference count of the udev_device struct by one.
43 // Thus, decrease the reference count of the udev_device struct by one before
44 // returning UdevDevice.
45 udev_device_unref(device);
46
47 return device_to_return;
48 }
49
CreateDeviceFromSysPath(const char * sys_path)50 std::unique_ptr<UdevDevice> Udev::CreateDeviceFromSysPath(
51 const char* sys_path) {
52 udev_device* device = udev_device_new_from_syspath(udev_, sys_path);
53 if (device)
54 return CreateDevice(device);
55
56 VLOG(2) << StringPrintf(
57 "udev_device_new_from_syspath"
58 "(%p, \"%s\") returned nullptr.",
59 udev_, sys_path);
60 return nullptr;
61 }
62
CreateDeviceFromDeviceNumber(char type,dev_t device_number)63 std::unique_ptr<UdevDevice> Udev::CreateDeviceFromDeviceNumber(
64 char type, dev_t device_number) {
65 udev_device* device = udev_device_new_from_devnum(udev_, type, device_number);
66 if (device)
67 return CreateDevice(device);
68
69 VLOG(2) << StringPrintf(
70 "udev_device_new_from_devnum"
71 "(%p, %d, %" PRIu64 ") returned nullptr.",
72 udev_, type, device_number);
73 return nullptr;
74 }
75
CreateDeviceFromSubsystemSysName(const char * subsystem,const char * sys_name)76 std::unique_ptr<UdevDevice> Udev::CreateDeviceFromSubsystemSysName(
77 const char* subsystem, const char* sys_name) {
78 udev_device* device =
79 udev_device_new_from_subsystem_sysname(udev_, subsystem, sys_name);
80 if (device)
81 return CreateDevice(device);
82
83 VLOG(2) << StringPrintf(
84 "udev_device_new_from_subsystem_sysname"
85 "(%p, \"%s\", \"%s\") returned nullptr.",
86 udev_, subsystem, sys_name);
87 return nullptr;
88 }
89
CreateEnumerate()90 std::unique_ptr<UdevEnumerate> Udev::CreateEnumerate() {
91 udev_enumerate* enumerate = udev_enumerate_new(udev_);
92 if (enumerate) {
93 auto enumerate_to_return = std::make_unique<UdevEnumerate>(enumerate);
94
95 // UdevEnumerate increases the reference count of the udev_enumerate struct
96 // by one. Thus, decrease the reference count of the udev_enumerate struct
97 // by one before returning UdevEnumerate.
98 udev_enumerate_unref(enumerate);
99
100 return enumerate_to_return;
101 }
102
103 VLOG(2) << StringPrintf("udev_enumerate_new(%p) returned nullptr.", udev_);
104 return nullptr;
105 }
106
CreateMonitorFromNetlink(const char * name)107 std::unique_ptr<UdevMonitor> Udev::CreateMonitorFromNetlink(const char* name) {
108 udev_monitor* monitor = udev_monitor_new_from_netlink(udev_, name);
109 if (monitor) {
110 auto monitor_to_return = std::make_unique<UdevMonitor>(monitor);
111
112 // UdevMonitor increases the reference count of the udev_monitor struct by
113 // one. Thus, decrease the reference count of the udev_monitor struct by one
114 // before returning UdevMonitor.
115 udev_monitor_unref(monitor);
116
117 return monitor_to_return;
118 }
119
120 VLOG(2) << StringPrintf(
121 "udev_monitor_new_from_netlink"
122 "(%p, \"%s\") returned nullptr.",
123 udev_, name);
124 return nullptr;
125 }
126
127 } // namespace brillo
128