shill: Clean up of DeviceInfo::GetMACAddressFromKernel
- Simplified GetMACAddressFromKernel by removing unnecessary code.
- Use the Sockets class.
- Add unit tests for GetMACAddressFromKernel.
- Add comments and a unit test for a "gotcha" case in ByteString.
- Add HANDLE_EINTR to Sockets.
BUG=None
TEST=All unit tests pass. Mobile, WiFi, and Ethernet work on alex.
Change-Id: I3f55daf916edb62332b4c6a2aee224d53eefd2df
Reviewed-on: https://gerrit.chromium.org/gerrit/28865
Commit-Ready: Gary Morain <gmorain@chromium.org>
Reviewed-by: Gary Morain <gmorain@chromium.org>
Tested-by: Gary Morain <gmorain@chromium.org>
diff --git a/device_info.cc b/device_info.cc
index 76f479a..5982c5f 100644
--- a/device_info.cc
+++ b/device_info.cc
@@ -39,6 +39,7 @@
#include "shill/rtnl_listener.h"
#include "shill/rtnl_message.h"
#include "shill/service.h"
+#include "shill/sockets.h"
#include "shill/virtio_ethernet.h"
#include "shill/wifi.h"
@@ -87,7 +88,8 @@
address_listener_(NULL),
device_info_root_(kDeviceInfoRoot),
routing_table_(RoutingTable::GetInstance()),
- rtnl_handler_(RTNLHandler::GetInstance()) {
+ rtnl_handler_(RTNLHandler::GetInstance()),
+ sockets_(new Sockets()) {
}
DeviceInfo::~DeviceInfo() {}
@@ -451,7 +453,6 @@
msg.mode() == RTNLMessage::kModeAdd);
int dev_index = msg.interface_index();
Technology::Identifier technology = Technology::kUnknown;
-
unsigned int flags = msg.link_status().flags;
unsigned int change = msg.link_status().change;
bool new_device =
@@ -547,32 +548,29 @@
}
ByteString DeviceInfo::GetMACAddressFromKernel(int interface_index) const {
- ByteString mac_address;
- mac_address.Clear();
- // TODO(gmorain): Use ScopedSocketCloser instead.
- const int fd = socket(PF_INET, SOCK_DGRAM, 0);
+ const Info *info = GetInfo(interface_index);
+ if (!info) {
+ return ByteString();
+ }
+
+ const int fd = sockets_->Socket(PF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
LOG(ERROR) << __func__ << ": Unable to open socket: " << fd;
- return mac_address;
+ return ByteString();
}
+
+ ScopedSocketCloser socket_closer(sockets_.get(), fd);
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
ifr.ifr_ifindex = interface_index;
- int err = HANDLE_EINTR(ioctl(fd, SIOCGIFNAME, &ifr));
- if (err < 0) {
- LOG(ERROR) << __func__ << ": Unable to read ifname: " << errno;
- close(fd);
- return mac_address;
- }
- err = HANDLE_EINTR(ioctl(fd, SIOCGIFHWADDR, &ifr));
- close(fd);
+ strcpy(ifr.ifr_ifrn.ifrn_name, info->name.c_str());
+ int err = sockets_->Ioctl(fd, SIOCGIFHWADDR, &ifr);
if (err < 0) {
LOG(ERROR) << __func__ << ": Unable to read MAC address: " << errno;
- return mac_address;
+ return ByteString();
}
- mac_address.Resize(IFHWADDRLEN);
- memcpy(mac_address.GetData(), ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
- return mac_address;
+
+ return ByteString(ifr.ifr_hwaddr.sa_data, IFHWADDRLEN);
}
bool DeviceInfo::GetAddresses(int interface_index,