Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright (c) 2011 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 <base/string_number_conversions.h> | |
| 6 #include <base/string_util.h> | |
| 7 #include <libudev.h> | |
| 8 #include <sys/statvfs.h> | |
| 9 #include <fcntl.h> | |
| 10 #include <fstream> | |
| 11 | |
| 12 #include "udev-device.h" | |
| 13 | |
| 14 namespace cros_disks { | |
| 15 | |
| 16 UdevDevice::UdevDevice(struct udev_device *dev) | |
| 17 : dev_(dev) { | |
| 18 | |
| 19 CHECK(dev_) << "Invalid udev device"; | |
| 20 udev_device_ref(dev_); | |
| 21 } | |
| 22 | |
| 23 UdevDevice::~UdevDevice() { | |
| 24 udev_device_unref(dev_); | |
| 25 } | |
| 26 | |
| 27 bool UdevDevice::IsValueBooleanTrue(const char *value) const { | |
| 28 return value && strcmp(value, "1") == 0; | |
| 29 } | |
| 30 | |
| 31 std::string UdevDevice::GetAttribute(const char *key) const { | |
| 32 const char *value = udev_device_get_sysattr_value(dev_, key); | |
| 33 return (value) ? value : ""; | |
| 34 } | |
| 35 | |
| 36 bool UdevDevice::IsAttributeTrue(const char *key) const { | |
| 37 const char *value = udev_device_get_sysattr_value(dev_, key); | |
| 38 return IsValueBooleanTrue(value); | |
| 39 } | |
| 40 | |
| 41 bool UdevDevice::HasAttribute(const char *key) const { | |
| 42 const char *value = udev_device_get_sysattr_value(dev_, key); | |
| 43 return value != NULL; | |
| 44 } | |
| 45 | |
| 46 std::string UdevDevice::GetProperty(const char *key) const { | |
| 47 const char *value = udev_device_get_property_value(dev_, key); | |
| 48 return (value) ? value : ""; | |
| 49 } | |
| 50 | |
| 51 bool UdevDevice::IsPropertyTrue(const char *key) const { | |
| 52 const char *value = udev_device_get_property_value(dev_, key); | |
| 53 return IsValueBooleanTrue(value); | |
| 54 } | |
| 55 | |
| 56 bool UdevDevice::HasProperty(const char *key) const { | |
| 57 const char *value = udev_device_get_property_value(dev_, key); | |
| 58 return value != NULL; | |
| 59 } | |
| 60 | |
| 61 void UdevDevice::GetSizeInfo(uint64 *total_size, uint64 *remaining_size) const { | |
| 62 const char *dev_file = udev_device_get_devnode(dev_); | |
| 63 | |
| 64 struct statvfs stat; | |
| 65 bool stat_available = (statvfs(dev_file, &stat) == 0); | |
| 66 | |
| 67 if (total_size) { | |
| 68 *total_size = (stat_available) ? (stat.f_blocks * stat.f_frsize) : 0; | |
| 69 const char *partition_size = udev_device_get_property_value(dev_, | |
| 70 "UDISKS_PARTITION_SIZE"); | |
| 71 int64 size = 0; | |
| 72 if (partition_size) { | |
| 73 base::StringToInt64(partition_size, &size); | |
| 74 *total_size = size; | |
| 75 } else { | |
| 76 const char *size_attr = udev_device_get_sysattr_value(dev_, "size"); | |
| 77 if (size_attr) { | |
| 78 base::StringToInt64(size_attr, &size); | |
| 79 *total_size = size; | |
| 80 } | |
| 81 } | |
| 82 } | |
| 83 | |
| 84 if (remaining_size) | |
| 85 *remaining_size = (stat_available) ? (stat.f_bfree * stat.f_frsize) : 0; | |
| 86 } | |
| 87 | |
| 88 bool UdevDevice::IsMediaAvailable() const { | |
| 89 bool is_media_available = true; | |
| 90 if (IsAttributeTrue("removable")) { | |
| 91 if (IsPropertyTrue("ID_CDROM")) { | |
| 92 is_media_available = IsPropertyTrue("ID_CDROM_MEDIA"); | |
| 93 } else { | |
| 94 const char *dev_file = udev_device_get_devnode(dev_); | |
| 95 int fd = open(dev_file, O_RDONLY); | |
| 96 if (fd < 0) { | |
| 97 is_media_available = true; | |
| 98 } else { | |
| 99 close(fd); | |
| 100 } | |
| 101 } | |
| 102 } | |
| 103 return is_media_available; | |
| 104 } | |
| 105 | |
| 106 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
| |
| 107 const std::string dev_file = udev_device_get_devnode(dev_); | |
| 108 std::vector<std::string> mounted_paths; | |
| 109 std::ifstream fs("/proc/mounts"); | |
| 110 if (fs.is_open()) { | |
| 111 std::string line; | |
| 112 while (std::getline(fs, line)) { | |
| 113 std::vector<std::string> tokens; | |
| 114 SplitString(line, ' ', &tokens); | |
| 115 if (tokens.size() >= 2) { | |
| 116 if (tokens[0] == dev_file) | |
| 117 mounted_paths.push_back(tokens[1]); | |
| 118 } | |
| 119 } | |
| 120 } | |
| 121 return mounted_paths; | |
| 122 } | |
| 123 | |
| 124 Disk UdevDevice::ToDisk() const { | |
| 125 Disk disk; | |
| 126 | |
| 127 disk.set_is_read_only(IsAttributeTrue("ro")); | |
| 128 disk.set_is_drive(HasAttribute("range")); | |
| 129 disk.set_is_rotational(HasProperty("ID_ATA_ROTATION_RATE_RPM")); | |
| 130 disk.set_is_optical_disk(IsPropertyTrue("ID_CDROM")); | |
| 131 disk.set_is_hidden(IsPropertyTrue("UDISKS_PRESENTATION_HIDE")); | |
| 132 disk.set_is_media_available(IsMediaAvailable()); | |
| 133 disk.set_drive_model(GetProperty("ID_MODEL")); | |
| 134 disk.set_label(GetProperty("ID_FS_LABEL")); | |
| 135 disk.set_native_path(udev_device_get_syspath(dev_)); | |
| 136 | |
| 137 const char *dev_file = udev_device_get_devnode(dev_); | |
| 138 disk.set_device_file(dev_file); | |
| 139 | |
| 140 std::vector<std::string> mounted_paths = GetMountedPaths(); | |
| 141 disk.set_is_mounted(!mounted_paths.empty()); | |
| 142 disk.set_mount_path(mounted_paths[0]); //TODO(benchan): multiple paths | |
| 143 | |
| 144 uint64 total_size, remaining_size; | |
| 145 GetSizeInfo(&total_size, &remaining_size); | |
| 146 disk.set_device_capacity(total_size); | |
| 147 disk.set_bytes_remaining(remaining_size); | |
| 148 | |
| 149 return disk; | |
| 150 } | |
| 151 | |
| 152 } // namespace cros_disks | |
| OLD | NEW |