Chromium Code Reviews| Index: udev-device.cc |
| diff --git a/udev-device.cc b/udev-device.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..608cf1899d2edf1e390bb9322e779864fcb4f388 |
| --- /dev/null |
| +++ b/udev-device.cc |
| @@ -0,0 +1,152 @@ |
| +// Copyright (c) 2011 The Chromium OS Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <base/string_number_conversions.h> |
| +#include <base/string_util.h> |
| +#include <libudev.h> |
| +#include <sys/statvfs.h> |
| +#include <fcntl.h> |
| +#include <fstream> |
| + |
| +#include "udev-device.h" |
| + |
| +namespace cros_disks { |
| + |
| +UdevDevice::UdevDevice(struct udev_device *dev) |
| + : dev_(dev) { |
| + |
| + CHECK(dev_) << "Invalid udev device"; |
| + udev_device_ref(dev_); |
| +} |
| + |
| +UdevDevice::~UdevDevice() { |
| + udev_device_unref(dev_); |
| +} |
| + |
| +bool UdevDevice::IsValueBooleanTrue(const char *value) const { |
| + return value && strcmp(value, "1") == 0; |
| +} |
| + |
| +std::string UdevDevice::GetAttribute(const char *key) const { |
| + const char *value = udev_device_get_sysattr_value(dev_, key); |
| + return (value) ? value : ""; |
| +} |
| + |
| +bool UdevDevice::IsAttributeTrue(const char *key) const { |
| + const char *value = udev_device_get_sysattr_value(dev_, key); |
| + return IsValueBooleanTrue(value); |
| +} |
| + |
| +bool UdevDevice::HasAttribute(const char *key) const { |
| + const char *value = udev_device_get_sysattr_value(dev_, key); |
| + return value != NULL; |
| +} |
| + |
| +std::string UdevDevice::GetProperty(const char *key) const { |
| + const char *value = udev_device_get_property_value(dev_, key); |
| + return (value) ? value : ""; |
| +} |
| + |
| +bool UdevDevice::IsPropertyTrue(const char *key) const { |
| + const char *value = udev_device_get_property_value(dev_, key); |
| + return IsValueBooleanTrue(value); |
| +} |
| + |
| +bool UdevDevice::HasProperty(const char *key) const { |
| + const char *value = udev_device_get_property_value(dev_, key); |
| + return value != NULL; |
| +} |
| + |
| +void UdevDevice::GetSizeInfo(uint64 *total_size, uint64 *remaining_size) const { |
| + const char *dev_file = udev_device_get_devnode(dev_); |
| + |
| + struct statvfs stat; |
| + bool stat_available = (statvfs(dev_file, &stat) == 0); |
| + |
| + if (total_size) { |
| + *total_size = (stat_available) ? (stat.f_blocks * stat.f_frsize) : 0; |
| + const char *partition_size = udev_device_get_property_value(dev_, |
| + "UDISKS_PARTITION_SIZE"); |
| + int64 size = 0; |
| + if (partition_size) { |
| + base::StringToInt64(partition_size, &size); |
| + *total_size = size; |
| + } else { |
| + const char *size_attr = udev_device_get_sysattr_value(dev_, "size"); |
| + if (size_attr) { |
| + base::StringToInt64(size_attr, &size); |
| + *total_size = size; |
| + } |
| + } |
| + } |
| + |
| + if (remaining_size) |
| + *remaining_size = (stat_available) ? (stat.f_bfree * stat.f_frsize) : 0; |
| +} |
| + |
| +bool UdevDevice::IsMediaAvailable() const { |
| + bool is_media_available = true; |
| + if (IsAttributeTrue("removable")) { |
| + if (IsPropertyTrue("ID_CDROM")) { |
| + is_media_available = IsPropertyTrue("ID_CDROM_MEDIA"); |
| + } else { |
| + const char *dev_file = udev_device_get_devnode(dev_); |
| + int fd = open(dev_file, O_RDONLY); |
| + if (fd < 0) { |
| + is_media_available = true; |
| + } else { |
| + close(fd); |
| + } |
| + } |
| + } |
| + return is_media_available; |
| +} |
| + |
| +std::vector<std::string> UdevDevice::GetMountedPaths() const { |
|
rtc
2011/04/12 21:12:01
It might be good to pass data into the function so
Ben Chan
2011/04/12 21:18:46
How about splitting the function into two?
std::v
|
| + const std::string dev_file = udev_device_get_devnode(dev_); |
| + std::vector<std::string> mounted_paths; |
| + std::ifstream fs("/proc/mounts"); |
| + if (fs.is_open()) { |
| + std::string line; |
| + while (std::getline(fs, line)) { |
| + std::vector<std::string> tokens; |
| + SplitString(line, ' ', &tokens); |
| + if (tokens.size() >= 2) { |
| + if (tokens[0] == dev_file) |
| + mounted_paths.push_back(tokens[1]); |
| + } |
| + } |
| + } |
| + return mounted_paths; |
| +} |
| + |
| +Disk UdevDevice::ToDisk() const { |
| + Disk disk; |
| + |
| + disk.set_is_read_only(IsAttributeTrue("ro")); |
| + disk.set_is_drive(HasAttribute("range")); |
| + disk.set_is_rotational(HasProperty("ID_ATA_ROTATION_RATE_RPM")); |
| + disk.set_is_optical_disk(IsPropertyTrue("ID_CDROM")); |
| + disk.set_is_hidden(IsPropertyTrue("UDISKS_PRESENTATION_HIDE")); |
| + disk.set_is_media_available(IsMediaAvailable()); |
| + disk.set_drive_model(GetProperty("ID_MODEL")); |
| + disk.set_label(GetProperty("ID_FS_LABEL")); |
| + disk.set_native_path(udev_device_get_syspath(dev_)); |
| + |
| + const char *dev_file = udev_device_get_devnode(dev_); |
| + disk.set_device_file(dev_file); |
| + |
| + std::vector<std::string> mounted_paths = GetMountedPaths(); |
| + disk.set_is_mounted(!mounted_paths.empty()); |
| + disk.set_mount_path(mounted_paths[0]); //TODO(benchan): multiple paths |
| + |
| + uint64 total_size, remaining_size; |
| + GetSizeInfo(&total_size, &remaining_size); |
| + disk.set_device_capacity(total_size); |
| + disk.set_bytes_remaining(remaining_size); |
| + |
| + return disk; |
| +} |
| + |
| +} // namespace cros_disks |