Merge "libcutils: remove rather than fix the mutex."
diff --git a/base/file.cpp b/base/file.cpp
index 2f697a1..d6fe753 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -199,17 +199,23 @@
bool RemoveFileIfExists(const std::string& path, std::string* err) {
struct stat st;
#if defined(_WIN32)
- //TODO: Windows version can't handle symbol link correctly.
+ // TODO: Windows version can't handle symbolic links correctly.
int result = stat(path.c_str(), &st);
bool file_type_removable = (result == 0 && S_ISREG(st.st_mode));
#else
int result = lstat(path.c_str(), &st);
bool file_type_removable = (result == 0 && (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)));
#endif
+ if (result == -1) {
+ if (errno == ENOENT || errno == ENOTDIR) return true;
+ if (err != nullptr) *err = strerror(errno);
+ return false;
+ }
+
if (result == 0) {
if (!file_type_removable) {
if (err != nullptr) {
- *err = "is not a regular or symbol link file";
+ *err = "is not a regular file or symbolic link";
}
return false;
}
diff --git a/base/file_test.cpp b/base/file_test.cpp
index 02b431d..6794652 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -26,6 +26,10 @@
#include "android-base/test_utils.h"
+#if !defined(_WIN32)
+#include <pwd.h>
+#endif
+
TEST(file, ReadFileToString_ENOENT) {
std::string s("hello");
errno = 0;
@@ -115,7 +119,7 @@
ASSERT_FALSE(android::base::ReadFully(tf.fd, &s[0], s.size()));
}
-TEST(file, RemoveFileIfExist) {
+TEST(file, RemoveFileIfExists) {
TemporaryFile tf;
ASSERT_TRUE(tf.fd != -1);
close(tf.fd);
@@ -126,9 +130,43 @@
TemporaryDir td;
ASSERT_FALSE(android::base::RemoveFileIfExists(td.path));
ASSERT_FALSE(android::base::RemoveFileIfExists(td.path, &err));
- ASSERT_EQ("is not a regular or symbol link file", err);
+ ASSERT_EQ("is not a regular file or symbolic link", err);
}
+TEST(file, RemoveFileIfExists_ENOTDIR) {
+ TemporaryFile tf;
+ close(tf.fd);
+ tf.fd = -1;
+ std::string err{"xxx"};
+ ASSERT_TRUE(android::base::RemoveFileIfExists(std::string{tf.path} + "/abc", &err));
+ ASSERT_EQ("xxx", err);
+}
+
+#if !defined(_WIN32)
+TEST(file, RemoveFileIfExists_EACCES) {
+ // EACCES -- one of the directories in the path has no search permission
+ // root can bypass permission restrictions, so drop root.
+ if (getuid() == 0) {
+ passwd* shell = getpwnam("shell");
+ setgid(shell->pw_gid);
+ setuid(shell->pw_uid);
+ }
+
+ TemporaryDir td;
+ TemporaryFile tf(td.path);
+ close(tf.fd);
+ tf.fd = -1;
+ std::string err{"xxx"};
+ // Remove dir's search permission.
+ ASSERT_TRUE(chmod(td.path, S_IRUSR | S_IWUSR) == 0);
+ ASSERT_FALSE(android::base::RemoveFileIfExists(tf.path, &err));
+ ASSERT_EQ("Permission denied", err);
+ // Set dir's search permission again.
+ ASSERT_TRUE(chmod(td.path, S_IRWXU) == 0);
+ ASSERT_TRUE(android::base::RemoveFileIfExists(tf.path, &err));
+}
+#endif
+
TEST(file, Readlink) {
#if !defined(_WIN32)
// Linux doesn't allow empty symbolic links.
diff --git a/fs_mgr/liblp/builder.cpp b/fs_mgr/liblp/builder.cpp
index 720590d..d15fa8c 100644
--- a/fs_mgr/liblp/builder.cpp
+++ b/fs_mgr/liblp/builder.cpp
@@ -27,8 +27,8 @@
#include <android-base/unique_fd.h>
#include <uuid/uuid.h>
-#include "liblp/metadata_format.h"
-#include "liblp/reader.h"
+#include "liblp/liblp.h"
+#include "reader.h"
#include "utility.h"
namespace android {
diff --git a/fs_mgr/liblp/include/liblp/builder.h b/fs_mgr/liblp/include/liblp/builder.h
index 3cd95ae..8bde313 100644
--- a/fs_mgr/liblp/include/liblp/builder.h
+++ b/fs_mgr/liblp/include/liblp/builder.h
@@ -23,7 +23,7 @@
#include <map>
#include <memory>
-#include "metadata_format.h"
+#include "liblp.h"
namespace android {
namespace fs_mgr {
diff --git a/fs_mgr/liblp/include/liblp/liblp.h b/fs_mgr/liblp/include/liblp/liblp.h
new file mode 100644
index 0000000..469ef9e
--- /dev/null
+++ b/fs_mgr/liblp/include/liblp/liblp.h
@@ -0,0 +1,75 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#ifndef LIBLP_LIBLP_H
+#define LIBLP_LIBLP_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+#include <memory>
+#include <string>
+
+#include "metadata_format.h"
+
+namespace android {
+namespace fs_mgr {
+
+// Helper structure for easily interpreting deserialized metadata, or
+// re-serializing metadata.
+struct LpMetadata {
+ LpMetadataGeometry geometry;
+ LpMetadataHeader header;
+ std::vector<LpMetadataPartition> partitions;
+ std::vector<LpMetadataExtent> extents;
+};
+
+// Place an initial partition table on the device. This will overwrite the
+// existing geometry, and should not be used for normal partition table
+// updates. False can be returned if the geometry is incompatible with the
+// block device or an I/O error occurs.
+bool FlashPartitionTable(const std::string& block_device, const LpMetadata& metadata,
+ uint32_t slot_number);
+
+// Update the partition table for a given metadata slot number. False is
+// returned if an error occurs, which can include:
+// - Invalid slot number.
+// - I/O error.
+// - Corrupt or missing metadata geometry on disk.
+// - Incompatible geometry.
+bool UpdatePartitionTable(const std::string& block_device, const LpMetadata& metadata,
+ uint32_t slot_number);
+
+// Read logical partition metadata from its predetermined location on a block
+// device. If readback fails, we also attempt to load from a backup copy.
+std::unique_ptr<LpMetadata> ReadMetadata(const char* block_device, uint32_t slot_number);
+
+// Read/Write logical partition metadata to an image file, for diagnostics or
+// flashing.
+bool WriteToImageFile(const char* file, const LpMetadata& metadata);
+std::unique_ptr<LpMetadata> ReadFromImageFile(const char* file);
+
+// Helper to extract safe C++ strings from partition info.
+std::string GetPartitionName(const LpMetadataPartition& partition);
+std::string GetPartitionGuid(const LpMetadataPartition& partition);
+
+// Helper to return a slot number for a slot suffix.
+uint32_t SlotNumberForSlotSuffix(const std::string& suffix);
+
+} // namespace fs_mgr
+} // namespace android
+
+#endif // LIBLP_LIBLP_H
diff --git a/fs_mgr/liblp/include/liblp/metadata_format.h b/fs_mgr/liblp/include/liblp/metadata_format.h
index 27602ac..b5202f0 100644
--- a/fs_mgr/liblp/include/liblp/metadata_format.h
+++ b/fs_mgr/liblp/include/liblp/metadata_format.h
@@ -67,7 +67,7 @@
* | Geometry Backup |
* +--------------------+
*/
-#define LP_METADATA_PARTITION_NAME "android"
+#define LP_METADATA_PARTITION_NAME "super"
/* Size of a sector is always 512 bytes for compatibility with the Linux kernel. */
#define LP_SECTOR_SIZE 512
@@ -262,28 +262,4 @@
} /* extern "C" */
#endif
-#ifdef __cplusplus
-namespace android {
-namespace fs_mgr {
-
-// Helper structure for easily interpreting deserialized metadata, or
-// re-serializing metadata.
-struct LpMetadata {
- LpMetadataGeometry geometry;
- LpMetadataHeader header;
- std::vector<LpMetadataPartition> partitions;
- std::vector<LpMetadataExtent> extents;
-};
-
-// Helper to extract safe C++ strings from partition info.
-std::string GetPartitionName(const LpMetadataPartition& partition);
-std::string GetPartitionGuid(const LpMetadataPartition& partition);
-
-// Helper to return a slot number for a slot suffix.
-uint32_t SlotNumberForSlotSuffix(const std::string& suffix);
-
-} // namespace fs_mgr
-} // namespace android
-#endif
-
#endif /* LOGICAL_PARTITION_METADATA_FORMAT_H_ */
diff --git a/fs_mgr/liblp/io_test.cpp b/fs_mgr/liblp/io_test.cpp
index c3f8f36..e91cc3e 100644
--- a/fs_mgr/liblp/io_test.cpp
+++ b/fs_mgr/liblp/io_test.cpp
@@ -23,10 +23,10 @@
#include <android-base/unique_fd.h>
#include <gtest/gtest.h>
#include <liblp/builder.h>
-#include <liblp/reader.h>
-#include <liblp/writer.h>
+#include "reader.h"
#include "utility.h"
+#include "writer.h"
using namespace std;
using namespace android::fs_mgr;
@@ -399,29 +399,42 @@
// When requested, write garbage instead of the requested bytes, then
// return false.
bool operator()(int fd, const std::string& blob) {
- if (++write_count_ == fail_on_write_) {
+ write_count_++;
+ if (write_count_ == fail_on_write_) {
std::unique_ptr<char[]> new_data = std::make_unique<char[]>(blob.size());
memset(new_data.get(), 0xe5, blob.size());
EXPECT_TRUE(android::base::WriteFully(fd, new_data.get(), blob.size()));
return false;
} else {
- return android::base::WriteFully(fd, blob.data(), blob.size());
+ if (!android::base::WriteFully(fd, blob.data(), blob.size())) {
+ return false;
+ }
+ return fail_after_write_ != write_count_;
}
}
- void FailOnWrite(int number) {
- fail_on_write_ = number;
+ void Reset() {
+ fail_on_write_ = 0;
+ fail_after_write_ = 0;
write_count_ = 0;
}
+ void FailOnWrite(int number) {
+ Reset();
+ fail_on_write_ = number;
+ }
+ void FailAfterWrite(int number) {
+ Reset();
+ fail_after_write_ = number;
+ }
private:
int fail_on_write_ = 0;
+ int fail_after_write_ = 0;
int write_count_ = 0;
};
// Test that an interrupted flash operation on the "primary" copy of metadata
// is not fatal.
-TEST(liblp, FlashPrimaryMetadataFailure) {
- // Initial state.
+TEST(liblp, UpdatePrimaryMetadataFailure) {
unique_fd fd = CreateFlashedDisk();
ASSERT_GE(fd, 0);
@@ -439,7 +452,7 @@
// Flash again, this time fail the backup copy. We should still be able
// to read the primary.
- writer.FailOnWrite(2);
+ writer.FailOnWrite(3);
ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 0, writer));
imported = ReadMetadata(fd, 0);
ASSERT_NE(imported, nullptr);
@@ -447,8 +460,7 @@
// Test that an interrupted flash operation on the "backup" copy of metadata
// is not fatal.
-TEST(liblp, FlashBackupMetadataFailure) {
- // Initial state.
+TEST(liblp, UpdateBackupMetadataFailure) {
unique_fd fd = CreateFlashedDisk();
ASSERT_GE(fd, 0);
@@ -466,12 +478,45 @@
// Flash again, this time fail the primary copy. We should still be able
// to read the primary.
- //
- // TODO(dvander): This is currently not handled correctly. liblp does not
- // guarantee both copies are in sync before the update. The ASSERT_EQ
- // will change to an ASSERT_NE when this is fixed.
- writer.FailOnWrite(1);
+ writer.FailOnWrite(2);
ASSERT_FALSE(UpdatePartitionTable(fd, *imported.get(), 0, writer));
imported = ReadMetadata(fd, 0);
- ASSERT_EQ(imported, nullptr);
+ ASSERT_NE(imported, nullptr);
+}
+
+// Test that an interrupted write *in between* writing metadata will read
+// the correct metadata copy. The primary is always considered newer than
+// the backup.
+TEST(liblp, UpdateMetadataCleanFailure) {
+ unique_fd fd = CreateFlashedDisk();
+ ASSERT_GE(fd, 0);
+
+ BadWriter writer;
+
+ // Change the name of the existing partition.
+ unique_ptr<LpMetadata> new_table = ReadMetadata(fd, 0);
+ ASSERT_NE(new_table, nullptr);
+ ASSERT_GE(new_table->partitions.size(), 1);
+ new_table->partitions[0].name[0]++;
+
+ // Flash it, but fail to write the backup copy.
+ writer.FailAfterWrite(2);
+ ASSERT_FALSE(UpdatePartitionTable(fd, *new_table.get(), 0, writer));
+
+ // When we read back, we should get the updated primary copy.
+ unique_ptr<LpMetadata> imported = ReadMetadata(fd, 0);
+ ASSERT_NE(imported, nullptr);
+ ASSERT_GE(new_table->partitions.size(), 1);
+ ASSERT_EQ(GetPartitionName(new_table->partitions[0]), GetPartitionName(imported->partitions[0]));
+
+ // Flash again. After, the backup and primary copy should be coherent.
+ // Note that the sync step should have used the primary to sync, not
+ // the backup.
+ writer.Reset();
+ ASSERT_TRUE(UpdatePartitionTable(fd, *new_table.get(), 0, writer));
+
+ imported = ReadMetadata(fd, 0);
+ ASSERT_NE(imported, nullptr);
+ ASSERT_GE(new_table->partitions.size(), 1);
+ ASSERT_EQ(GetPartitionName(new_table->partitions[0]), GetPartitionName(imported->partitions[0]));
}
diff --git a/fs_mgr/liblp/reader.cpp b/fs_mgr/liblp/reader.cpp
index a0eeec9..985cf09 100644
--- a/fs_mgr/liblp/reader.cpp
+++ b/fs_mgr/liblp/reader.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "liblp/reader.h"
+#include "reader.h"
#include <stddef.h>
#include <stdlib.h>
@@ -111,16 +111,6 @@
return ParseGeometry(buffer.get(), geometry);
}
-// Helper function to read geometry from a device without an open descriptor.
-bool ReadLogicalPartitionGeometry(const char* block_device, LpMetadataGeometry* geometry) {
- android::base::unique_fd fd(open(block_device, O_RDONLY));
- if (fd < 0) {
- PERROR << __PRETTY_FUNCTION__ << "open failed: " << block_device;
- return false;
- }
- return ReadLogicalPartitionGeometry(fd, geometry);
-}
-
static bool ValidateTableBounds(const LpMetadataHeader& header,
const LpMetadataTableDescriptor& table) {
if (table.offset > header.tables_size) {
@@ -175,8 +165,6 @@
return true;
}
-using ReadMetadataFn = std::function<bool(void* buffer, size_t num_bytes)>;
-
// Parse and validate all metadata at the current position in the given file
// descriptor.
static std::unique_ptr<LpMetadata> ParseMetadata(int fd) {
@@ -243,6 +231,26 @@
return metadata;
}
+std::unique_ptr<LpMetadata> ReadPrimaryMetadata(int fd, const LpMetadataGeometry& geometry,
+ uint32_t slot_number) {
+ int64_t offset = GetPrimaryMetadataOffset(geometry, slot_number);
+ if (SeekFile64(fd, offset, SEEK_SET) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << offset;
+ return nullptr;
+ }
+ return ParseMetadata(fd);
+}
+
+std::unique_ptr<LpMetadata> ReadBackupMetadata(int fd, const LpMetadataGeometry& geometry,
+ uint32_t slot_number) {
+ int64_t offset = GetBackupMetadataOffset(geometry, slot_number);
+ if (SeekFile64(fd, offset, SEEK_END) < 0) {
+ PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << offset;
+ return nullptr;
+ }
+ return ParseMetadata(fd);
+}
+
std::unique_ptr<LpMetadata> ReadMetadata(int fd, uint32_t slot_number) {
LpMetadataGeometry geometry;
if (!ReadLogicalPartitionGeometry(fd, &geometry)) {
@@ -254,24 +262,11 @@
return nullptr;
}
- // First try the primary copy.
- int64_t offset = GetPrimaryMetadataOffset(geometry, slot_number);
- if (SeekFile64(fd, offset, SEEK_SET) < 0) {
- PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << offset;
- return nullptr;
- }
- std::unique_ptr<LpMetadata> metadata = ParseMetadata(fd);
-
- // If the primary copy failed, try the backup copy.
+ // Read the priamry copy, and if that fails, try the backup.
+ std::unique_ptr<LpMetadata> metadata = ReadPrimaryMetadata(fd, geometry, slot_number);
if (!metadata) {
- offset = GetBackupMetadataOffset(geometry, slot_number);
- if (SeekFile64(fd, offset, SEEK_END) < 0) {
- PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << offset;
- return nullptr;
- }
- metadata = ParseMetadata(fd);
+ metadata = ReadBackupMetadata(fd, geometry, slot_number);
}
-
if (metadata) {
metadata->geometry = geometry;
}
diff --git a/fs_mgr/liblp/include/liblp/reader.h b/fs_mgr/liblp/reader.h
similarity index 63%
rename from fs_mgr/liblp/include/liblp/reader.h
rename to fs_mgr/liblp/reader.h
index 982fe65..c4cac8f 100644
--- a/fs_mgr/liblp/include/liblp/reader.h
+++ b/fs_mgr/liblp/reader.h
@@ -21,23 +21,22 @@
#include <memory>
-#include "metadata_format.h"
+#include <liblp/liblp.h>
namespace android {
namespace fs_mgr {
-// Read logical partition metadata from its predetermined location on a block
-// device. If readback fails, we also attempt to load from a backup copy.
-std::unique_ptr<LpMetadata> ReadMetadata(const char* block_device, uint32_t slot_number);
std::unique_ptr<LpMetadata> ReadMetadata(int fd, uint32_t slot_number);
-// Read and validate the logical partition geometry from a block device.
-bool ReadLogicalPartitionGeometry(const char* block_device, LpMetadataGeometry* geometry);
+// Helper functions for manually reading geometry and metadata.
bool ReadLogicalPartitionGeometry(int fd, LpMetadataGeometry* geometry);
-// Read logical partition metadata from an image file that was created with
-// WriteToImageFile().
-std::unique_ptr<LpMetadata> ReadFromImageFile(const char* file);
+// These functions assume a valid geometry and slot number.
+std::unique_ptr<LpMetadata> ReadPrimaryMetadata(int fd, const LpMetadataGeometry& geometry,
+ uint32_t slot_number);
+std::unique_ptr<LpMetadata> ReadBackupMetadata(int fd, const LpMetadataGeometry& geometry,
+ uint32_t slot_number);
+
std::unique_ptr<LpMetadata> ReadFromImageFile(int fd);
} // namespace fs_mgr
diff --git a/fs_mgr/liblp/utility_test.cpp b/fs_mgr/liblp/utility_test.cpp
index dcc569e..2143e13 100644
--- a/fs_mgr/liblp/utility_test.cpp
+++ b/fs_mgr/liblp/utility_test.cpp
@@ -14,8 +14,10 @@
* limitations under the License.
*/
-#include "utility.h"
#include <gtest/gtest.h>
+#include <liblp/liblp.h>
+
+#include "utility.h"
using namespace android;
using namespace android::fs_mgr;
diff --git a/fs_mgr/liblp/writer.cpp b/fs_mgr/liblp/writer.cpp
index 36c7b5a..b85e4ad 100644
--- a/fs_mgr/liblp/writer.cpp
+++ b/fs_mgr/liblp/writer.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include "writer.h"
+
#include <inttypes.h>
#include <unistd.h>
@@ -22,8 +24,7 @@
#include <android-base/file.h>
#include <android-base/unique_fd.h>
-#include "liblp/reader.h"
-#include "liblp/writer.h"
+#include "reader.h"
#include "utility.h"
namespace android {
@@ -130,20 +131,9 @@
return true;
}
-static bool DefaultWriter(int fd, const std::string& blob) {
- return android::base::WriteFully(fd, blob.data(), blob.size());
-}
-
-static bool WriteMetadata(int fd, const LpMetadataGeometry& geometry, uint32_t slot_number,
- const std::string& blob,
- std::function<bool(int, const std::string&)> writer) {
- // Make sure we're writing to a valid metadata slot.
- if (slot_number >= geometry.metadata_slot_count) {
- LERROR << "Invalid logical partition metadata slot number.";
- return false;
- }
-
- // Write the primary copy of the metadata.
+static bool WritePrimaryMetadata(int fd, const LpMetadataGeometry& geometry, uint32_t slot_number,
+ const std::string& blob,
+ const std::function<bool(int, const std::string&)>& writer) {
int64_t primary_offset = GetPrimaryMetadataOffset(geometry, slot_number);
if (SeekFile64(fd, primary_offset, SEEK_SET) < 0) {
PERROR << __PRETTY_FUNCTION__ << "lseek failed: offset " << primary_offset;
@@ -153,8 +143,12 @@
PERROR << __PRETTY_FUNCTION__ << "write " << blob.size() << " bytes failed";
return false;
}
+ return true;
+}
- // Write the backup copy of the metadata.
+static bool WriteBackupMetadata(int fd, const LpMetadataGeometry& geometry, uint32_t slot_number,
+ const std::string& blob,
+ const std::function<bool(int, const std::string&)>& writer) {
int64_t backup_offset = GetBackupMetadataOffset(geometry, slot_number);
int64_t abs_offset = SeekFile64(fd, backup_offset, SEEK_END);
if (abs_offset == (int64_t)-1) {
@@ -173,6 +167,27 @@
return true;
}
+static bool WriteMetadata(int fd, const LpMetadataGeometry& geometry, uint32_t slot_number,
+ const std::string& blob,
+ const std::function<bool(int, const std::string&)>& writer) {
+ // Make sure we're writing to a valid metadata slot.
+ if (slot_number >= geometry.metadata_slot_count) {
+ LERROR << "Invalid logical partition metadata slot number.";
+ return false;
+ }
+ if (!WritePrimaryMetadata(fd, geometry, slot_number, blob, writer)) {
+ return false;
+ }
+ if (!WriteBackupMetadata(fd, geometry, slot_number, blob, writer)) {
+ return false;
+ }
+ return true;
+}
+
+static bool DefaultWriter(int fd, const std::string& blob) {
+ return android::base::WriteFully(fd, blob.data(), blob.size());
+}
+
bool FlashPartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number) {
// Before writing geometry and/or logical partition tables, perform some
// basic checks that the geometry and tables are coherent, and will fit
@@ -205,8 +220,13 @@
return WriteMetadata(fd, metadata.geometry, slot_number, metadata_blob, DefaultWriter);
}
+static bool CompareMetadata(const LpMetadata& a, const LpMetadata& b) {
+ return !memcmp(a.header.header_checksum, b.header.header_checksum,
+ sizeof(a.header.header_checksum));
+}
+
bool UpdatePartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number,
- std::function<bool(int, const std::string&)> writer) {
+ const std::function<bool(int, const std::string&)>& writer) {
// Before writing geometry and/or logical partition tables, perform some
// basic checks that the geometry and tables are coherent, and will fit
// on the given block device.
@@ -227,6 +247,45 @@
LERROR << "Incompatible geometry in new logical partition metadata";
return false;
}
+
+ // Validate the slot number now, before we call Read*Metadata.
+ if (slot_number >= geometry.metadata_slot_count) {
+ LERROR << "Invalid logical partition metadata slot number.";
+ return false;
+ }
+
+ // Try to read both existing copies of the metadata, if any.
+ std::unique_ptr<LpMetadata> primary = ReadPrimaryMetadata(fd, geometry, slot_number);
+ std::unique_ptr<LpMetadata> backup = ReadBackupMetadata(fd, geometry, slot_number);
+
+ if (primary && (!backup || !CompareMetadata(*primary.get(), *backup.get()))) {
+ // If the backup copy does not match the primary copy, we first
+ // synchronize the backup copy. This guarantees that a partial write
+ // still leaves one copy intact.
+ std::string old_blob;
+ if (!ValidateAndSerializeMetadata(fd, *primary.get(), &old_blob)) {
+ LERROR << "Error serializing primary metadata to repair corrupted backup";
+ return false;
+ }
+ if (!WriteBackupMetadata(fd, geometry, slot_number, old_blob, writer)) {
+ LERROR << "Error writing primary metadata to repair corrupted backup";
+ return false;
+ }
+ } else if (backup && !primary) {
+ // The backup copy is coherent, and the primary is not. Sync it for
+ // safety.
+ std::string old_blob;
+ if (!ValidateAndSerializeMetadata(fd, *backup.get(), &old_blob)) {
+ LERROR << "Error serializing primary metadata to repair corrupted backup";
+ return false;
+ }
+ if (!WritePrimaryMetadata(fd, geometry, slot_number, old_blob, writer)) {
+ LERROR << "Error writing primary metadata to repair corrupted backup";
+ return false;
+ }
+ }
+
+ // Both copies should now be in sync, so we can continue the update.
return WriteMetadata(fd, geometry, slot_number, blob, writer);
}
diff --git a/fs_mgr/liblp/include/liblp/writer.h b/fs_mgr/liblp/writer.h
similarity index 61%
rename from fs_mgr/liblp/include/liblp/writer.h
rename to fs_mgr/liblp/writer.h
index f4d1ad7..94c1d31 100644
--- a/fs_mgr/liblp/include/liblp/writer.h
+++ b/fs_mgr/liblp/writer.h
@@ -18,34 +18,20 @@
#define LIBLP_WRITER_H
#include <functional>
-#include "metadata_format.h"
+#include <string>
+
+#include <liblp/liblp.h>
namespace android {
namespace fs_mgr {
-// Place an initial partition table on the device. This will overwrite the
-// existing geometry, and should not be used for normal partition table
-// updates. False can be returned if the geometry is incompatible with the
-// block device or an I/O error occurs.
-bool FlashPartitionTable(const std::string& block_device, const LpMetadata& metadata,
- uint32_t slot_number);
-
-// Update the partition table for a given metadata slot number. False is
-// returned if an error occurs, which can include:
-// - Invalid slot number.
-// - I/O error.
-// - Corrupt or missing metadata geometry on disk.
-// - Incompatible geometry.
-bool UpdatePartitionTable(const std::string& block_device, const LpMetadata& metadata,
- uint32_t slot_number);
-
// These variants are for testing only. The path-based functions should be used
// for actual operation, so that open() is called with the correct flags.
bool FlashPartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number);
bool UpdatePartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number);
bool UpdatePartitionTable(int fd, const LpMetadata& metadata, uint32_t slot_number,
- std::function<bool(int, const std::string&)> writer);
+ const std::function<bool(int, const std::string&)>& writer);
// Helper function to serialize geometry and metadata to a normal file, for
// flashing or debugging.
diff --git a/init/service.cpp b/init/service.cpp
index 95b37ab..4c2747e 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -130,7 +130,7 @@
if (umount2("/sys", MNT_DETACH) == -1) {
return ErrnoError() << "Could not umount(/sys)";
}
- if (mount("", "/sys", "sys", kSafeFlags, "") == -1) {
+ if (mount("", "/sys", "sysfs", kSafeFlags, "") == -1) {
return ErrnoError() << "Could not mount(/sys)";
}
}
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index 58e59d6..37afb98 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -20,6 +20,7 @@
libcutils_nonwindows_sources = [
"android_get_control_file.cpp",
"fs.cpp",
+ "hashmap.cpp",
"multiuser.cpp",
"socket_inaddr_any_server_unix.cpp",
"socket_local_client_unix.cpp",
@@ -61,7 +62,6 @@
"config_utils.cpp",
"fs_config.cpp",
"canned_fs_config.cpp",
- "hashmap.cpp",
"iosched_policy.cpp",
"load_file.cpp",
"native_handle.cpp",
diff --git a/libcutils/hashmap.cpp b/libcutils/hashmap.cpp
index 2a4a52e..57d6006 100644
--- a/libcutils/hashmap.cpp
+++ b/libcutils/hashmap.cpp
@@ -18,7 +18,7 @@
#include <assert.h>
#include <errno.h>
-#include <cutils/threads.h>
+#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
@@ -36,7 +36,7 @@
size_t bucketCount;
int (*hash)(void* key);
bool (*equals)(void* keyA, void* keyB);
- mutex_t lock;
+ pthread_mutex_t lock;
size_t size;
};
@@ -69,7 +69,7 @@
map->hash = hash;
map->equals = equals;
- mutex_init(&map->lock);
+ pthread_mutex_init(&map->lock, nullptr);
return map;
}
@@ -129,11 +129,11 @@
}
void hashmapLock(Hashmap* map) {
- mutex_lock(&map->lock);
+ pthread_mutex_lock(&map->lock);
}
void hashmapUnlock(Hashmap* map) {
- mutex_unlock(&map->lock);
+ pthread_mutex_unlock(&map->lock);
}
void hashmapFree(Hashmap* map) {
@@ -147,7 +147,7 @@
}
}
free(map->buckets);
- mutex_destroy(&map->lock);
+ pthread_mutex_destroy(&map->lock);
free(map);
}
diff --git a/liblog/include/log/log_read.h b/liblog/include/log/log_read.h
index d118563..93b9d4e 100644
--- a/liblog/include/log/log_read.h
+++ b/liblog/include/log/log_read.h
@@ -184,7 +184,7 @@
hdr_size = sizeof(entry_v1);
}
if ((hdr_size < sizeof(entry_v1)) || (hdr_size > sizeof(entry))) {
- return NULL;
+ return nullptr;
}
return reinterpret_cast<char*>(buf) + hdr_size;
}
diff --git a/liblog/include/private/android_logger.h b/liblog/include/private/android_logger.h
index 965de37..b927b46 100644
--- a/liblog/include/private/android_logger.h
+++ b/liblog/include/private/android_logger.h
@@ -173,7 +173,7 @@
#if defined(_USING_LIBCXX)
operator std::string() {
if (ret) return std::string("");
- const char* cp = NULL;
+ const char* cp = nullptr;
ssize_t len = android_log_write_list_buffer(ctx, &cp);
if (len < 0) ret = len;
if (!cp || (len <= 0)) return std::string("");
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 915cddb..2c00456 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -204,49 +204,19 @@
uint64_t offset = ehdr.e_phoff;
for (size_t i = 0; i < ehdr.e_phnum; i++, offset += ehdr.e_phentsize) {
PhdrType phdr;
- if (!memory_->ReadField(offset, &phdr, &phdr.p_type, sizeof(phdr.p_type))) {
+ if (!memory_->ReadFully(offset, &phdr, sizeof(phdr))) {
last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address =
- offset + reinterpret_cast<uintptr_t>(&phdr.p_type) - reinterpret_cast<uintptr_t>(&phdr);
+ last_error_.address = offset;
return false;
}
- if (HandleType(offset, phdr.p_type)) {
- continue;
- }
-
switch (phdr.p_type) {
case PT_LOAD:
{
- // Get the flags first, if this isn't an executable header, ignore it.
- if (!memory_->ReadField(offset, &phdr, &phdr.p_flags, sizeof(phdr.p_flags))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_flags) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
if ((phdr.p_flags & PF_X) == 0) {
continue;
}
- if (!memory_->ReadField(offset, &phdr, &phdr.p_vaddr, sizeof(phdr.p_vaddr))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_vaddr) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
- if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_offset) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
- if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_memsz) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
pt_loads_[phdr.p_offset] = LoadInfo{phdr.p_offset, phdr.p_vaddr,
static_cast<size_t>(phdr.p_memsz)};
if (phdr.p_offset == 0) {
@@ -256,46 +226,20 @@
}
case PT_GNU_EH_FRAME:
- if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_offset) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
// This is really the pointer to the .eh_frame_hdr section.
eh_frame_hdr_offset_ = phdr.p_offset;
- if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_memsz) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
eh_frame_hdr_size_ = phdr.p_memsz;
break;
case PT_DYNAMIC:
- if (!memory_->ReadField(offset, &phdr, &phdr.p_offset, sizeof(phdr.p_offset))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_offset) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
dynamic_offset_ = phdr.p_offset;
- if (!memory_->ReadField(offset, &phdr, &phdr.p_vaddr, sizeof(phdr.p_vaddr))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_vaddr) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
dynamic_vaddr_ = phdr.p_vaddr;
- if (!memory_->ReadField(offset, &phdr, &phdr.p_memsz, sizeof(phdr.p_memsz))) {
- last_error_.code = ERROR_MEMORY_INVALID;
- last_error_.address = offset + reinterpret_cast<uintptr_t>(&phdr.p_memsz) -
- reinterpret_cast<uintptr_t>(&phdr);
- return false;
- }
dynamic_size_ = phdr.p_memsz;
break;
+
+ default:
+ HandleUnknownType(phdr.p_type, phdr.p_offset, phdr.p_filesz);
+ break;
}
}
return true;
@@ -313,8 +257,7 @@
ShdrType shdr;
if (ehdr.e_shstrndx < ehdr.e_shnum) {
uint64_t sh_offset = offset + ehdr.e_shstrndx * ehdr.e_shentsize;
- if (memory_->ReadField(sh_offset, &shdr, &shdr.sh_offset, sizeof(shdr.sh_offset)) &&
- memory_->ReadField(sh_offset, &shdr, &shdr.sh_size, sizeof(shdr.sh_size))) {
+ if (memory_->ReadFully(sh_offset, &shdr, sizeof(shdr))) {
sec_offset = shdr.sh_offset;
sec_size = shdr.sh_size;
}
diff --git a/libunwindstack/ElfInterfaceArm.cpp b/libunwindstack/ElfInterfaceArm.cpp
index a3244e8..3dd5d54 100644
--- a/libunwindstack/ElfInterfaceArm.cpp
+++ b/libunwindstack/ElfInterfaceArm.cpp
@@ -87,23 +87,17 @@
#define PT_ARM_EXIDX 0x70000001
#endif
-bool ElfInterfaceArm::HandleType(uint64_t offset, uint32_t type) {
+void ElfInterfaceArm::HandleUnknownType(uint32_t type, uint64_t ph_offset, uint64_t ph_filesz) {
if (type != PT_ARM_EXIDX) {
- return false;
- }
-
- Elf32_Phdr phdr;
- if (!memory_->ReadFully(offset, &phdr, sizeof(phdr))) {
- return true;
+ return;
}
// The offset already takes into account the load bias.
- start_offset_ = phdr.p_offset;
+ start_offset_ = ph_offset;
// Always use filesz instead of memsz. In most cases they are the same,
// but some shared libraries wind up setting one correctly and not the other.
- total_entries_ = phdr.p_filesz / 8;
- return true;
+ total_entries_ = ph_filesz / 8;
}
bool ElfInterfaceArm::Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) {
diff --git a/libunwindstack/ElfInterfaceArm.h b/libunwindstack/ElfInterfaceArm.h
index 3bee9cf..4c3a0c3 100644
--- a/libunwindstack/ElfInterfaceArm.h
+++ b/libunwindstack/ElfInterfaceArm.h
@@ -70,7 +70,7 @@
bool FindEntry(uint32_t pc, uint64_t* entry_offset);
- bool HandleType(uint64_t offset, uint32_t type) override;
+ void HandleUnknownType(uint32_t type, uint64_t ph_offset, uint64_t ph_filesz) override;
bool Step(uint64_t pc, Regs* regs, Memory* process_memory, bool* finished) override;
diff --git a/libunwindstack/include/unwindstack/ElfInterface.h b/libunwindstack/include/unwindstack/ElfInterface.h
index 0c588da..5c1210d 100644
--- a/libunwindstack/include/unwindstack/ElfInterface.h
+++ b/libunwindstack/include/unwindstack/ElfInterface.h
@@ -118,7 +118,7 @@
template <typename SymType>
bool GetGlobalVariableWithTemplate(const std::string& name, uint64_t* memory_address);
- virtual bool HandleType(uint64_t, uint32_t) { return false; }
+ virtual void HandleUnknownType(uint32_t, uint64_t, uint64_t) {}
template <typename EhdrType>
static void GetMaxSizeWithTemplate(Memory* memory, uint64_t* size);
diff --git a/libunwindstack/include/unwindstack/Memory.h b/libunwindstack/include/unwindstack/Memory.h
index c0c07f4..dee5e98 100644
--- a/libunwindstack/include/unwindstack/Memory.h
+++ b/libunwindstack/include/unwindstack/Memory.h
@@ -41,18 +41,6 @@
bool ReadFully(uint64_t addr, void* dst, size_t size);
- inline bool ReadField(uint64_t addr, void* start, void* field, size_t size) {
- if (reinterpret_cast<uintptr_t>(field) < reinterpret_cast<uintptr_t>(start)) {
- return false;
- }
- uint64_t offset = reinterpret_cast<uintptr_t>(field) - reinterpret_cast<uintptr_t>(start);
- if (__builtin_add_overflow(addr, offset, &offset)) {
- return false;
- }
- // The read will check if offset + size overflows.
- return ReadFully(offset, field, size);
- }
-
inline bool Read32(uint64_t addr, uint32_t* dst) {
return ReadFully(addr, dst, sizeof(uint32_t));
}
diff --git a/libunwindstack/tests/ElfInterfaceArmTest.cpp b/libunwindstack/tests/ElfInterfaceArmTest.cpp
index a8bb4aa..43c6a97 100644
--- a/libunwindstack/tests/ElfInterfaceArmTest.cpp
+++ b/libunwindstack/tests/ElfInterfaceArmTest.cpp
@@ -242,44 +242,21 @@
ASSERT_EQ(0xa020U, entries[4]);
}
-TEST_F(ElfInterfaceArmTest, HandleType_not_arm_exidx) {
+TEST_F(ElfInterfaceArmTest, HandleUnknownType_arm_exidx) {
ElfInterfaceArmFake interface(&memory_);
- ASSERT_FALSE(interface.HandleType(0x1000, PT_NULL));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_LOAD));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_DYNAMIC));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_INTERP));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_NOTE));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_SHLIB));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_PHDR));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_TLS));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_LOOS));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_HIOS));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_LOPROC));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_HIPROC));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_GNU_EH_FRAME));
- ASSERT_FALSE(interface.HandleType(0x1000, PT_GNU_STACK));
-}
-
-TEST_F(ElfInterfaceArmTest, HandleType_arm_exidx) {
- ElfInterfaceArmFake interface(&memory_);
-
- Elf32_Phdr phdr = {};
interface.FakeSetStartOffset(0x1000);
interface.FakeSetTotalEntries(100);
- phdr.p_offset = 0x2000;
- phdr.p_filesz = 0xa00;
- // Verify that if reads fail, we don't set the values but still get true.
- ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001));
+ // Verify that if the type is not the one we want, we don't set the values.
+ interface.HandleUnknownType(0x70000000, 0x2000, 320);
ASSERT_EQ(0x1000U, interface.start_offset());
ASSERT_EQ(100U, interface.total_entries());
// Everything is correct and present.
- memory_.SetMemory(0x1000, &phdr, sizeof(phdr));
- ASSERT_TRUE(interface.HandleType(0x1000, 0x70000001));
+ interface.HandleUnknownType(0x70000001, 0x2000, 320);
ASSERT_EQ(0x2000U, interface.start_offset());
- ASSERT_EQ(320U, interface.total_entries());
+ ASSERT_EQ(40U, interface.total_entries());
}
TEST_F(ElfInterfaceArmTest, StepExidx) {
diff --git a/libunwindstack/tests/MemoryTest.cpp b/libunwindstack/tests/MemoryTest.cpp
index 4a9ed9f..3655984 100644
--- a/libunwindstack/tests/MemoryTest.cpp
+++ b/libunwindstack/tests/MemoryTest.cpp
@@ -51,40 +51,6 @@
uint64_t four;
};
-TEST(MemoryTest, read_field) {
- MemoryFakeAlwaysReadZero memory;
-
- FakeStruct data;
- memset(&data, 0xff, sizeof(data));
- ASSERT_TRUE(memory.ReadField(0, &data, &data.one, sizeof(data.one)));
- ASSERT_EQ(0, data.one);
-
- memset(&data, 0xff, sizeof(data));
- ASSERT_TRUE(memory.ReadField(0, &data, &data.two, sizeof(data.two)));
- ASSERT_FALSE(data.two);
-
- memset(&data, 0xff, sizeof(data));
- ASSERT_TRUE(memory.ReadField(0, &data, &data.three, sizeof(data.three)));
- ASSERT_EQ(0U, data.three);
-
- memset(&data, 0xff, sizeof(data));
- ASSERT_TRUE(memory.ReadField(0, &data, &data.four, sizeof(data.four)));
- ASSERT_EQ(0U, data.four);
-}
-
-TEST(MemoryTest, read_field_fails) {
- MemoryFakeAlwaysReadZero memory;
-
- FakeStruct data;
- memset(&data, 0xff, sizeof(data));
-
- ASSERT_FALSE(memory.ReadField(UINT64_MAX, &data, &data.three, sizeof(data.three)));
-
- // Field and start reversed, should fail.
- ASSERT_FALSE(memory.ReadField(100, &data.two, &data, sizeof(data.two)));
- ASSERT_FALSE(memory.ReadField(0, &data.two, &data, sizeof(data.two)));
-}
-
TEST(MemoryTest, read_string) {
std::string name("string_in_memory");
diff --git a/libutils/include/utils/AndroidThreads.h b/libutils/include/utils/AndroidThreads.h
index dab888d..a8d7851 100644
--- a/libutils/include/utils/AndroidThreads.h
+++ b/libutils/include/utils/AndroidThreads.h
@@ -106,7 +106,7 @@
const char* threadName = "android:unnamed_thread",
int32_t threadPriority = PRIORITY_DEFAULT,
size_t threadStackSize = 0,
- thread_id_t *threadId = 0)
+ thread_id_t *threadId = nullptr)
{
return androidCreateThreadEtc(entryFunction, userData, threadName,
threadPriority, threadStackSize, threadId) ? true : false;
diff --git a/libutils/include/utils/CallStack.h b/libutils/include/utils/CallStack.h
index 9622142..0c1b875 100644
--- a/libutils/include/utils/CallStack.h
+++ b/libutils/include/utils/CallStack.h
@@ -49,13 +49,13 @@
// Dump a stack trace to the log using the supplied logtag.
void log(const char* logtag,
android_LogPriority priority = ANDROID_LOG_DEBUG,
- const char* prefix = 0) const;
+ const char* prefix = nullptr) const;
// Dump a stack trace to the specified file descriptor.
- void dump(int fd, int indent = 0, const char* prefix = 0) const;
+ void dump(int fd, int indent = 0, const char* prefix = nullptr) const;
// Return a string (possibly very long) containing the complete stack trace.
- String8 toString(const char* prefix = 0) const;
+ String8 toString(const char* prefix = nullptr) const;
// Dump a serialized representation of the stack trace to the specified printer.
void print(Printer& printer) const;
diff --git a/libutils/include/utils/Looper.h b/libutils/include/utils/Looper.h
index a62e67f..4509d75 100644
--- a/libutils/include/utils/Looper.h
+++ b/libutils/include/utils/Looper.h
@@ -262,7 +262,7 @@
*/
int pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData);
inline int pollOnce(int timeoutMillis) {
- return pollOnce(timeoutMillis, NULL, NULL, NULL);
+ return pollOnce(timeoutMillis, nullptr, nullptr, nullptr);
}
/**
@@ -272,7 +272,7 @@
*/
int pollAll(int timeoutMillis, int* outFd, int* outEvents, void** outData);
inline int pollAll(int timeoutMillis) {
- return pollAll(timeoutMillis, NULL, NULL, NULL);
+ return pollAll(timeoutMillis, nullptr, nullptr, nullptr);
}
/**
diff --git a/libutils/include/utils/Mutex.h b/libutils/include/utils/Mutex.h
index 1228df4..29c2e8c 100644
--- a/libutils/include/utils/Mutex.h
+++ b/libutils/include/utils/Mutex.h
@@ -100,7 +100,7 @@
Mutex();
explicit Mutex(const char* name);
- explicit Mutex(int type, const char* name = NULL);
+ explicit Mutex(int type, const char* name = nullptr);
~Mutex();
// lock or unlock the mutex
@@ -160,10 +160,10 @@
#if !defined(_WIN32)
inline Mutex::Mutex() {
- pthread_mutex_init(&mMutex, NULL);
+ pthread_mutex_init(&mMutex, nullptr);
}
inline Mutex::Mutex(__attribute__((unused)) const char* name) {
- pthread_mutex_init(&mMutex, NULL);
+ pthread_mutex_init(&mMutex, nullptr);
}
inline Mutex::Mutex(int type, __attribute__((unused)) const char* name) {
if (type == SHARED) {
@@ -173,7 +173,7 @@
pthread_mutex_init(&mMutex, &attr);
pthread_mutexattr_destroy(&attr);
} else {
- pthread_mutex_init(&mMutex, NULL);
+ pthread_mutex_init(&mMutex, nullptr);
}
}
inline Mutex::~Mutex() {
diff --git a/libutils/include/utils/RWLock.h b/libutils/include/utils/RWLock.h
index 7d43e69..64e370e 100644
--- a/libutils/include/utils/RWLock.h
+++ b/libutils/include/utils/RWLock.h
@@ -48,7 +48,7 @@
RWLock();
explicit RWLock(const char* name);
- explicit RWLock(int type, const char* name = NULL);
+ explicit RWLock(int type, const char* name = nullptr);
~RWLock();
status_t readLock();
@@ -82,10 +82,10 @@
};
inline RWLock::RWLock() {
- pthread_rwlock_init(&mRWLock, NULL);
+ pthread_rwlock_init(&mRWLock, nullptr);
}
inline RWLock::RWLock(__attribute__((unused)) const char* name) {
- pthread_rwlock_init(&mRWLock, NULL);
+ pthread_rwlock_init(&mRWLock, nullptr);
}
inline RWLock::RWLock(int type, __attribute__((unused)) const char* name) {
if (type == SHARED) {
@@ -95,7 +95,7 @@
pthread_rwlock_init(&mRWLock, &attr);
pthread_rwlockattr_destroy(&attr);
} else {
- pthread_rwlock_init(&mRWLock, NULL);
+ pthread_rwlock_init(&mRWLock, nullptr);
}
}
inline RWLock::~RWLock() {
diff --git a/libutils/include/utils/RefBase.h b/libutils/include/utils/RefBase.h
index e817ee4..13b6a2b 100644
--- a/libutils/include/utils/RefBase.h
+++ b/libutils/include/utils/RefBase.h
@@ -354,7 +354,7 @@
public:
typedef typename RefBase::weakref_type weakref_type;
- inline wp() : m_ptr(0) { }
+ inline wp() : m_ptr(nullptr) { }
wp(T* other); // NOLINT(implicit)
wp(const wp<T>& other);
@@ -505,7 +505,7 @@
wp<T>& wp<T>::operator = (T* other)
{
weakref_type* newRefs =
- other ? other->createWeak(this) : 0;
+ other ? other->createWeak(this) : nullptr;
if (m_ptr) m_refs->decWeak(this);
m_ptr = other;
m_refs = newRefs;
@@ -528,7 +528,7 @@
wp<T>& wp<T>::operator = (const sp<T>& other)
{
weakref_type* newRefs =
- other != NULL ? other->createWeak(this) : 0;
+ other != nullptr ? other->createWeak(this) : nullptr;
T* otherPtr(other.m_ptr);
if (m_ptr) m_refs->decWeak(this);
m_ptr = otherPtr;
diff --git a/libutils/include/utils/Singleton.h b/libutils/include/utils/Singleton.h
index 2dd5a47..44d8ad7 100644
--- a/libutils/include/utils/Singleton.h
+++ b/libutils/include/utils/Singleton.h
@@ -51,7 +51,7 @@
static TYPE& getInstance() {
Mutex::Autolock _l(sLock);
TYPE* instance = sInstance;
- if (instance == 0) {
+ if (instance == nullptr) {
instance = new TYPE();
sInstance = instance;
}
@@ -60,7 +60,7 @@
static bool hasInstance() {
Mutex::Autolock _l(sLock);
- return sInstance != 0;
+ return sInstance != nullptr;
}
protected:
@@ -90,7 +90,7 @@
#define ANDROID_SINGLETON_STATIC_INSTANCE(TYPE) \
template<> ::android::Mutex \
(::android::Singleton< TYPE >::sLock)(::android::Mutex::PRIVATE); \
- template<> TYPE* ::android::Singleton< TYPE >::sInstance(0); /* NOLINT */ \
+ template<> TYPE* ::android::Singleton< TYPE >::sInstance(nullptr); /* NOLINT */ \
template class ::android::Singleton< TYPE >;
diff --git a/libutils/include/utils/String8.h b/libutils/include/utils/String8.h
index 94ac32f..c8f584e 100644
--- a/libutils/include/utils/String8.h
+++ b/libutils/include/utils/String8.h
@@ -187,7 +187,7 @@
* "/tmp" --> "tmp" (remain = "")
* "bar.c" --> "bar.c" (remain = "")
*/
- String8 walkPath(String8* outRemains = NULL) const;
+ String8 walkPath(String8* outRemains = nullptr) const;
/*
* Return the filename extension. This is the last '.' and any number
diff --git a/libutils/include/utils/StrongPointer.h b/libutils/include/utils/StrongPointer.h
index 9cd278f1..360fce5 100644
--- a/libutils/include/utils/StrongPointer.h
+++ b/libutils/include/utils/StrongPointer.h
@@ -52,7 +52,7 @@
template<typename T>
class sp {
public:
- inline sp() : m_ptr(0) { }
+ inline sp() : m_ptr(nullptr) { }
sp(T* other); // NOLINT(implicit)
sp(const sp<T>& other);
@@ -230,7 +230,7 @@
void sp<T>::clear() {
if (m_ptr) {
m_ptr->decStrong(this);
- m_ptr = 0;
+ m_ptr = nullptr;
}
}
diff --git a/libutils/include/utils/VectorImpl.h b/libutils/include/utils/VectorImpl.h
index 55d5d98..41b9f33 100644
--- a/libutils/include/utils/VectorImpl.h
+++ b/libutils/include/utils/VectorImpl.h
@@ -157,7 +157,7 @@
virtual int do_compare(const void* lhs, const void* rhs) const = 0;
private:
- ssize_t _indexOrderOf(const void* item, size_t* order = 0) const;
+ ssize_t _indexOrderOf(const void* item, size_t* order = nullptr) const;
// these are made private, because they can't be used on a SortedVector
// (they don't have an implementation either)
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index 06c0ab5..7a843d8 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -288,9 +288,9 @@
uid = AID_ROOT;
}
- const char* name = NULL;
- const char* format = NULL;
- const char* id = NULL;
+ const char* name = nullptr;
+ const char* format = nullptr;
+ const char* id = nullptr;
for (int i = 1; i < argc; ++i) {
static const char _name[] = "name=";
if (!strncmp(argv[i], _name, strlen(_name))) {
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp
old mode 100755
new mode 100644
index 70ecbe0..658e079
--- a/logd/FlushCommand.cpp
+++ b/logd/FlushCommand.cpp
@@ -36,7 +36,7 @@
// reference counts are used to ensure that individual
// LogTimeEntry lifetime is managed when not protected.
void FlushCommand::runSocketCommand(SocketClient* client) {
- LogTimeEntry* entry = NULL;
+ LogTimeEntry* entry = nullptr;
LastLogTimes& times = mReader.logbuf().mTimes;
LogTimeEntry::wrlock();
diff --git a/logd/FlushCommand.h b/logd/FlushCommand.h
old mode 100755
new mode 100644
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
old mode 100755
new mode 100644
index 27cd9a8..4ea7877
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -171,13 +171,13 @@
}
int LogAudit::logPrint(const char* fmt, ...) {
- if (fmt == NULL) {
+ if (fmt == nullptr) {
return -EINVAL;
}
va_list args;
- char* str = NULL;
+ char* str = nullptr;
va_start(args, fmt);
int rc = vasprintf(&str, fmt, args);
va_end(args);
@@ -228,7 +228,7 @@
static char* last_str;
static bool last_info;
- if (last_str != NULL) {
+ if (last_str != nullptr) {
static const char avc[] = "): avc: ";
char* avcl = strstr(last_str, avc);
bool skip = false;
@@ -265,10 +265,10 @@
writev(fdDmesg, iov, arraysize(iov));
free(last_str);
- last_str = NULL;
+ last_str = nullptr;
}
}
- if (last_str == NULL) {
+ if (last_str == nullptr) {
count = 0;
last_str = strdup(str);
last_info = info;
@@ -357,7 +357,7 @@
static const char comm_str[] = " comm=\"";
const char* comm = strstr(str, comm_str);
const char* estr = str + strlen(str);
- const char* commfree = NULL;
+ const char* commfree = nullptr;
if (comm) {
estr = comm;
comm += sizeof(comm_str) - 1;
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index f20ac45..2d627b9 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -91,7 +91,7 @@
// caller must own and free character string
char* android::tidToName(pid_t tid) {
- char* retval = NULL;
+ char* retval = nullptr;
char buffer[256];
snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid);
int fd = open(buffer, O_RDONLY);
@@ -114,7 +114,7 @@
char* name = android::pidToName(tid);
if (!retval) {
retval = name;
- name = NULL;
+ name = nullptr;
}
// check if comm is truncated, see if cmdline has full representation
@@ -162,15 +162,15 @@
if (!strncmp(name + 1, commName + 1, len)) {
if (commName[len + 1] == '\0') {
free(const_cast<char*>(commName));
- commName = NULL;
+ commName = nullptr;
} else {
free(const_cast<char*>(name));
- name = NULL;
+ name = nullptr;
}
}
}
if (name) {
- char* buf = NULL;
+ char* buf = nullptr;
asprintf(&buf, "(%s)", name);
if (buf) {
free(const_cast<char*>(name));
@@ -178,7 +178,7 @@
}
}
if (commName) {
- char* buf = NULL;
+ char* buf = nullptr;
asprintf(&buf, " %s", commName);
if (buf) {
free(const_cast<char*>(commName));
@@ -187,7 +187,7 @@
}
// identical to below to calculate the buffer size required
const char* type = lastSame ? "identical" : "expire";
- size_t len = snprintf(NULL, 0, format_uid, mUid, name ? name : "",
+ size_t len = snprintf(nullptr, 0, format_uid, mUid, name ? name : "",
commName ? commName : "", type, getDropped(),
(getDropped() > 1) ? "s" : "");
@@ -247,7 +247,7 @@
iovec[0].iov_base = &entry;
iovec[0].iov_len = entry.hdr_size;
- char* buffer = NULL;
+ char* buffer = nullptr;
if (mDropped) {
entry.len = populateDroppedMessage(buffer, parent, lastSame);
diff --git a/logd/LogCommand.cpp b/logd/LogCommand.cpp
index 6d7c0a5..8bff9da 100644
--- a/logd/LogCommand.cpp
+++ b/logd/LogCommand.cpp
@@ -44,9 +44,9 @@
char* ptr;
static const char ws[] = " \n";
- for (buf = strtok_r(buf, ws, &ptr); buf; buf = strtok_r(NULL, ws, &ptr)) {
+ for (buf = strtok_r(buf, ws, &ptr); buf; buf = strtok_r(nullptr, ws, &ptr)) {
errno = 0;
- gid_t Gid = strtol(buf, NULL, 10);
+ gid_t Gid = strtol(buf, nullptr, 10);
if (errno != 0) {
return false;
}
@@ -98,7 +98,7 @@
continue;
}
- char* line = NULL;
+ char* line = nullptr;
size_t len = 0;
while (getline(&line, &len, file) > 0) {
static const char groups_string[] = "Groups:\t";
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
old mode 100755
new mode 100644
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
old mode 100755
new mode 100644
index fc51dcf..e568ddc
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -50,7 +50,7 @@
alignas(4) char control[CMSG_SPACE(sizeof(struct ucred))];
struct msghdr hdr = {
- NULL, 0, &iov, 1, control, sizeof(control), 0,
+ nullptr, 0, &iov, 1, control, sizeof(control), 0,
};
int socket = cli->getSocket();
@@ -66,10 +66,10 @@
buffer[n] = 0;
- struct ucred* cred = NULL;
+ struct ucred* cred = nullptr;
struct cmsghdr* cmsg = CMSG_FIRSTHDR(&hdr);
- while (cmsg != NULL) {
+ while (cmsg != nullptr) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS) {
cred = (struct ucred*)CMSG_DATA(cmsg);
@@ -79,7 +79,7 @@
}
struct ucred fake_cred;
- if (cred == NULL) {
+ if (cred == nullptr) {
cred = &fake_cred;
cred->pid = 0;
cred->uid = DEFAULT_OVERFLOWUID;
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
old mode 100755
new mode 100644
diff --git a/logd/LogReader.h b/logd/LogReader.h
old mode 100755
new mode 100644
diff --git a/logd/LogStatistics.cpp b/logd/LogStatistics.cpp
index af59ddc..cefacf7 100644
--- a/logd/LogStatistics.cpp
+++ b/logd/LogStatistics.cpp
@@ -56,7 +56,7 @@
// caller must own and free character string
char* pidToName(pid_t pid) {
- char* retval = NULL;
+ char* retval = nullptr;
if (pid == 0) { // special case from auditd/klogd for kernel
retval = strdup("logd");
} else {
@@ -286,7 +286,7 @@
name = strdup(nameTmp);
} else if (fastcmp<strcmp>(name, nameTmp)) {
free(const_cast<char*>(name));
- name = NULL;
+ name = nullptr;
break;
}
}
@@ -872,7 +872,7 @@
pidTable_t& writablePidTable = const_cast<pidTable_t&>(pidTable);
const char* name = writablePidTable.add(pid)->second.getName();
if (!name) {
- return NULL;
+ return nullptr;
}
return strdup(name);
}
diff --git a/logd/LogTags.cpp b/logd/LogTags.cpp
index ff7e762..1ab9dd1 100644
--- a/logd/LogTags.cpp
+++ b/logd/LogTags.cpp
@@ -91,7 +91,7 @@
fd = TEMP_FAILURE_RETRY(open(
filename, O_WRONLY | O_TRUNC | O_CLOEXEC | O_NOFOLLOW | O_BINARY));
if (fd >= 0) {
- time_t now = time(NULL);
+ time_t now = time(nullptr);
struct tm tm;
localtime_r(&now, &tm);
char timebuf[20];
@@ -208,7 +208,7 @@
} else if (lineStart) {
if (*cp == '#') {
/* comment; just scan to end */
- lineStart = NULL;
+ lineStart = nullptr;
} else if (isdigit(*cp)) {
unsigned long Tag = strtoul(cp, &cp, 10);
if (warn && (Tag > emptyTag)) {
@@ -235,7 +235,7 @@
if (hasAlpha &&
((cp >= endp) || (*cp == '#') || isspace(*cp))) {
if (Tag > emptyTag) {
- if (*cp != '\n') lineStart = NULL;
+ if (*cp != '\n') lineStart = nullptr;
continue;
}
while ((cp < endp) && (*cp != '\n') && isspace(*cp))
@@ -245,14 +245,14 @@
while ((cp < endp) && (*cp != '\n')) {
if (*cp == '#') {
uid = sniffUid(cp, endp);
- lineStart = NULL;
+ lineStart = nullptr;
break;
}
++cp;
}
while ((cp > format) && isspace(cp[-1])) {
--cp;
- lineStart = NULL;
+ lineStart = nullptr;
}
std::string Format(format, cp - format);
@@ -263,7 +263,7 @@
android::prdebug("tag name invalid %.*s",
(int)(cp - name + 1), name);
}
- lineStart = NULL;
+ lineStart = nullptr;
}
} else if (!isspace(*cp)) {
break;
@@ -364,7 +364,7 @@
android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));
it = tag2name.find(tag);
- if ((it == tag2name.end()) || (it->second.length() == 0)) return NULL;
+ if ((it == tag2name.end()) || (it->second.length() == 0)) return nullptr;
return it->second.c_str();
}
@@ -383,7 +383,7 @@
const char* android::tagToName(uint32_t tag) {
LogTags* me = logtags;
- if (!me) return NULL;
+ if (!me) return nullptr;
me->WritePmsgEventLogTags(tag);
return me->tagToName(tag);
}
@@ -412,7 +412,7 @@
android::RWLock::AutoRLock readLock(const_cast<android::RWLock&>(rwlock));
iform = tag2format.find(tag);
- if (iform == tag2format.end()) return NULL;
+ if (iform == tag2format.end()) return nullptr;
return iform->second.c_str();
}
@@ -441,7 +441,7 @@
bool& unique) {
key2tag_const_iterator ik;
- bool write = format != NULL;
+ bool write = format != nullptr;
unique = write;
if (!write) {
@@ -679,7 +679,7 @@
// are in readonly mode.
uint32_t LogTags::nameToTag(uid_t uid, const char* name, const char* format) {
std::string Name = std::string(name);
- bool write = format != NULL;
+ bool write = format != nullptr;
bool updateUid = uid != AID_ROOT;
bool updateFormat = format && *format;
bool unique;
@@ -848,7 +848,7 @@
if (!list) {
// switch to read entry only if format == "*"
- if (format && (format[0] == '*') && !format[1]) format = NULL;
+ if (format && (format[0] == '*') && !format[1]) format = nullptr;
// WAI: for null format, only works for a single entry, we can have
// multiple entries, one for each format, so we find first entry
diff --git a/logd/LogTags.h b/logd/LogTags.h
index 203318d..e4d165a 100644
--- a/logd/LogTags.h
+++ b/logd/LogTags.h
@@ -87,14 +87,14 @@
bool RebuildFileEventLogTags(const char* filename, bool warn = true);
void AddEventLogTags(uint32_t tag, uid_t uid, const std::string& Name,
- const std::string& Format, const char* source = NULL,
+ const std::string& Format, const char* source = nullptr,
bool warn = false);
void WriteDynamicEventLogTags(uint32_t tag, uid_t uid);
void WriteDebugEventLogTags(uint32_t tag, uid_t uid);
// push tag details to persistent storage
void WritePersistEventLogTags(uint32_t tag, uid_t uid = AID_ROOT,
- const char* source = NULL);
+ const char* source = nullptr);
static const uint32_t emptyTag = uint32_t(-1);
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
old mode 100755
new mode 100644
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
old mode 100755
new mode 100644
diff --git a/logd/LogWhiteBlackList.cpp b/logd/LogWhiteBlackList.cpp
index 4b8b080..9d762dc 100644
--- a/logd/LogWhiteBlackList.cpp
+++ b/logd/LogWhiteBlackList.cpp
@@ -51,7 +51,7 @@
}
PruneList::PruneList() {
- init(NULL);
+ init(nullptr);
}
PruneList::~PruneList() {
@@ -79,7 +79,7 @@
// default here means take ro.logd.filter, persist.logd.filter then
// internal default in that order.
if (str && !strcmp(str, _default)) {
- str = NULL;
+ str = nullptr;
}
static const char _disable[] = "disable";
if (str && !strcmp(str, _disable)) {