adb: fdevent: move run queue to fdevent_context.
am: 95eef6b097
Change-Id: I131984a407220281364c016f832aef45e0f9a457
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 6f6481f..f6ef906 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -82,3 +82,9 @@
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sbin/charger)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/sbin)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/sbin)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product_services)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/product_services.img)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/product_services)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/product_services)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/product_services)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/debug_ramdisk/product_services)
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 24d4292..d5e7be1 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -337,9 +337,12 @@
case ADB_AUTH_SIGNATURE: {
// TODO: Switch to string_view.
std::string signature(p->payload.begin(), p->payload.end());
- if (adbd_auth_verify(t->token, sizeof(t->token), signature)) {
+ std::string auth_key;
+ if (adbd_auth_verify(t->token, sizeof(t->token), signature, &auth_key)) {
adbd_auth_verified(t);
t->failed_auth_attempts = 0;
+ t->auth_key = auth_key;
+ adbd_notify_framework_connected_key(t);
} else {
if (t->failed_auth_attempts++ > 256) std::this_thread::sleep_for(1s);
send_auth_request(t);
@@ -348,7 +351,8 @@
}
case ADB_AUTH_RSAPUBLICKEY:
- adbd_auth_confirm_key(p->payload.data(), p->msg.data_length, t);
+ t->auth_key = std::string(p->payload.data());
+ adbd_auth_confirm_key(t);
break;
#endif
default:
diff --git a/adb/adb.h b/adb/adb.h
index 352b2fe..c6cb06a 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -33,6 +33,7 @@
constexpr size_t MAX_PAYLOAD_V1 = 4 * 1024;
constexpr size_t MAX_PAYLOAD = 1024 * 1024;
+constexpr size_t MAX_FRAMEWORK_PAYLOAD = 64 * 1024;
constexpr size_t LINUX_MAX_SOCKET_SIZE = 4194304;
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 2fc8478..2be9a76 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -50,8 +50,10 @@
void adbd_auth_verified(atransport *t);
void adbd_cloexec_auth_socket();
-bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig);
-void adbd_auth_confirm_key(const char* data, size_t len, atransport* t);
+bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig,
+ std::string* auth_key);
+void adbd_auth_confirm_key(atransport* t);
+void adbd_notify_framework_connected_key(atransport* t);
void send_auth_request(atransport *t);
diff --git a/adb/client/commandline.cpp b/adb/client/commandline.cpp
index 7211f72..11a3dfd 100644
--- a/adb/client/commandline.cpp
+++ b/adb/client/commandline.cpp
@@ -128,7 +128,7 @@
" pull [-a] REMOTE... LOCAL\n"
" copy files/dirs from device\n"
" -a: preserve file timestamp and mode\n"
- " sync [all|data|odm|oem|product_services|product|system|vendor]\n"
+ " sync [all|data|odm|oem|product|system|system_ext|vendor]\n"
" sync a local build from $ANDROID_PRODUCT_OUT to the device (default all)\n"
" -l: list but don't copy\n"
"\n"
@@ -775,17 +775,16 @@
error_exit("abb is not supported by the device");
}
+ optind = 1; // argv[0] is always "abb", so set `optind` appropriately.
+
// Defaults.
constexpr char escape_char = '~'; // -e
constexpr bool use_shell_protocol = true;
constexpr auto shell_type_arg = kShellServiceArgRaw;
constexpr bool empty_command = false;
- std::string service_string("abb:");
- for (auto i = optind; i < argc; ++i) {
- service_string.append(argv[i]);
- service_string.push_back(ABB_ARG_DELIMETER);
- }
+ std::vector<const char*> args(argv + optind, argv + argc);
+ std::string service_string = "abb:" + android::base::Join(args, ABB_ARG_DELIMETER);
D("abb -e 0x%x [%*.s]\n", escape_char, static_cast<int>(service_string.size()),
service_string.data());
@@ -1843,8 +1842,8 @@
}
if (src.empty()) src = "all";
- std::vector<std::string> partitions{"data", "odm", "oem", "product", "product_services",
- "system", "vendor"};
+ std::vector<std::string> partitions{"data", "odm", "oem", "product",
+ "system", "system_ext", "vendor"};
bool found = false;
for (const auto& partition : partitions) {
if (src == "all" || src == partition) {
diff --git a/adb/daemon/auth.cpp b/adb/daemon/auth.cpp
index 2b8f461..7a3a4f5 100644
--- a/adb/daemon/auth.cpp
+++ b/adb/daemon/auth.cpp
@@ -26,7 +26,9 @@
#include <resolv.h>
#include <stdio.h>
#include <string.h>
+#include <iomanip>
+#include <algorithm>
#include <memory>
#include <android-base/file.h>
@@ -38,22 +40,24 @@
static fdevent* listener_fde = nullptr;
static fdevent* framework_fde = nullptr;
-static int framework_fd = -1;
+static auto& framework_mutex = *new std::mutex();
+static int framework_fd GUARDED_BY(framework_mutex) = -1;
+static auto& connected_keys GUARDED_BY(framework_mutex) = *new std::vector<std::string>;
-static void usb_disconnected(void* unused, atransport* t);
-static struct adisconnect usb_disconnect = { usb_disconnected, nullptr};
-static atransport* usb_transport;
+static void adb_disconnected(void* unused, atransport* t);
+static struct adisconnect adb_disconnect = {adb_disconnected, nullptr};
+static atransport* adb_transport;
static bool needs_retry = false;
bool auth_required = true;
-bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig) {
+bool adbd_auth_verify(const char* token, size_t token_size, const std::string& sig,
+ std::string* auth_key) {
static constexpr const char* key_paths[] = { "/adb_keys", "/data/misc/adb/adb_keys", nullptr };
for (const auto& path : key_paths) {
if (access(path, R_OK) == 0) {
LOG(INFO) << "Loading keys from " << path;
-
std::string content;
if (!android::base::ReadFileToString(path, &content)) {
PLOG(ERROR) << "Couldn't read " << path;
@@ -61,6 +65,8 @@
}
for (const auto& line : android::base::Split(content, "\n")) {
+ if (line.empty()) continue;
+ *auth_key = line;
// TODO: do we really have to support both ' ' and '\t'?
char* sep = strpbrk(const_cast<char*>(line.c_str()), " \t");
if (sep) *sep = '\0';
@@ -88,9 +94,31 @@
}
}
}
+ auth_key->clear();
return false;
}
+static bool adbd_send_key_message_locked(std::string_view msg_type, std::string_view key)
+ REQUIRES(framework_mutex) {
+ if (framework_fd < 0) {
+ LOG(ERROR) << "Client not connected to send msg_type " << msg_type;
+ return false;
+ }
+ std::string msg = std::string(msg_type) + std::string(key);
+ int msg_len = msg.length();
+ if (msg_len >= static_cast<int>(MAX_FRAMEWORK_PAYLOAD)) {
+ LOG(ERROR) << "Key too long (" << msg_len << ")";
+ return false;
+ }
+
+ LOG(DEBUG) << "Sending '" << msg << "'";
+ if (!WriteFdExactly(framework_fd, msg.c_str(), msg_len)) {
+ PLOG(ERROR) << "Failed to write " << msg_type;
+ return false;
+ }
+ return true;
+}
+
static bool adbd_auth_generate_token(void* token, size_t token_size) {
FILE* fp = fopen("/dev/urandom", "re");
if (!fp) return false;
@@ -99,17 +127,28 @@
return okay;
}
-static void usb_disconnected(void* unused, atransport* t) {
- LOG(INFO) << "USB disconnect";
- usb_transport = nullptr;
+static void adb_disconnected(void* unused, atransport* t) {
+ LOG(INFO) << "ADB disconnect";
+ adb_transport = nullptr;
needs_retry = false;
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (framework_fd >= 0) {
+ adbd_send_key_message_locked("DC", t->auth_key);
+ }
+ connected_keys.erase(std::remove(connected_keys.begin(), connected_keys.end(), t->auth_key),
+ connected_keys.end());
+ }
}
static void framework_disconnected() {
LOG(INFO) << "Framework disconnect";
if (framework_fde) {
fdevent_destroy(framework_fde);
- framework_fd = -1;
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ framework_fd = -1;
+ }
}
}
@@ -120,41 +159,28 @@
if (ret <= 0) {
framework_disconnected();
} else if (ret == 2 && response[0] == 'O' && response[1] == 'K') {
- if (usb_transport) {
- adbd_auth_verified(usb_transport);
+ if (adb_transport) {
+ adbd_auth_verified(adb_transport);
}
}
}
}
-void adbd_auth_confirm_key(const char* key, size_t len, atransport* t) {
- if (!usb_transport) {
- usb_transport = t;
- t->AddDisconnect(&usb_disconnect);
+void adbd_auth_confirm_key(atransport* t) {
+ if (!adb_transport) {
+ adb_transport = t;
+ t->AddDisconnect(&adb_disconnect);
}
- if (framework_fd < 0) {
- LOG(ERROR) << "Client not connected";
- needs_retry = true;
- return;
- }
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (framework_fd < 0) {
+ LOG(ERROR) << "Client not connected";
+ needs_retry = true;
+ return;
+ }
- if (key[len - 1] != '\0') {
- LOG(ERROR) << "Key must be a null-terminated string";
- return;
- }
-
- char msg[MAX_PAYLOAD_V1];
- int msg_len = snprintf(msg, sizeof(msg), "PK%s", key);
- if (msg_len >= static_cast<int>(sizeof(msg))) {
- LOG(ERROR) << "Key too long (" << msg_len << ")";
- return;
- }
- LOG(DEBUG) << "Sending '" << msg << "'";
-
- if (unix_write(framework_fd, msg, msg_len) == -1) {
- PLOG(ERROR) << "Failed to write PK";
- return;
+ adbd_send_key_message_locked("PK", t->auth_key);
}
}
@@ -165,18 +191,46 @@
return;
}
- if (framework_fd >= 0) {
- LOG(WARNING) << "adb received framework auth socket connection again";
- framework_disconnected();
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (framework_fd >= 0) {
+ LOG(WARNING) << "adb received framework auth socket connection again";
+ framework_disconnected();
+ }
+
+ framework_fd = s;
+ framework_fde = fdevent_create(framework_fd, adbd_auth_event, nullptr);
+ fdevent_add(framework_fde, FDE_READ);
+
+ if (needs_retry) {
+ needs_retry = false;
+ send_auth_request(adb_transport);
+ }
+
+ // if a client connected before the framework was available notify the framework of the
+ // connected key now.
+ if (!connected_keys.empty()) {
+ for (const auto& key : connected_keys) {
+ adbd_send_key_message_locked("CK", key);
+ }
+ }
}
+}
- framework_fd = s;
- framework_fde = fdevent_create(framework_fd, adbd_auth_event, nullptr);
- fdevent_add(framework_fde, FDE_READ);
-
- if (needs_retry) {
- needs_retry = false;
- send_auth_request(usb_transport);
+void adbd_notify_framework_connected_key(atransport* t) {
+ if (!adb_transport) {
+ adb_transport = t;
+ t->AddDisconnect(&adb_disconnect);
+ }
+ {
+ std::lock_guard<std::mutex> lock(framework_mutex);
+ if (std::find(connected_keys.begin(), connected_keys.end(), t->auth_key) ==
+ connected_keys.end()) {
+ connected_keys.push_back(t->auth_key);
+ }
+ if (framework_fd >= 0) {
+ adbd_send_key_message_locked("CK", t->auth_key);
+ }
}
}
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index f4aa9fb..1abae87 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -509,16 +509,14 @@
}
if (id.direction == TransferDirection::READ) {
- if (!HandleRead(id, event.res)) {
- return;
- }
+ HandleRead(id, event.res);
} else {
HandleWrite(id);
}
}
}
- bool HandleRead(TransferId id, int64_t size) {
+ void HandleRead(TransferId id, int64_t size) {
uint64_t read_idx = id.id % kUsbReadQueueDepth;
IoBlock* block = &read_requests_[read_idx];
block->pending = false;
@@ -528,7 +526,7 @@
if (block->id().id != needed_read_id_) {
LOG(VERBOSE) << "read " << block->id().id << " completed while waiting for "
<< needed_read_id_;
- return true;
+ return;
}
for (uint64_t id = needed_read_id_;; ++id) {
@@ -537,22 +535,15 @@
if (current_block->pending) {
break;
}
- if (!ProcessRead(current_block)) {
- return false;
- }
+ ProcessRead(current_block);
++needed_read_id_;
}
-
- return true;
}
- bool ProcessRead(IoBlock* block) {
+ void ProcessRead(IoBlock* block) {
if (!block->payload->empty()) {
if (!incoming_header_.has_value()) {
- if (block->payload->size() != sizeof(amessage)) {
- HandleError("received packet of unexpected length while reading header");
- return false;
- }
+ CHECK_EQ(sizeof(amessage), block->payload->size());
amessage msg;
memcpy(&msg, block->payload->data(), sizeof(amessage));
LOG(DEBUG) << "USB read:" << dump_header(&msg);
@@ -560,10 +551,7 @@
} else {
size_t bytes_left = incoming_header_->data_length - incoming_payload_.size();
Block payload = std::move(*block->payload);
- if (block->payload->size() > bytes_left) {
- HandleError("received too many bytes while waiting for payload");
- return false;
- }
+ CHECK_LE(payload.size(), bytes_left);
incoming_payload_.append(std::make_unique<Block>(std::move(payload)));
}
@@ -582,7 +570,6 @@
PrepareReadBlock(block, block->id().id + kUsbReadQueueDepth);
SubmitRead(block);
- return true;
}
bool SubmitRead(IoBlock* block) {
diff --git a/adb/daemon/usb_ffs.cpp b/adb/daemon/usb_ffs.cpp
index a64ce40..338d776 100644
--- a/adb/daemon/usb_ffs.cpp
+++ b/adb/daemon/usb_ffs.cpp
@@ -299,7 +299,6 @@
}
// Signal only when writing the descriptors to ffs
android::base::SetProperty("sys.usb.ffs.ready", "1");
- *out_control = std::move(control);
}
bulk_out.reset(adb_open(USB_FFS_ADB_OUT, O_RDONLY));
@@ -314,6 +313,7 @@
return false;
}
+ *out_control = std::move(control);
*out_bulk_in = std::move(bulk_in);
*out_bulk_out = std::move(bulk_out);
return true;
diff --git a/adb/transport.h b/adb/transport.h
index f4490ed..3473ca2 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -274,6 +274,9 @@
std::string device;
std::string devpath;
+ // Used to provide the key to the framework.
+ std::string auth_key;
+
bool IsTcpDevice() const { return type == kTransportLocal; }
#if ADB_HOST
diff --git a/base/include/android-base/logging.h b/base/include/android-base/logging.h
index f94cc25..ab6476c 100644
--- a/base/include/android-base/logging.h
+++ b/base/include/android-base/logging.h
@@ -469,7 +469,7 @@
} // namespace base
} // namespace android
-namespace std {
+namespace std { // NOLINT(cert-dcl58-cpp)
// Emit a warning of ostream<< with std::string*. The intention was most likely to print *string.
//
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 6936cc2..8e7d918 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -1093,8 +1093,8 @@
void LogBootInfoToStatsd(std::chrono::milliseconds end_time,
std::chrono::milliseconds total_duration, int32_t bootloader_duration_ms,
double time_since_last_boot_sec) {
- const auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "<EMPTY>");
- const auto system_reason = android::base::GetProperty(system_reboot_reason_property, "<EMPTY>");
+ auto reason = android::base::GetProperty(bootloader_reboot_reason_property, "<EMPTY>");
+ auto system_reason = android::base::GetProperty(system_reboot_reason_property, "<EMPTY>");
android::util::stats_write(android::util::BOOT_SEQUENCE_REPORTED, reason.c_str(),
system_reason.c_str(), end_time.count(), total_duration.count(),
(int64_t)bootloader_duration_ms,
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index c436be3..8923f40 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -144,14 +144,13 @@
{ "dts", "dt.img", "dt.sig", "dts", true, ImageType::BootCritical },
{ "odm", "odm.img", "odm.sig", "odm", true, ImageType::Normal },
{ "product", "product.img", "product.sig", "product", true, ImageType::Normal },
- { "product_services",
- "product_services.img",
- "product_services.sig",
- "product_services",
- true, ImageType::Normal },
{ "recovery", "recovery.img", "recovery.sig", "recovery", true, ImageType::BootCritical },
{ "super", "super.img", "super.sig", "super", true, ImageType::Extra },
{ "system", "system.img", "system.sig", "system", false, ImageType::Normal },
+ { "system_ext",
+ "system_ext.img", "system_ext.sig",
+ "system_ext",
+ true, ImageType::Normal },
{ nullptr, "system_other.img", "system.sig", "system", true, ImageType::Normal },
{ "userdata", "userdata.img", "userdata.sig", "userdata", true, ImageType::Extra },
{ "vbmeta", "vbmeta.img", "vbmeta.sig", "vbmeta", true, ImageType::BootCritical },
diff --git a/fs_mgr/libdm/include/libdm/dm.h b/fs_mgr/libdm/include/libdm/dm.h
index afcb090..08376c0 100644
--- a/fs_mgr/libdm/include/libdm/dm.h
+++ b/fs_mgr/libdm/include/libdm/dm.h
@@ -38,7 +38,7 @@
#define DM_VERSION2 (0)
#define DM_ALIGN_MASK (7)
-#define DM_ALIGN(x) ((x + DM_ALIGN_MASK) & ~DM_ALIGN_MASK)
+#define DM_ALIGN(x) (((x) + DM_ALIGN_MASK) & ~DM_ALIGN_MASK)
namespace android {
namespace dm {
diff --git a/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp b/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp
index a0ccc10..16a82d2 100644
--- a/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp
+++ b/fs_mgr/libfiemap_writer/split_fiemap_writer.cpp
@@ -95,8 +95,9 @@
// To make sure the alignment doesn't create too much inconsistency, we
// account the *actual* size, not the requested size.
total_bytes_written += writer->size();
- remaining_bytes -= writer->size();
-
+ // writer->size() is block size aligned and could be bigger than remaining_bytes
+ // If remaining_bytes is bigger, set remaining_bytes to 0 to avoid underflow error.
+ remaining_bytes = remaining_bytes > writer->size() ? (remaining_bytes - writer->size()) : 0;
out->AddFile(std::move(writer));
}
diff --git a/healthd/Android.mk b/healthd/Android.mk
index d18f15a..05123af 100644
--- a/healthd/Android.mk
+++ b/healthd/Android.mk
@@ -93,7 +93,6 @@
libbinderthreadstate \
libhidltransport \
libhidlbase \
- libhwbinder_noltopgo \
libhealthstoragedefault \
libvndksupport \
libhealthd_charger \
@@ -152,7 +151,6 @@
libbinderthreadstate \
libhidltransport \
libhidlbase \
- libhwbinder_noltopgo \
libhealthstoragedefault \
libvndksupport \
libhealthd_charger_nops \
diff --git a/init/Android.bp b/init/Android.bp
index 6bc581d..86dcb4c 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -26,6 +26,7 @@
"-Wextra",
"-Wno-unused-parameter",
"-Werror",
+ "-DALLOW_FIRST_STAGE_CONSOLE=0",
"-DALLOW_LOCAL_PROP_OVERRIDE=0",
"-DALLOW_PERMISSIVE_SELINUX=0",
"-DREBOOT_BOOTLOADER_ON_PANIC=0",
@@ -36,6 +37,8 @@
product_variables: {
debuggable: {
cppflags: [
+ "-UALLOW_FIRST_STAGE_CONSOLE",
+ "-DALLOW_FIRST_STAGE_CONSOLE=1",
"-UALLOW_LOCAL_PROP_OVERRIDE",
"-DALLOW_LOCAL_PROP_OVERRIDE=1",
"-UALLOW_PERMISSIVE_SELINUX",
diff --git a/init/Android.mk b/init/Android.mk
index b24f757..9017772 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -8,6 +8,7 @@
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
init_options += \
+ -DALLOW_FIRST_STAGE_CONSOLE=1 \
-DALLOW_LOCAL_PROP_OVERRIDE=1 \
-DALLOW_PERMISSIVE_SELINUX=1 \
-DREBOOT_BOOTLOADER_ON_PANIC=1 \
@@ -15,6 +16,7 @@
-DDUMP_ON_UMOUNT_FAILURE=1
else
init_options += \
+ -DALLOW_FIRST_STAGE_CONSOLE=0 \
-DALLOW_LOCAL_PROP_OVERRIDE=0 \
-DALLOW_PERMISSIVE_SELINUX=0 \
-DREBOOT_BOOTLOADER_ON_PANIC=0 \
diff --git a/init/action_manager.cpp b/init/action_manager.cpp
index 9de4085..985b8ad 100644
--- a/init/action_manager.cpp
+++ b/init/action_manager.cpp
@@ -88,7 +88,8 @@
current_command_ = 0;
if (action->oneshot()) {
auto eraser = [&action](std::unique_ptr<Action>& a) { return a.get() == action; };
- actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser));
+ actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser),
+ actions_.end());
}
}
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index cc84aa0..ba2c7ac 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -243,7 +243,7 @@
strlcpy(ifr.ifr_name, args[1].c_str(), IFNAMSIZ);
- unique_fd s(TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_DGRAM, 0)));
+ unique_fd s(TEMP_FAILURE_RETRY(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0)));
if (s < 0) return ErrnoError() << "opening socket failed";
if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
@@ -784,7 +784,7 @@
}
static Result<void> readahead_file(const std::string& filename, bool fully) {
- android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY)));
+ android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(filename.c_str(), O_RDONLY | O_CLOEXEC)));
if (fd == -1) {
return ErrnoError() << "Error opening file";
}
@@ -1107,7 +1107,7 @@
// /apex/<name> paths, so unless we filter them out, we will parse the
// same file twice.
std::vector<std::string> paths = android::base::Split(path, "/");
- if (paths.size() >= 2 && paths[1].find('@') != std::string::npos) {
+ if (paths.size() >= 3 && paths[2].find('@') != std::string::npos) {
continue;
}
configs.push_back(path);
diff --git a/init/first_stage_init.cpp b/init/first_stage_init.cpp
index 17387e2..b60c450 100644
--- a/init/first_stage_init.cpp
+++ b/init/first_stage_init.cpp
@@ -24,10 +24,12 @@
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <sys/types.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <filesystem>
#include <string>
+#include <thread>
#include <vector>
#include <android-base/chrono_utils.h>
@@ -76,7 +78,7 @@
if (S_ISDIR(info.st_mode)) {
is_dir = true;
- auto fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);
+ auto fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
if (fd >= 0) {
auto subdir =
std::unique_ptr<DIR, decltype(&closedir)>{fdopendir(fd), closedir};
@@ -92,9 +94,50 @@
}
}
-bool ForceNormalBoot() {
- std::string cmdline;
- android::base::ReadFileToString("/proc/cmdline", &cmdline);
+void StartConsole() {
+ if (mknod("/dev/console", S_IFCHR | 0600, makedev(5, 1))) {
+ PLOG(ERROR) << "unable to create /dev/console";
+ return;
+ }
+ pid_t pid = fork();
+ if (pid != 0) {
+ int status;
+ waitpid(pid, &status, 0);
+ LOG(ERROR) << "console shell exited with status " << status;
+ return;
+ }
+ int fd = -1;
+ int tries = 10;
+ // The device driver for console may not be ready yet so retry for a while in case of failure.
+ while (tries--) {
+ fd = open("/dev/console", O_RDWR);
+ if (fd != -1) {
+ break;
+ }
+ std::this_thread::sleep_for(100ms);
+ }
+ if (fd == -1) {
+ LOG(ERROR) << "Could not open /dev/console, errno = " << errno;
+ _exit(127);
+ }
+ ioctl(fd, TIOCSCTTY, 0);
+ dup2(fd, 0);
+ dup2(fd, 1);
+ dup2(fd, 2);
+ close(fd);
+
+ const char* path = "/system/bin/sh";
+ const char* args[] = {path, nullptr};
+ int rv = execv(path, const_cast<char**>(args));
+ LOG(ERROR) << "unable to execv, returned " << rv << " errno " << errno;
+ _exit(127);
+}
+
+bool FirstStageConsole(const std::string& cmdline) {
+ return cmdline.find("androidboot.first_stage_console=1") != std::string::npos;
+}
+
+bool ForceNormalBoot(const std::string& cmdline) {
return cmdline.find("androidboot.force_normal_boot=1") != std::string::npos;
}
@@ -109,7 +152,7 @@
std::vector<std::pair<std::string, int>> errors;
#define CHECKCALL(x) \
- if (x != 0) errors.emplace_back(#x " failed", errno);
+ if ((x) != 0) errors.emplace_back(#x " failed", errno);
// Clear the umask.
umask(0);
@@ -127,6 +170,8 @@
#undef MAKE_STR
// Don't expose the raw commandline to unprivileged processes.
CHECKCALL(chmod("/proc/cmdline", 0440));
+ std::string cmdline;
+ android::base::ReadFileToString("/proc/cmdline", &cmdline);
gid_t groups[] = {AID_READPROC};
CHECKCALL(setgroups(arraysize(groups), groups));
CHECKCALL(mount("sysfs", "/sys", "sysfs", 0, NULL));
@@ -198,7 +243,11 @@
LOG(FATAL) << "Failed to load kernel modules";
}
- if (ForceNormalBoot()) {
+ if (ALLOW_FIRST_STAGE_CONSOLE && FirstStageConsole(cmdline)) {
+ StartConsole();
+ }
+
+ if (ForceNormalBoot(cmdline)) {
mkdir("/first_stage_ramdisk", 0755);
// SwitchRoot() must be called with a mount point as the target, so we bind mount the
// target directory to itself here.
diff --git a/init/persistent_properties.cpp b/init/persistent_properties.cpp
index 73787b9..baa9ad4 100644
--- a/init/persistent_properties.cpp
+++ b/init/persistent_properties.cpp
@@ -69,7 +69,7 @@
continue;
}
- unique_fd fd(openat(dirfd(dir.get()), entry->d_name, O_RDONLY | O_NOFOLLOW));
+ unique_fd fd(openat(dirfd(dir.get()), entry->d_name, O_RDONLY | O_NOFOLLOW | O_CLOEXEC));
if (fd == -1) {
PLOG(ERROR) << "Unable to open persistent property file \"" << entry->d_name << "\"";
continue;
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 1520c9f..b89914f 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -667,9 +667,9 @@
if (flen > 0) {
if (filter[flen - 1] == '*') {
- if (strncmp(key, filter, flen - 1)) continue;
+ if (strncmp(key, filter, flen - 1) != 0) continue;
} else {
- if (strcmp(key, filter)) continue;
+ if (strcmp(key, filter) != 0) continue;
}
}
diff --git a/init/service.cpp b/init/service.cpp
index cd08f3d..f95b675 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -126,7 +126,7 @@
: Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args) {}
Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
- const std::vector<gid_t>& supp_gids, unsigned namespace_flags,
+ const std::vector<gid_t>& supp_gids, int namespace_flags,
const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
const std::vector<std::string>& args)
: name_(name),
diff --git a/init/service.h b/init/service.h
index 78f94ce..cc35a8d 100644
--- a/init/service.h
+++ b/init/service.h
@@ -69,9 +69,8 @@
const std::vector<std::string>& args);
Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
- const std::vector<gid_t>& supp_gids, unsigned namespace_flags,
- const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
- const std::vector<std::string>& args);
+ const std::vector<gid_t>& supp_gids, int namespace_flags, const std::string& seclabel,
+ Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args);
static std::unique_ptr<Service> MakeTemporaryOneshotService(const std::vector<std::string>& args);
@@ -109,7 +108,7 @@
int crash_count() const { return crash_count_; }
uid_t uid() const { return proc_attr_.uid; }
gid_t gid() const { return proc_attr_.gid; }
- unsigned namespace_flags() const { return namespaces_.flags; }
+ int namespace_flags() const { return namespaces_.flags; }
const std::vector<gid_t>& supp_gids() const { return proc_attr_.supp_gids; }
const std::string& seclabel() const { return seclabel_; }
const std::vector<int>& keycodes() const { return keycodes_; }
diff --git a/init/service_test.cpp b/init/service_test.cpp
index 4bfaa6b..6a34acc 100644
--- a/init/service_test.cpp
+++ b/init/service_test.cpp
@@ -30,7 +30,7 @@
TEST(service, pod_initialized) {
constexpr auto memory_size = sizeof(Service);
- alignas(alignof(Service)) char old_memory[memory_size];
+ alignas(alignof(Service)) unsigned char old_memory[memory_size];
for (std::size_t i = 0; i < memory_size; ++i) {
old_memory[i] = 0xFF;
@@ -45,7 +45,7 @@
EXPECT_EQ(0, service_in_old_memory->crash_count());
EXPECT_EQ(0U, service_in_old_memory->uid());
EXPECT_EQ(0U, service_in_old_memory->gid());
- EXPECT_EQ(0U, service_in_old_memory->namespace_flags());
+ EXPECT_EQ(0, service_in_old_memory->namespace_flags());
EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory->ioprio_class());
EXPECT_EQ(0, service_in_old_memory->ioprio_pri());
EXPECT_EQ(0, service_in_old_memory->priority());
@@ -64,7 +64,7 @@
EXPECT_EQ(0, service_in_old_memory2->crash_count());
EXPECT_EQ(0U, service_in_old_memory2->uid());
EXPECT_EQ(0U, service_in_old_memory2->gid());
- EXPECT_EQ(0U, service_in_old_memory2->namespace_flags());
+ EXPECT_EQ(0, service_in_old_memory2->namespace_flags());
EXPECT_EQ(IoSchedClass_NONE, service_in_old_memory2->ioprio_class());
EXPECT_EQ(0, service_in_old_memory2->ioprio_pri());
EXPECT_EQ(0, service_in_old_memory2->priority());
diff --git a/init/service_utils.cpp b/init/service_utils.cpp
index f88ea97..34aa837 100644
--- a/init/service_utils.cpp
+++ b/init/service_utils.cpp
@@ -120,22 +120,19 @@
}
void ZapStdio() {
- int fd;
- fd = open("/dev/null", O_RDWR);
+ auto fd = unique_fd{open("/dev/null", O_RDWR | O_CLOEXEC)};
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
- close(fd);
}
void OpenConsole(const std::string& console) {
- int fd = open(console.c_str(), O_RDWR);
- if (fd == -1) fd = open("/dev/null", O_RDWR);
+ auto fd = unique_fd{open(console.c_str(), O_RDWR | O_CLOEXEC)};
+ if (fd == -1) fd.reset(open("/dev/null", O_RDWR | O_CLOEXEC));
ioctl(fd, TIOCSCTTY, 0);
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, 2);
- close(fd);
}
} // namespace
diff --git a/init/service_utils.h b/init/service_utils.h
index c26b123..365cb29 100644
--- a/init/service_utils.h
+++ b/init/service_utils.h
@@ -30,7 +30,7 @@
namespace init {
struct NamespaceInfo {
- unsigned flags;
+ int flags;
// Pair of namespace type, path to name.
std::vector<std::pair<int, std::string>> namespaces_to_enter;
};
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index 02ed507..2f9541b 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -246,7 +246,7 @@
// We explicitly do not use O_CLOEXEC here, such that we can reference this FD by number
// in the subcontext process after we exec.
- int child_fd = dup(subcontext_socket);
+ int child_fd = dup(subcontext_socket); // NOLINT(android-cloexec-dup)
if (child_fd < 0) {
PLOG(FATAL) << "Could not dup child_fd";
}
diff --git a/init/tokenizer_test.cpp b/init/tokenizer_test.cpp
index acfc7c7..6b31683 100644
--- a/init/tokenizer_test.cpp
+++ b/init/tokenizer_test.cpp
@@ -46,6 +46,7 @@
return;
case T_NEWLINE:
tokens.emplace_back(std::move(current_line));
+ current_line.clear();
break;
case T_TEXT:
current_line.emplace_back(state.text);
diff --git a/init/uevent_listener.cpp b/init/uevent_listener.cpp
index 62cd2be..ac633776 100644
--- a/init/uevent_listener.cpp
+++ b/init/uevent_listener.cpp
@@ -131,7 +131,7 @@
const ListenerCallback& callback) const {
int dfd = dirfd(d);
- int fd = openat(dfd, "uevent", O_WRONLY);
+ int fd = openat(dfd, "uevent", O_WRONLY | O_CLOEXEC);
if (fd >= 0) {
write(fd, "add\n", 4);
close(fd);
@@ -146,7 +146,7 @@
while ((de = readdir(d)) != nullptr) {
if (de->d_type != DT_DIR || de->d_name[0] == '.') continue;
- fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY);
+ fd = openat(dfd, de->d_name, O_RDONLY | O_DIRECTORY | O_CLOEXEC);
if (fd < 0) continue;
std::unique_ptr<DIR, decltype(&closedir)> d2(fdopendir(fd), closedir);
diff --git a/init/util.cpp b/init/util.cpp
index 2b34242..058a111 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -450,7 +450,7 @@
// SetStdioToDevNull() must be called again in second stage init.
void SetStdioToDevNull(char** argv) {
// Make stdin/stdout/stderr all point to /dev/null.
- int fd = open("/dev/null", O_RDWR);
+ int fd = open("/dev/null", O_RDWR); // NOLINT(android-cloexec-open)
if (fd == -1) {
int saved_errno = errno;
android::base::InitLogging(argv, &android::base::KernelLogger, InitAborter);
diff --git a/libappfuse/FuseBridgeLoop.cc b/libappfuse/FuseBridgeLoop.cc
index f1ca446..f71d0c3 100644
--- a/libappfuse/FuseBridgeLoop.cc
+++ b/libappfuse/FuseBridgeLoop.cc
@@ -86,6 +86,7 @@
const bool proxy_read_ready = last_proxy_events_.events & EPOLLIN;
const bool proxy_write_ready = last_proxy_events_.events & EPOLLOUT;
+ last_state_ = state_;
last_device_events_.events = 0;
last_proxy_events_.events = 0;
diff --git a/libcutils/include/cutils/native_handle.h b/libcutils/include/cutils/native_handle.h
index f6cae36..4f07456 100644
--- a/libcutils/include/cutils/native_handle.h
+++ b/libcutils/include/cutils/native_handle.h
@@ -69,10 +69,11 @@
/*
* native_handle_create
- *
+ *
* creates a native_handle_t and initializes it. must be destroyed with
- * native_handle_delete().
- *
+ * native_handle_delete(). Note that numFds must be <= NATIVE_HANDLE_MAX_FDS,
+ * numInts must be <= NATIVE_HANDLE_MAX_INTS, and both must be >= 0.
+ *
*/
native_handle_t* native_handle_create(int numFds, int numInts);
diff --git a/libmeminfo/procmeminfo.cpp b/libmeminfo/procmeminfo.cpp
index caf6e86..a8b43c1 100644
--- a/libmeminfo/procmeminfo.cpp
+++ b/libmeminfo/procmeminfo.cpp
@@ -312,12 +312,12 @@
cur_page * sizeof(uint64_t));
if (bytes != total_bytes) {
if (bytes == -1) {
- PLOG(ERROR) << "Failed to read page data at offset "
+ PLOG(ERROR) << "Failed to read page data at offset 0x" << std::hex
<< cur_page * sizeof(uint64_t);
} else {
- LOG(ERROR) << "Failed to read page data at offset "
- << cur_page * sizeof(uint64_t) << " read bytes " << sizeof(uint64_t)
- << " expected bytes " << bytes;
+ LOG(ERROR) << "Failed to read page data at offset 0x" << std::hex
+ << cur_page * sizeof(uint64_t) << std::dec << " read bytes " << bytes
+ << " expected bytes " << total_bytes;
}
return false;
}
diff --git a/libmemunreachable/Android.bp b/libmemunreachable/Android.bp
index 62a7266..f1abdd2 100644
--- a/libmemunreachable/Android.bp
+++ b/libmemunreachable/Android.bp
@@ -111,7 +111,7 @@
static_libs: ["libmemunreachable"],
shared_libs: [
"libbinder",
- "libhwbinder",
+ "libhidlbase",
"libutils",
],
test_suites: ["device-tests"],
diff --git a/libstats/statsd_writer.c b/libstats/statsd_writer.c
index b778f92..b1c05ea 100644
--- a/libstats/statsd_writer.c
+++ b/libstats/statsd_writer.c
@@ -109,6 +109,11 @@
if (sock < 0) {
ret = -errno;
} else {
+ int sndbuf = 1 * 1024 * 1024; // set max send buffer size 1MB
+ socklen_t bufLen = sizeof(sndbuf);
+ // SO_RCVBUF does not have an effect on unix domain socket, but SO_SNDBUF does.
+ // Proceed to connect even setsockopt fails.
+ setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sndbuf, bufLen);
struct sockaddr_un un;
memset(&un, 0, sizeof(struct sockaddr_un));
un.sun_family = AF_UNIX;
diff --git a/libsystem/include/system/graphics-base-v1.2.h b/libsystem/include/system/graphics-base-v1.2.h
new file mode 100644
index 0000000..2194f5e
--- /dev/null
+++ b/libsystem/include/system/graphics-base-v1.2.h
@@ -0,0 +1,31 @@
+// This file is autogenerated by hidl-gen. Do not edit manually.
+// Source: android.hardware.graphics.common@1.2
+// Location: hardware/interfaces/graphics/common/1.2/
+
+#ifndef HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
+#define HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ HAL_HDR_HDR10_PLUS = 4,
+} android_hdr_v1_2_t;
+
+typedef enum {
+ HAL_DATASPACE_DISPLAY_BT2020 = 142999552 /* ((STANDARD_BT2020 | TRANSFER_SRGB) | RANGE_FULL) */,
+ HAL_DATASPACE_DYNAMIC_DEPTH = 4098 /* 0x1002 */,
+ HAL_DATASPACE_JPEG_APP_SEGMENTS = 4099 /* 0x1003 */,
+ HAL_DATASPACE_HEIF = 4100 /* 0x1004 */,
+} android_dataspace_v1_2_t;
+
+typedef enum {
+ HAL_PIXEL_FORMAT_HSV_888 = 55 /* 0x37 */,
+} android_pixel_format_v1_2_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // HIDL_GENERATED_ANDROID_HARDWARE_GRAPHICS_COMMON_V1_2_EXPORTED_CONSTANTS_H_
diff --git a/libsystem/include/system/graphics-base.h b/libsystem/include/system/graphics-base.h
index ea92007..92ee077 100644
--- a/libsystem/include/system/graphics-base.h
+++ b/libsystem/include/system/graphics-base.h
@@ -3,5 +3,6 @@
#include "graphics-base-v1.0.h"
#include "graphics-base-v1.1.h"
+#include "graphics-base-v1.2.h"
#endif // SYSTEM_CORE_GRAPHICS_BASE_H_
diff --git a/lmkd/lmkd.c b/lmkd/lmkd.c
index 48140b8..521f92e 100644
--- a/lmkd/lmkd.c
+++ b/lmkd/lmkd.c
@@ -1373,8 +1373,8 @@
set_process_group_and_prio(pid, SP_FOREGROUND, ANDROID_PRIORITY_HIGHEST);
inc_killcnt(procp->oomadj);
- ALOGI("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB",
- taskname, pid, uid, procp->oomadj, tasksize * page_k);
+ ALOGE("Kill '%s' (%d), uid %d, oom_adj %d to free %ldkB", taskname, pid, uid, procp->oomadj,
+ tasksize * page_k);
TRACE_KILL_END();
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 15e07fe..6e38d95 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -483,7 +483,8 @@
" Additionally, 'kernel' for userdebug and eng builds, and\n"
" 'security' for Device Owner installations.\n"
" Multiple -b parameters or comma separated list of buffers are\n"
- " allowed. Buffers interleaved. Default -b main,system,crash.\n"
+ " allowed. Buffers interleaved.\n"
+ " Default -b main,system,crash,kernel.\n"
" -B, --binary Output the log in binary.\n"
" -S, --statistics Output statistics.\n"
" -p, --prune Print prune white and ~black list. Service is specified as\n"
@@ -1312,6 +1313,10 @@
dev = dev->next = new log_device_t("crash", false);
context->devCount++;
}
+ if (android_name_to_log_id("kernel") == LOG_ID_KERNEL) {
+ dev = dev->next = new log_device_t("kernel", false);
+ context->devCount++;
+ }
}
if (!!context->logRotateSizeKBytes && !context->outputFileName) {
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index f084cd2..246f9ac 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -113,10 +113,10 @@
else
LOCAL_POST_INSTALL_CMD += ; ln -sf /system/product $(TARGET_ROOT_OUT)/product
endif
-ifdef BOARD_USES_PRODUCT_SERVICESIMAGE
- LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/product_services
+ifdef BOARD_USES_SYSTEM_EXTIMAGE
+ LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/system_ext
else
- LOCAL_POST_INSTALL_CMD += ; ln -sf /system/product_services $(TARGET_ROOT_OUT)/product_services
+ LOCAL_POST_INSTALL_CMD += ; ln -sf /system/system_ext $(TARGET_ROOT_OUT)/system_ext
endif
ifdef BOARD_USES_METADATA_PARTITION
LOCAL_POST_INSTALL_CMD += ; mkdir -p $(TARGET_ROOT_OUT)/metadata
diff --git a/rootdir/etc/ld.config.txt b/rootdir/etc/ld.config.txt
index b1616d3..f732b3c 100644
--- a/rootdir/etc/ld.config.txt
+++ b/rootdir/etc/ld.config.txt
@@ -183,6 +183,7 @@
namespace.media.asan.search.paths = /apex/com.android.media/${LIB}
namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
+namespace.media.asan.permitted.paths = /apex/com.android.media/${LIB}/extractors
namespace.media.links = default
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
@@ -651,6 +652,7 @@
namespace.media.asan.search.paths = /apex/com.android.media/${LIB}
namespace.media.permitted.paths = /apex/com.android.media/${LIB}/extractors
+namespace.media.asan.permitted.paths = /apex/com.android.media/${LIB}/extractors
namespace.media.links = default
namespace.media.link.default.shared_libs = %LLNDK_LIBRARIES%
diff --git a/rootdir/etc/public.libraries.android.txt b/rootdir/etc/public.libraries.android.txt
index d8f6095..27e855f 100644
--- a/rootdir/etc/public.libraries.android.txt
+++ b/rootdir/etc/public.libraries.android.txt
@@ -1,6 +1,7 @@
# See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
libandroid.so
libaaudio.so
+libamidi.so
libbinder_ndk.so
libc.so
libcamera2ndk.so
diff --git a/rootdir/etc/public.libraries.iot.txt b/rootdir/etc/public.libraries.iot.txt
index 20905bf..b565340 100644
--- a/rootdir/etc/public.libraries.iot.txt
+++ b/rootdir/etc/public.libraries.iot.txt
@@ -2,6 +2,7 @@
libandroid.so
libandroidthings.so
libaaudio.so
+libamidi.so
libbinder_ndk.so
libc.so
libcamera2ndk.so
diff --git a/rootdir/etc/public.libraries.wear.txt b/rootdir/etc/public.libraries.wear.txt
index 4ece5b5..7cbda08 100644
--- a/rootdir/etc/public.libraries.wear.txt
+++ b/rootdir/etc/public.libraries.wear.txt
@@ -1,6 +1,7 @@
# See https://android.googlesource.com/platform/ndk/+/master/docs/PlatformApis.md
libandroid.so
libaaudio.so
+libamidi.so
libbinder_ndk.so
libc.so
libcamera2ndk.so
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 3acf301..55a1623 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -590,7 +590,6 @@
symlink /data/data /data/user/0
mkdir /data/media 0770 media_rw media_rw
- mkdir /data/media/obb 0770 media_rw media_rw
mkdir /data/cache 0770 system cache
mkdir /data/cache/recovery 0770 system cache
@@ -667,6 +666,12 @@
chown root system /sys/module/lowmemorykiller/parameters/minfree
chmod 0664 /sys/module/lowmemorykiller/parameters/minfree
+ # System server manages zram writeback
+ chown root system /sys/block/zram0/idle
+ chmod 0664 /sys/block/zram0/idle
+ chown root system /sys/block/zram0/writeback
+ chmod 0664 /sys/block/zram0/writeback
+
# Tweak background writeout
write /proc/sys/vm/dirty_expire_centisecs 200
write /proc/sys/vm/dirty_background_ratio 5
diff --git a/rootdir/init.usb.rc b/rootdir/init.usb.rc
index f0681d2..b6cba90 100644
--- a/rootdir/init.usb.rc
+++ b/rootdir/init.usb.rc
@@ -14,7 +14,7 @@
# adbd is controlled via property triggers in init.<platform>.usb.rc
service adbd /system/bin/adbd --root_seclabel=u:r:su:s0
class core
- socket adbd stream 660 system system
+ socket adbd seqpacket 660 system system
disabled
seclabel u:r:adbd:s0
diff --git a/rootdir/init.zygote32.rc b/rootdir/init.zygote32.rc
index f8e680d..bf3fb42 100644
--- a/rootdir/init.zygote32.rc
+++ b/rootdir/init.zygote32.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
diff --git a/rootdir/init.zygote32_64.rc b/rootdir/init.zygote32_64.rc
index 0235370..1bab588 100644
--- a/rootdir/init.zygote32_64.rc
+++ b/rootdir/init.zygote32_64.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
@@ -20,6 +20,6 @@
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
- socket blastula_pool_secondary stream 660 root system
+ socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
diff --git a/rootdir/init.zygote64.rc b/rootdir/init.zygote64.rc
index 3f3cc15..6fa210a 100644
--- a/rootdir/init.zygote64.rc
+++ b/rootdir/init.zygote64.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
index fae38c9..48461ec 100644
--- a/rootdir/init.zygote64_32.rc
+++ b/rootdir/init.zygote64_32.rc
@@ -4,7 +4,7 @@
user root
group root readproc reserved_disk
socket zygote stream 660 root system
- socket blastula_pool stream 660 root system
+ socket usap_pool_primary stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
@@ -20,6 +20,6 @@
user root
group root readproc reserved_disk
socket zygote_secondary stream 660 root system
- socket blastula_pool_secondary stream 660 root system
+ socket usap_pool_secondary stream 660 root system
onrestart restart zygote
writepid /dev/cpuset/foreground/tasks
diff --git a/sdcard/sdcard.cpp b/sdcard/sdcard.cpp
index 2b35819..0acea72 100644
--- a/sdcard/sdcard.cpp
+++ b/sdcard/sdcard.cpp
@@ -214,7 +214,14 @@
if (multi_user) {
std::string obb_path = source_path + "/obb";
- fs_prepare_dir(obb_path.c_str(), 0775, uid, gid);
+ // Only attempt to prepare the /obb dir if it already exists. We want
+ // the legacy obb path "/data/media/obb" to be fixed up so that we can
+ // migrate it to its new location, but we don't want the directory to be
+ // created if it doesn't already exist.
+ struct stat sb;
+ if (TEMP_FAILURE_RETRY(lstat(obb_path.c_str(), &sb)) == 0) {
+ fs_prepare_dir(obb_path.c_str(), 0775, uid, gid);
+ }
}
exit(0);
diff --git a/shell_and_utilities/Android.bp b/shell_and_utilities/Android.bp
index 3bc3883..bac3dc3 100644
--- a/shell_and_utilities/Android.bp
+++ b/shell_and_utilities/Android.bp
@@ -13,7 +13,6 @@
"auditctl",
"awk",
"bzip2",
- "grep",
"logwrapper",
"mini-keyctl",
"mkshrc",
@@ -32,7 +31,6 @@
phony {
name: "shell_and_utilities_recovery",
required: [
- "grep.recovery",
"sh.recovery",
"toolbox.recovery",
"toybox.recovery",
@@ -44,7 +42,6 @@
name: "shell_and_utilities_vendor",
required: [
"awk_vendor",
- "grep_vendor",
"logwrapper_vendor",
"mkshrc_vendor",
"sh_vendor",
diff --git a/toolbox/Android.bp b/toolbox/Android.bp
index 9ca5607..0cc603a 100644
--- a/toolbox/Android.bp
+++ b/toolbox/Android.bp
@@ -1,14 +1,10 @@
cc_defaults {
name: "toolbox_defaults",
-
cflags: [
"-Werror",
"-Wno-unused-parameter",
"-Wno-unused-const-variable",
"-D_FILE_OFFSET_BITS=64",
- "-DWITHOUT_NLS",
- "-DWITHOUT_BZ2",
- "-DWITHOUT_GZIP",
],
}
@@ -60,39 +56,3 @@
vendor: true,
defaults: ["toolbox_binary_defaults"],
}
-
-// We build BSD grep separately (but see http://b/111849261).
-cc_defaults {
- name: "grep_common",
- defaults: ["toolbox_defaults"],
- srcs: [
- "upstream-netbsd/usr.bin/grep/fastgrep.c",
- "upstream-netbsd/usr.bin/grep/file.c",
- "upstream-netbsd/usr.bin/grep/grep.c",
- "upstream-netbsd/usr.bin/grep/queue.c",
- "upstream-netbsd/usr.bin/grep/util.c",
- ],
- symlinks: [
- "egrep",
- "fgrep",
- ],
- sanitize: {
- integer_overflow: false,
- },
-}
-
-cc_binary {
- name: "grep",
- defaults: ["grep_common"],
- recovery_available: true,
-}
-
-// Build vendor grep.
-// TODO: Add vendor_available to "grep" module and remove "grep_vendor" module
-// when vendor_available is fully supported.
-cc_binary {
- name: "grep_vendor",
- stem: "grep",
- vendor: true,
- defaults: ["grep_common"],
-}
diff --git a/toolbox/upstream-netbsd/usr.bin/grep/fastgrep.c b/toolbox/upstream-netbsd/usr.bin/grep/fastgrep.c
deleted file mode 100644
index 2fcd864..0000000
--- a/toolbox/upstream-netbsd/usr.bin/grep/fastgrep.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* $OpenBSD: util.c,v 1.36 2007/10/02 17:59:18 otto Exp $ */
-/* $FreeBSD: head/usr.bin/grep/fastgrep.c 211496 2010-08-19 09:28:59Z des $ */
-
-/*-
- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
- * Copyright (C) 2008 Gabor Kovesdan <gabor@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * XXX: This file is a speed up for grep to cover the defects of the
- * regex library. These optimizations should practically be implemented
- * there keeping this code clean. This is a future TODO, but for the
- * meantime, we need to use this workaround.
- */
-
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
-#include <sys/cdefs.h>
-__RCSID("$NetBSD: fastgrep.c,v 1.5 2011/04/18 03:27:40 joerg Exp $");
-
-#include <limits.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <string.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "grep.h"
-
-static inline int grep_cmp(const unsigned char *, const unsigned char *, size_t);
-static inline void grep_revstr(unsigned char *, int);
-
-void
-fgrepcomp(fastgrep_t *fg, const char *pat)
-{
- unsigned int i;
-
- /* Initialize. */
- fg->len = strlen(pat);
- fg->bol = false;
- fg->eol = false;
- fg->reversed = false;
-
- fg->pattern = (unsigned char *)grep_strdup(pat);
-
- /* Preprocess pattern. */
- for (i = 0; i <= UCHAR_MAX; i++)
- fg->qsBc[i] = fg->len;
- for (i = 1; i < fg->len; i++)
- fg->qsBc[fg->pattern[i]] = fg->len - i;
-}
-
-/*
- * Returns: -1 on failure, 0 on success
- */
-int
-fastcomp(fastgrep_t *fg, const char *pat)
-{
- unsigned int i;
- int firstHalfDot = -1;
- int firstLastHalfDot = -1;
- int hasDot = 0;
- int lastHalfDot = 0;
- int shiftPatternLen;
-
- /* Initialize. */
- fg->len = strlen(pat);
- fg->bol = false;
- fg->eol = false;
- fg->reversed = false;
- fg->word = wflag;
-
- /* Remove end-of-line character ('$'). */
- if (fg->len > 0 && pat[fg->len - 1] == '$') {
- fg->eol = true;
- fg->len--;
- }
-
- /* Remove beginning-of-line character ('^'). */
- if (pat[0] == '^') {
- fg->bol = true;
- fg->len--;
- pat++;
- }
-
- if (fg->len >= 14 &&
- memcmp(pat, "[[:<:]]", 7) == 0 &&
- memcmp(pat + fg->len - 7, "[[:>:]]", 7) == 0) {
- fg->len -= 14;
- pat += 7;
- /* Word boundary is handled separately in util.c */
- fg->word = true;
- }
-
- /*
- * pat has been adjusted earlier to not include '^', '$' or
- * the word match character classes at the beginning and ending
- * of the string respectively.
- */
- fg->pattern = grep_malloc(fg->len + 1);
- memcpy(fg->pattern, pat, fg->len);
- fg->pattern[fg->len] = '\0';
-
- /* Look for ways to cheat...er...avoid the full regex engine. */
- for (i = 0; i < fg->len; i++) {
- /* Can still cheat? */
- if (fg->pattern[i] == '.') {
- hasDot = i;
- if (i < fg->len / 2) {
- if (firstHalfDot < 0)
- /* Closest dot to the beginning */
- firstHalfDot = i;
- } else {
- /* Closest dot to the end of the pattern. */
- lastHalfDot = i;
- if (firstLastHalfDot < 0)
- firstLastHalfDot = i;
- }
- } else {
- /* Free memory and let others know this is empty. */
- free(fg->pattern);
- fg->pattern = NULL;
- return (-1);
- }
- }
-
- /*
- * Determine if a reverse search would be faster based on the placement
- * of the dots.
- */
- if ((!(lflag || cflag)) && ((!(fg->bol || fg->eol)) &&
- ((lastHalfDot) && ((firstHalfDot < 0) ||
- ((fg->len - (lastHalfDot + 1)) < (size_t)firstHalfDot)))) &&
- !oflag && !color) {
- fg->reversed = true;
- hasDot = fg->len - (firstHalfDot < 0 ?
- firstLastHalfDot : firstHalfDot) - 1;
- grep_revstr(fg->pattern, fg->len);
- }
-
- /*
- * Normal Quick Search would require a shift based on the position the
- * next character after the comparison is within the pattern. With
- * wildcards, the position of the last dot effects the maximum shift
- * distance.
- * The closer to the end the wild card is the slower the search. A
- * reverse version of this algorithm would be useful for wildcards near
- * the end of the string.
- *
- * Examples:
- * Pattern Max shift
- * ------- ---------
- * this 5
- * .his 4
- * t.is 3
- * th.s 2
- * thi. 1
- */
-
- /* Adjust the shift based on location of the last dot ('.'). */
- shiftPatternLen = fg->len - hasDot;
-
- /* Preprocess pattern. */
- for (i = 0; i <= (signed)UCHAR_MAX; i++)
- fg->qsBc[i] = shiftPatternLen;
- for (i = hasDot + 1; i < fg->len; i++) {
- fg->qsBc[fg->pattern[i]] = fg->len - i;
- }
-
- /*
- * Put pattern back to normal after pre-processing to allow for easy
- * comparisons later.
- */
- if (fg->reversed)
- grep_revstr(fg->pattern, fg->len);
-
- return (0);
-}
-
-int
-grep_search(fastgrep_t *fg, const unsigned char *data, size_t len, regmatch_t *pmatch)
-{
- unsigned int j;
- int ret = REG_NOMATCH;
-
- if (pmatch->rm_so == (ssize_t)len)
- return (ret);
-
- if (fg->bol && pmatch->rm_so != 0) {
- pmatch->rm_so = len;
- pmatch->rm_eo = len;
- return (ret);
- }
-
- /* No point in going farther if we do not have enough data. */
- if (len < fg->len)
- return (ret);
-
- /* Only try once at the beginning or ending of the line. */
- if (fg->bol || fg->eol) {
- /* Simple text comparison. */
- /* Verify data is >= pattern length before searching on it. */
- if (len >= fg->len) {
- /* Determine where in data to start search at. */
- j = fg->eol ? len - fg->len : 0;
- if (!((fg->bol && fg->eol) && (len != fg->len)))
- if (grep_cmp(fg->pattern, data + j,
- fg->len) == -1) {
- pmatch->rm_so = j;
- pmatch->rm_eo = j + fg->len;
- ret = 0;
- }
- }
- } else if (fg->reversed) {
- /* Quick Search algorithm. */
- j = len;
- do {
- if (grep_cmp(fg->pattern, data + j - fg->len,
- fg->len) == -1) {
- pmatch->rm_so = j - fg->len;
- pmatch->rm_eo = j;
- ret = 0;
- break;
- }
- /* Shift if within bounds, otherwise, we are done. */
- if (j == fg->len)
- break;
- j -= fg->qsBc[data[j - fg->len - 1]];
- } while (j >= fg->len);
- } else {
- /* Quick Search algorithm. */
- j = pmatch->rm_so;
- do {
- if (grep_cmp(fg->pattern, data + j, fg->len) == -1) {
- pmatch->rm_so = j;
- pmatch->rm_eo = j + fg->len;
- ret = 0;
- break;
- }
-
- /* Shift if within bounds, otherwise, we are done. */
- if (j + fg->len == len)
- break;
- else
- j += fg->qsBc[data[j + fg->len]];
- } while (j <= (len - fg->len));
- }
-
- return (ret);
-}
-
-/*
- * Returns: i >= 0 on failure (position that it failed)
- * -1 on success
- */
-static inline int
-grep_cmp(const unsigned char *pat, const unsigned char *data, size_t len)
-{
- size_t size;
- wchar_t *wdata, *wpat;
- unsigned int i;
-
- if (iflag) {
- if ((size = mbstowcs(NULL, (const char *)data, 0)) ==
- ((size_t) - 1))
- return (-1);
-
- wdata = grep_malloc(size * sizeof(wint_t));
-
- if (mbstowcs(wdata, (const char *)data, size) ==
- ((size_t) - 1))
- return (-1);
-
- if ((size = mbstowcs(NULL, (const char *)pat, 0)) ==
- ((size_t) - 1))
- return (-1);
-
- wpat = grep_malloc(size * sizeof(wint_t));
-
- if (mbstowcs(wpat, (const char *)pat, size) == ((size_t) - 1))
- return (-1);
- for (i = 0; i < len; i++) {
- if ((towlower(wpat[i]) == towlower(wdata[i])) ||
- ((grepbehave != GREP_FIXED) && wpat[i] == L'.'))
- continue;
- free(wpat);
- free(wdata);
- return (i);
- }
- } else {
- for (i = 0; i < len; i++) {
- if ((pat[i] == data[i]) || ((grepbehave != GREP_FIXED) &&
- pat[i] == '.'))
- continue;
- return (i);
- }
- }
- return (-1);
-}
-
-static inline void
-grep_revstr(unsigned char *str, int len)
-{
- int i;
- char c;
-
- for (i = 0; i < len / 2; i++) {
- c = str[i];
- str[i] = str[len - i - 1];
- str[len - i - 1] = c;
- }
-}
diff --git a/toolbox/upstream-netbsd/usr.bin/grep/file.c b/toolbox/upstream-netbsd/usr.bin/grep/file.c
deleted file mode 100644
index 428bf58..0000000
--- a/toolbox/upstream-netbsd/usr.bin/grep/file.c
+++ /dev/null
@@ -1,276 +0,0 @@
-/* $NetBSD: file.c,v 1.10 2018/08/12 09:03:21 christos Exp $ */
-/* $FreeBSD: head/usr.bin/grep/file.c 211496 2010-08-19 09:28:59Z des $ */
-/* $OpenBSD: file.c,v 1.11 2010/07/02 20:48:48 nicm Exp $ */
-
-/*-
- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
- * Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
- * Copyright (C) 2010 Dimitry Andric <dimitry@andric.com>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
-#include <sys/cdefs.h>
-__RCSID("$NetBSD: file.c,v 1.10 2018/08/12 09:03:21 christos Exp $");
-
-#include <sys/param.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include <err.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "grep.h"
-
-#define MAXBUFSIZ (32 * 1024)
-#define LNBUFBUMP 80
-
-#ifndef WITHOUT_GZIP
-static gzFile gzbufdesc;
-#endif
-#ifndef WITHOUT_BZ2
-static BZFILE* bzbufdesc;
-#endif
-
-static unsigned char buffer[MAXBUFSIZ + 1];
-static unsigned char *bufpos;
-static size_t bufrem;
-
-static unsigned char *lnbuf;
-static size_t lnbuflen;
-
-static inline int
-grep_refill(struct file *f)
-{
- ssize_t nr = -1;
- int bzerr;
-
- bufpos = buffer;
- bufrem = 0;
-
-#ifndef WITHOUT_GZIP
- if (filebehave == FILE_GZIP) {
- nr = gzread(gzbufdesc, buffer, MAXBUFSIZ);
- if (nr == -1)
- return -1;
- }
-#endif
-#ifndef WITHOUT_BZ2
- if (filebehave == FILE_BZIP && bzbufdesc != NULL) {
- nr = BZ2_bzRead(&bzerr, bzbufdesc, buffer, MAXBUFSIZ);
- switch (bzerr) {
- case BZ_OK:
- case BZ_STREAM_END:
- /* No problem, nr will be okay */
- break;
- case BZ_DATA_ERROR_MAGIC:
- /*
- * As opposed to gzread(), which simply returns the
- * plain file data, if it is not in the correct
- * compressed format, BZ2_bzRead() instead aborts.
- *
- * So, just restart at the beginning of the file again,
- * and use plain reads from now on.
- */
- BZ2_bzReadClose(&bzerr, bzbufdesc);
- bzbufdesc = NULL;
- if (lseek(f->fd, 0, SEEK_SET) == -1)
- return (-1);
- nr = read(f->fd, buffer, MAXBUFSIZ);
- break;
- default:
- /* Make sure we exit with an error */
- nr = -1;
- }
- if (nr == -1)
- return -1;
- }
-#endif
- if (nr == -1) {
- nr = read(f->fd, buffer, MAXBUFSIZ);
- }
-
- if (nr < 0)
- return (-1);
-
- bufrem = nr;
- return (0);
-}
-
-static inline void
-grep_lnbufgrow(size_t newlen)
-{
-
- if (lnbuflen < newlen) {
- lnbuf = grep_realloc(lnbuf, newlen);
- lnbuflen = newlen;
- }
-}
-
-char *
-grep_fgetln(struct file *f, size_t *lenp)
-{
- unsigned char *p;
- char *ret;
- size_t len;
- size_t off;
- ptrdiff_t diff;
-
- /* Fill the buffer, if necessary */
- if (bufrem == 0 && grep_refill(f) != 0)
- goto error;
-
- if (bufrem == 0) {
- /* Return zero length to indicate EOF */
- *lenp = 0;
- return ((char *)bufpos);
- }
-
- /* Look for a newline in the remaining part of the buffer */
- if ((p = memchr(bufpos, line_sep, bufrem)) != NULL) {
- ++p; /* advance over newline */
- len = p - bufpos;
- grep_lnbufgrow(len + 1);
- memcpy(lnbuf, bufpos, len);
- lnbuf[len] = '\0';
- *lenp = len;
- bufrem -= len;
- bufpos = p;
- return ((char *)lnbuf);
- }
-
- /* We have to copy the current buffered data to the line buffer */
- for (len = bufrem, off = 0; ; len += bufrem) {
- /* Make sure there is room for more data */
- grep_lnbufgrow(len + LNBUFBUMP);
- memcpy(lnbuf + off, bufpos, len - off);
- lnbuf[len] = '\0';
- off = len;
- if (grep_refill(f) != 0)
- goto error;
- if (bufrem == 0)
- /* EOF: return partial line */
- break;
- if ((p = memchr(bufpos, line_sep, bufrem)) == NULL)
- continue;
- /* got it: finish up the line (like code above) */
- ++p;
- diff = p - bufpos;
- len += diff;
- grep_lnbufgrow(len + 1);
- memcpy(lnbuf + off, bufpos, diff);
- lnbuf[off + diff] = '\0';
- bufrem -= diff;
- bufpos = p;
- break;
- }
- *lenp = len;
- return ((char *)lnbuf);
-
-error:
- *lenp = 0;
- return (NULL);
-}
-
-static inline struct file *
-grep_file_init(struct file *f)
-{
-
-#ifndef WITHOUT_GZIP
- if (filebehave == FILE_GZIP &&
- (gzbufdesc = gzdopen(f->fd, "r")) == NULL)
- goto error;
-#endif
-
-#ifndef WITHOUT_BZ2
- if (filebehave == FILE_BZIP &&
- (bzbufdesc = BZ2_bzdopen(f->fd, "r")) == NULL)
- goto error;
-#endif
-
- /* Fill read buffer, also catches errors early */
- if (grep_refill(f) != 0)
- goto error;
-
- /* Check for binary stuff, if necessary */
- if (!nulldataflag && binbehave != BINFILE_TEXT &&
- memchr(bufpos, '\0', bufrem) != NULL)
- f->binary = true;
-
- return (f);
-error:
- close(f->fd);
- free(f);
- return (NULL);
-}
-
-/*
- * Opens a file for processing.
- */
-struct file *
-grep_open(const char *path)
-{
- struct file *f;
-
- f = grep_malloc(sizeof *f);
- memset(f, 0, sizeof *f);
- if (path == NULL) {
- /* Processing stdin implies --line-buffered. */
- lbflag = true;
- f->fd = STDIN_FILENO;
- } else if ((f->fd = open(path, O_RDONLY)) == -1) {
- free(f);
- return (NULL);
- }
-
- return (grep_file_init(f));
-}
-
-/*
- * Closes a file.
- */
-void
-grep_close(struct file *f)
-{
-
- close(f->fd);
-
- /* Reset read buffer and line buffer */
- bufpos = buffer;
- bufrem = 0;
-
- free(lnbuf);
- lnbuf = NULL;
- lnbuflen = 0;
-}
diff --git a/toolbox/upstream-netbsd/usr.bin/grep/grep.c b/toolbox/upstream-netbsd/usr.bin/grep/grep.c
deleted file mode 100644
index bad2a73..0000000
--- a/toolbox/upstream-netbsd/usr.bin/grep/grep.c
+++ /dev/null
@@ -1,722 +0,0 @@
-/* $NetBSD: grep.c,v 1.15 2018/08/12 09:03:21 christos Exp $ */
-/* $FreeBSD: head/usr.bin/grep/grep.c 211519 2010-08-19 22:55:17Z delphij $ */
-/* $OpenBSD: grep.c,v 1.42 2010/07/02 22:18:03 tedu Exp $ */
-
-/*-
- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
- * Copyright (C) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
-#include <sys/cdefs.h>
-__RCSID("$NetBSD: grep.c,v 1.15 2018/08/12 09:03:21 christos Exp $");
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <getopt.h>
-#include <limits.h>
-#include <libgen.h>
-#include <locale.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "grep.h"
-
-#ifndef WITHOUT_NLS
-#include <nl_types.h>
-nl_catd catalog;
-#endif
-
-/*
- * Default messags to use when NLS is disabled or no catalogue
- * is found.
- */
-const char *errstr[] = {
- "",
-/* 1*/ "(standard input)",
-/* 2*/ "cannot read bzip2 compressed file",
-/* 3*/ "unknown %s option",
-/* 4*/ "usage: %s [-abcDEFGHhIiJLlmnOoPqRSsUVvwxZz] [-A num] [-B num] [-C[num]]\n",
-/* 5*/ "\t[-e pattern] [-f file] [--binary-files=value] [--color=when]\n",
-/* 6*/ "\t[--context[=num]] [--directories=action] [--label] [--line-buffered]\n",
-/* 7*/ "\t[pattern] [file ...]\n",
-/* 8*/ "Binary file %s matches\n",
-/* 9*/ "%s (BSD grep) %s\n",
-};
-
-/* Flags passed to regcomp() and regexec() */
-int cflags = 0;
-int eflags = REG_STARTEND;
-
-/* Searching patterns */
-unsigned int patterns, pattern_sz;
-char **pattern;
-regex_t *r_pattern;
-fastgrep_t *fg_pattern;
-
-/* Filename exclusion/inclusion patterns */
-unsigned int fpatterns, fpattern_sz;
-unsigned int dpatterns, dpattern_sz;
-struct epat *dpattern, *fpattern;
-
-/* For regex errors */
-char re_error[RE_ERROR_BUF + 1];
-
-/* Command-line flags */
-unsigned long long Aflag; /* -A x: print x lines trailing each match */
-unsigned long long Bflag; /* -B x: print x lines leading each match */
-bool Hflag; /* -H: always print file name */
-bool Lflag; /* -L: only show names of files with no matches */
-bool bflag; /* -b: show block numbers for each match */
-bool cflag; /* -c: only show a count of matching lines */
-bool hflag; /* -h: don't print filename headers */
-bool iflag; /* -i: ignore case */
-bool lflag; /* -l: only show names of files with matches */
-bool mflag; /* -m x: stop reading the files after x matches */
-unsigned long long mcount; /* count for -m */
-bool nflag; /* -n: show line numbers in front of matching lines */
-bool oflag; /* -o: print only matching part */
-bool qflag; /* -q: quiet mode (don't output anything) */
-bool sflag; /* -s: silent mode (ignore errors) */
-bool vflag; /* -v: only show non-matching lines */
-bool wflag; /* -w: pattern must start and end on word boundaries */
-bool xflag; /* -x: pattern must match entire line */
-bool lbflag; /* --line-buffered */
-bool nullflag; /* --null */
-bool nulldataflag; /* --null-data */
-unsigned char line_sep = '\n'; /* 0 for --null-data */
-char *label; /* --label */
-const char *color; /* --color */
-int grepbehave = GREP_BASIC; /* -EFGP: type of the regex */
-int binbehave = BINFILE_BIN; /* -aIU: handling of binary files */
-int filebehave = FILE_STDIO; /* -JZ: normal, gzip or bzip2 file */
-int devbehave = DEV_READ; /* -D: handling of devices */
-int dirbehave = DIR_READ; /* -dRr: handling of directories */
-int linkbehave = LINK_READ; /* -OpS: handling of symlinks */
-
-bool dexclude, dinclude; /* --exclude-dir and --include-dir */
-bool fexclude, finclude; /* --exclude and --include */
-
-enum {
- BIN_OPT = CHAR_MAX + 1,
- COLOR_OPT,
- DECOMPRESS_OPT,
- HELP_OPT,
- MMAP_OPT,
- LINEBUF_OPT,
- LABEL_OPT,
- R_EXCLUDE_OPT,
- R_INCLUDE_OPT,
- R_DEXCLUDE_OPT,
- R_DINCLUDE_OPT
-};
-
-static inline const char *init_color(const char *);
-
-/* Housekeeping */
-int tail; /* lines left to print */
-bool notfound; /* file not found */
-
-extern char *__progname;
-
-/*
- * Prints usage information and returns 2.
- */
-__dead static void
-usage(void)
-{
- fprintf(stderr, getstr(4), __progname);
- fprintf(stderr, "%s", getstr(5));
- fprintf(stderr, "%s", getstr(6));
- fprintf(stderr, "%s", getstr(7));
- exit(2);
-}
-
-static const char optstr[] =
- "0123456789A:B:C:D:EFGHIJLOPSRUVZabcd:e:f:hilm:nopqrsuvwxyz";
-
-struct option long_options[] =
-{
- {"binary-files", required_argument, NULL, BIN_OPT},
-#ifndef WITHOUT_GZIP
- {"decompress", no_argument, NULL, DECOMPRESS_OPT},
-#endif
- {"help", no_argument, NULL, HELP_OPT},
- {"mmap", no_argument, NULL, MMAP_OPT},
- {"line-buffered", no_argument, NULL, LINEBUF_OPT},
- {"label", required_argument, NULL, LABEL_OPT},
- {"color", optional_argument, NULL, COLOR_OPT},
- {"colour", optional_argument, NULL, COLOR_OPT},
- {"exclude", required_argument, NULL, R_EXCLUDE_OPT},
- {"include", required_argument, NULL, R_INCLUDE_OPT},
- {"exclude-dir", required_argument, NULL, R_DEXCLUDE_OPT},
- {"include-dir", required_argument, NULL, R_DINCLUDE_OPT},
- {"after-context", required_argument, NULL, 'A'},
- {"text", no_argument, NULL, 'a'},
- {"before-context", required_argument, NULL, 'B'},
- {"byte-offset", no_argument, NULL, 'b'},
- {"context", optional_argument, NULL, 'C'},
- {"count", no_argument, NULL, 'c'},
- {"devices", required_argument, NULL, 'D'},
- {"directories", required_argument, NULL, 'd'},
- {"extended-regexp", no_argument, NULL, 'E'},
- {"regexp", required_argument, NULL, 'e'},
- {"fixed-strings", no_argument, NULL, 'F'},
- {"file", required_argument, NULL, 'f'},
- {"basic-regexp", no_argument, NULL, 'G'},
- {"no-filename", no_argument, NULL, 'h'},
- {"with-filename", no_argument, NULL, 'H'},
- {"ignore-case", no_argument, NULL, 'i'},
-#ifndef WITHOUT_BZ2
- {"bz2decompress", no_argument, NULL, 'J'},
-#endif
- {"files-with-matches", no_argument, NULL, 'l'},
- {"files-without-match", no_argument, NULL, 'L'},
- {"max-count", required_argument, NULL, 'm'},
- {"line-number", no_argument, NULL, 'n'},
- {"only-matching", no_argument, NULL, 'o'},
- {"quiet", no_argument, NULL, 'q'},
- {"silent", no_argument, NULL, 'q'},
- {"recursive", no_argument, NULL, 'r'},
- {"no-messages", no_argument, NULL, 's'},
- {"binary", no_argument, NULL, 'U'},
- {"unix-byte-offsets", no_argument, NULL, 'u'},
- {"invert-match", no_argument, NULL, 'v'},
- {"version", no_argument, NULL, 'V'},
- {"word-regexp", no_argument, NULL, 'w'},
- {"line-regexp", no_argument, NULL, 'x'},
- {"null", no_argument, NULL, 'Z'},
- {"null-data", no_argument, NULL, 'z'},
- {NULL, no_argument, NULL, 0}
-};
-
-/*
- * Adds a searching pattern to the internal array.
- */
-static void
-add_pattern(char *pat, size_t len)
-{
-
- /* TODO: Check for empty patterns and shortcut */
-
- /* Increase size if necessary */
- if (patterns == pattern_sz) {
- pattern_sz *= 2;
- pattern = grep_realloc(pattern, ++pattern_sz *
- sizeof(*pattern));
- }
- if (len > 0 && pat[len - 1] == '\n')
- --len;
- /* pat may not be NUL-terminated */
- pattern[patterns] = grep_malloc(len + 1);
- memcpy(pattern[patterns], pat, len);
- pattern[patterns][len] = '\0';
- ++patterns;
-}
-
-/*
- * Adds a file include/exclude pattern to the internal array.
- */
-static void
-add_fpattern(const char *pat, int mode)
-{
-
- /* Increase size if necessary */
- if (fpatterns == fpattern_sz) {
- fpattern_sz *= 2;
- fpattern = grep_realloc(fpattern, ++fpattern_sz *
- sizeof(struct epat));
- }
- fpattern[fpatterns].pat = grep_strdup(pat);
- fpattern[fpatterns].mode = mode;
- ++fpatterns;
-}
-
-/*
- * Adds a directory include/exclude pattern to the internal array.
- */
-static void
-add_dpattern(const char *pat, int mode)
-{
-
- /* Increase size if necessary */
- if (dpatterns == dpattern_sz) {
- dpattern_sz *= 2;
- dpattern = grep_realloc(dpattern, ++dpattern_sz *
- sizeof(struct epat));
- }
- dpattern[dpatterns].pat = grep_strdup(pat);
- dpattern[dpatterns].mode = mode;
- ++dpatterns;
-}
-
-/*
- * Reads searching patterns from a file and adds them with add_pattern().
- */
-static void
-read_patterns(const char *fn)
-{
- FILE *f;
- char *line;
- size_t len;
- ssize_t rlen;
-
- if ((f = fopen(fn, "r")) == NULL)
- err(2, "%s", fn);
- line = NULL;
- len = 0;
- while ((rlen = getline(&line, &len, f)) != -1)
- add_pattern(line, *line == '\n' ? 0 : (size_t)rlen);
- free(line);
- if (ferror(f))
- err(2, "%s", fn);
- fclose(f);
-}
-
-static inline const char *
-init_color(const char *d)
-{
- char *c;
-
- c = getenv("GREP_COLOR");
- return (c != NULL ? c : d);
-}
-
-int
-main(int argc, char *argv[])
-{
- char **aargv, **eargv, *eopts;
- char *ep;
- unsigned long long l;
- unsigned int aargc, eargc, i, j;
- int c, lastc, needpattern, newarg, prevoptind;
-
- setlocale(LC_ALL, "");
-
-#ifndef WITHOUT_NLS
- catalog = catopen("grep", NL_CAT_LOCALE);
-#endif
-
- /* Check what is the program name of the binary. In this
- way we can have all the funcionalities in one binary
- without the need of scripting and using ugly hacks. */
- switch (__progname[0]) {
- case 'e':
- grepbehave = GREP_EXTENDED;
- break;
- case 'f':
- grepbehave = GREP_FIXED;
- break;
- case 'g':
- grepbehave = GREP_BASIC;
- break;
-#ifndef WITHOUT_GZIP
- case 'z':
- filebehave = FILE_GZIP;
- switch(__progname[1]) {
- case 'e':
- grepbehave = GREP_EXTENDED;
- break;
- case 'f':
- grepbehave = GREP_FIXED;
- break;
- case 'g':
- grepbehave = GREP_BASIC;
- break;
- }
- break;
-#endif
- }
-
- lastc = '\0';
- newarg = 1;
- prevoptind = 1;
- needpattern = 1;
-
- eopts = getenv("GREP_OPTIONS");
-
- /* support for extra arguments in GREP_OPTIONS */
- eargc = 0;
- if (eopts != NULL) {
- char *str;
-
- /* make an estimation of how many extra arguments we have */
- for (j = 0; j < strlen(eopts); j++)
- if (eopts[j] == ' ')
- eargc++;
-
- eargv = (char **)grep_malloc(sizeof(char *) * (eargc + 1));
-
- eargc = 0;
- /* parse extra arguments */
- while ((str = strsep(&eopts, " ")) != NULL)
- eargv[eargc++] = grep_strdup(str);
-
- aargv = (char **)grep_calloc(eargc + argc + 1,
- sizeof(char *));
-
- aargv[0] = argv[0];
- for (i = 0; i < eargc; i++)
- aargv[i + 1] = eargv[i];
- for (j = 1; j < (unsigned int)argc; j++, i++)
- aargv[i + 1] = argv[j];
-
- aargc = eargc + argc;
- } else {
- aargv = argv;
- aargc = argc;
- }
-
- while (((c = getopt_long(aargc, aargv, optstr, long_options, NULL)) !=
- -1)) {
- switch (c) {
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (newarg || !isdigit(lastc))
- Aflag = 0;
- else if (Aflag > LLONG_MAX / 10) {
- errno = ERANGE;
- err(2, NULL);
- }
- Aflag = Bflag = (Aflag * 10) + (c - '0');
- break;
- case 'C':
- if (optarg == NULL) {
- Aflag = Bflag = 2;
- break;
- }
- /* FALLTHROUGH */
- case 'A':
- /* FALLTHROUGH */
- case 'B':
- errno = 0;
- l = strtoull(optarg, &ep, 10);
- if (((errno == ERANGE) && (l == ULLONG_MAX)) ||
- ((errno == EINVAL) && (l == 0)))
- err(2, NULL);
- else if (ep[0] != '\0') {
- errno = EINVAL;
- err(2, NULL);
- }
- if (c == 'A')
- Aflag = l;
- else if (c == 'B')
- Bflag = l;
- else
- Aflag = Bflag = l;
- break;
- case 'a':
- binbehave = BINFILE_TEXT;
- break;
- case 'b':
- bflag = true;
- break;
- case 'c':
- cflag = true;
- break;
- case 'D':
- if (strcasecmp(optarg, "skip") == 0)
- devbehave = DEV_SKIP;
- else if (strcasecmp(optarg, "read") == 0)
- devbehave = DEV_READ;
- else
- errx(2, getstr(3), "--devices");
- break;
- case 'd':
- if (strcasecmp("recurse", optarg) == 0) {
- Hflag = true;
- dirbehave = DIR_RECURSE;
- } else if (strcasecmp("skip", optarg) == 0)
- dirbehave = DIR_SKIP;
- else if (strcasecmp("read", optarg) == 0)
- dirbehave = DIR_READ;
- else
- errx(2, getstr(3), "--directories");
- break;
- case 'E':
- grepbehave = GREP_EXTENDED;
- break;
- case 'e':
- add_pattern(optarg, strlen(optarg));
- needpattern = 0;
- break;
- case 'F':
- grepbehave = GREP_FIXED;
- break;
- case 'f':
- read_patterns(optarg);
- needpattern = 0;
- break;
- case 'G':
- grepbehave = GREP_BASIC;
- break;
- case 'H':
- Hflag = true;
- break;
- case 'h':
- Hflag = false;
- hflag = true;
- break;
- case 'I':
- binbehave = BINFILE_SKIP;
- break;
- case 'i':
- case 'y':
- iflag = true;
- cflags |= REG_ICASE;
- break;
-#ifndef WITHOUT_BZ2
- case 'J':
- filebehave = FILE_BZIP;
- break;
-#endif
- case 'L':
- lflag = false;
- Lflag = true;
- break;
- case 'l':
- Lflag = false;
- lflag = true;
- break;
- case 'm':
- mflag = true;
- errno = 0;
- mcount = strtoull(optarg, &ep, 10);
- if (((errno == ERANGE) && (mcount == ULLONG_MAX)) ||
- ((errno == EINVAL) && (mcount == 0)))
- err(2, NULL);
- else if (ep[0] != '\0') {
- errno = EINVAL;
- err(2, NULL);
- }
- break;
- case 'n':
- nflag = true;
- break;
- case 'O':
- linkbehave = LINK_EXPLICIT;
- break;
- case 'o':
- oflag = true;
- break;
- case 'p':
- linkbehave = LINK_SKIP;
- break;
- case 'q':
- qflag = true;
- break;
- case 'S':
- linkbehave = LINK_READ;
- break;
- case 'R':
- case 'r':
- dirbehave = DIR_RECURSE;
- Hflag = true;
- break;
- case 's':
- sflag = true;
- break;
- case 'U':
- binbehave = BINFILE_BIN;
- break;
- case 'u':
- case MMAP_OPT:
- /* noop, compatibility */
- break;
- case 'V':
- printf(getstr(9), __progname, VERSION);
- exit(0);
- case 'v':
- vflag = true;
- break;
- case 'w':
- wflag = true;
- break;
- case 'x':
- xflag = true;
- break;
- case 'Z':
- nullflag = true;
- break;
- case 'z':
- nulldataflag = true;
- line_sep = '\0';
- break;
- case BIN_OPT:
- if (strcasecmp("binary", optarg) == 0)
- binbehave = BINFILE_BIN;
- else if (strcasecmp("without-match", optarg) == 0)
- binbehave = BINFILE_SKIP;
- else if (strcasecmp("text", optarg) == 0)
- binbehave = BINFILE_TEXT;
- else
- errx(2, getstr(3), "--binary-files");
- break;
- case COLOR_OPT:
- color = NULL;
- if (optarg == NULL || strcasecmp("auto", optarg) == 0 ||
- strcasecmp("tty", optarg) == 0 ||
- strcasecmp("if-tty", optarg) == 0) {
- char *term;
-
- term = getenv("TERM");
- if (isatty(STDOUT_FILENO) && term != NULL &&
- strcasecmp(term, "dumb") != 0)
- color = init_color("01;31");
- } else if (strcasecmp("always", optarg) == 0 ||
- strcasecmp("yes", optarg) == 0 ||
- strcasecmp("force", optarg) == 0) {
- color = init_color("01;31");
- } else if (strcasecmp("never", optarg) != 0 &&
- strcasecmp("none", optarg) != 0 &&
- strcasecmp("no", optarg) != 0)
- errx(2, getstr(3), "--color");
- break;
-#ifndef WITHOUT_GZIP
- case DECOMPRESS_OPT:
- filebehave = FILE_GZIP;
- break;
-#endif
- case LABEL_OPT:
- label = optarg;
- break;
- case LINEBUF_OPT:
- lbflag = true;
- break;
- case R_INCLUDE_OPT:
- finclude = true;
- add_fpattern(optarg, INCL_PAT);
- break;
- case R_EXCLUDE_OPT:
- fexclude = true;
- add_fpattern(optarg, EXCL_PAT);
- break;
- case R_DINCLUDE_OPT:
- dinclude = true;
- add_dpattern(optarg, INCL_PAT);
- break;
- case R_DEXCLUDE_OPT:
- dexclude = true;
- add_dpattern(optarg, EXCL_PAT);
- break;
- case HELP_OPT:
- default:
- usage();
- }
- lastc = c;
- newarg = optind != prevoptind;
- prevoptind = optind;
- }
- aargc -= optind;
- aargv += optind;
-
- /* Fail if we don't have any pattern */
- if (aargc == 0 && needpattern)
- usage();
-
- /* Process patterns from command line */
- if (aargc != 0 && needpattern) {
- add_pattern(*aargv, strlen(*aargv));
- --aargc;
- ++aargv;
- }
-
- switch (grepbehave) {
- case GREP_FIXED:
- case GREP_BASIC:
- break;
- case GREP_EXTENDED:
- cflags |= REG_EXTENDED;
- break;
- default:
- /* NOTREACHED */
- usage();
- }
-
- fg_pattern = grep_calloc(patterns, sizeof(*fg_pattern));
- r_pattern = grep_calloc(patterns, sizeof(*r_pattern));
-/*
- * XXX: fgrepcomp() and fastcomp() are workarounds for regexec() performance.
- * Optimizations should be done there.
- */
- /* Check if cheating is allowed (always is for fgrep). */
- if (grepbehave == GREP_FIXED) {
- for (i = 0; i < patterns; ++i)
- fgrepcomp(&fg_pattern[i], pattern[i]);
- } else {
- for (i = 0; i < patterns; ++i) {
- if (fastcomp(&fg_pattern[i], pattern[i])) {
- /* Fall back to full regex library */
- c = regcomp(&r_pattern[i], pattern[i], cflags);
- if (c != 0) {
- regerror(c, &r_pattern[i], re_error,
- RE_ERROR_BUF);
- errx(2, "%s", re_error);
- }
- }
- }
- }
-
- if (lbflag) {
-#ifdef _IOLBF
- setvbuf(stdout, NULL, _IOLBF, 0);
-#else
- setlinebuf(stdout);
-#endif
- }
-
- if ((aargc == 0 || aargc == 1) && !Hflag)
- hflag = true;
-
- if (aargc == 0)
- exit(!procfile("-"));
-
- if (dirbehave == DIR_RECURSE)
- c = grep_tree(aargv);
- else
- for (c = 0; aargc--; ++aargv) {
- if ((finclude || fexclude) && !file_matching(*aargv))
- continue;
- c+= procfile(*aargv);
- }
-
-#ifndef WITHOUT_NLS
- catclose(catalog);
-#endif
-
- /* Find out the correct return value according to the
- results and the command line option. */
- exit(c ? (notfound ? (qflag ? 0 : 2) : 0) : (notfound ? 2 : 1));
-}
diff --git a/toolbox/upstream-netbsd/usr.bin/grep/grep.h b/toolbox/upstream-netbsd/usr.bin/grep/grep.h
deleted file mode 100644
index b7ef7fa..0000000
--- a/toolbox/upstream-netbsd/usr.bin/grep/grep.h
+++ /dev/null
@@ -1,162 +0,0 @@
-/* $NetBSD: grep.h,v 1.10 2018/08/12 09:03:21 christos Exp $ */
-/* $OpenBSD: grep.h,v 1.15 2010/04/05 03:03:55 tedu Exp $ */
-/* $FreeBSD: head/usr.bin/grep/grep.h 211496 2010-08-19 09:28:59Z des $ */
-
-/*-
- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
- * Copyright (c) 2008-2009 Gabor Kovesdan <gabor@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef WITHOUT_BZ2
-#include <bzlib.h>
-#endif
-#include <limits.h>
-#include <regex.h>
-#include <stdbool.h>
-#include <stdio.h>
-#ifndef WITHOUT_GZIP
-#include <zlib.h>
-#endif
-
-#ifdef WITHOUT_NLS
-#define getstr(n) errstr[n]
-#else
-#include <nl_types.h>
-
-extern nl_catd catalog;
-#define getstr(n) catgets(catalog, 1, n, errstr[n])
-#endif
-
-extern const char *errstr[];
-
-#define VERSION "2.5.1-FreeBSD"
-
-#define GREP_FIXED 0
-#define GREP_BASIC 1
-#define GREP_EXTENDED 2
-
-#define BINFILE_BIN 0
-#define BINFILE_SKIP 1
-#define BINFILE_TEXT 2
-
-#define FILE_STDIO 0
-#define FILE_GZIP 1
-#define FILE_BZIP 2
-
-#define DIR_READ 0
-#define DIR_SKIP 1
-#define DIR_RECURSE 2
-
-#define DEV_READ 0
-#define DEV_SKIP 1
-
-#define LINK_READ 0
-#define LINK_EXPLICIT 1
-#define LINK_SKIP 2
-
-#define EXCL_PAT 0
-#define INCL_PAT 1
-
-#define MAX_LINE_MATCHES 32
-
-struct file {
- int fd;
- bool binary;
-};
-
-struct str {
- off_t off;
- size_t len;
- char *dat;
- char *file;
- int line_no;
-};
-
-struct epat {
- char *pat;
- int mode;
-};
-
-typedef struct {
- size_t len;
- unsigned char *pattern;
- int qsBc[UCHAR_MAX + 1];
- /* flags */
- bool bol;
- bool eol;
- bool reversed;
- bool word;
-} fastgrep_t;
-
-/* Flags passed to regcomp() and regexec() */
-extern int cflags, eflags;
-
-/* Command line flags */
-extern bool Eflag, Fflag, Gflag, Hflag, Lflag,
- bflag, cflag, hflag, iflag, lflag, mflag, nflag, oflag,
- qflag, sflag, vflag, wflag, xflag;
-extern bool dexclude, dinclude, fexclude, finclude, lbflag, nullflag, nulldataflag;
-extern unsigned char line_sep;
-extern unsigned long long Aflag, Bflag, mcount;
-extern char *label;
-extern const char *color;
-extern int binbehave, devbehave, dirbehave, filebehave, grepbehave, linkbehave;
-
-extern bool notfound;
-extern int tail;
-extern unsigned int dpatterns, fpatterns, patterns;
-extern char **pattern;
-extern struct epat *dpattern, *fpattern;
-extern regex_t *er_pattern, *r_pattern;
-extern fastgrep_t *fg_pattern;
-
-/* For regex errors */
-#define RE_ERROR_BUF 512
-extern char re_error[RE_ERROR_BUF + 1]; /* Seems big enough */
-
-/* util.c */
-bool file_matching(const char *fname);
-int procfile(const char *fn);
-int grep_tree(char **argv);
-void *grep_malloc(size_t size);
-void *grep_calloc(size_t nmemb, size_t size);
-void *grep_realloc(void *ptr, size_t size);
-char *grep_strdup(const char *str);
-void printline(struct str *line, int sep, regmatch_t *matches, int m);
-
-/* queue.c */
-void enqueue(struct str *x);
-void printqueue(void);
-void clearqueue(void);
-
-/* file.c */
-void grep_close(struct file *f);
-struct file *grep_open(const char *path);
-char *grep_fgetln(struct file *f, size_t *len);
-
-/* fastgrep.c */
-int fastcomp(fastgrep_t *, const char *);
-void fgrepcomp(fastgrep_t *, const char *);
-int grep_search(fastgrep_t *, const unsigned char *, size_t, regmatch_t *);
diff --git a/toolbox/upstream-netbsd/usr.bin/grep/queue.c b/toolbox/upstream-netbsd/usr.bin/grep/queue.c
deleted file mode 100644
index e3c6be1..0000000
--- a/toolbox/upstream-netbsd/usr.bin/grep/queue.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/* $NetBSD: queue.c,v 1.5 2011/08/31 16:24:57 plunky Exp $ */
-/* $FreeBSD: head/usr.bin/grep/queue.c 211496 2010-08-19 09:28:59Z des $ */
-/*-
- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * A really poor man's queue. It does only what it has to and gets out of
- * Dodge. It is used in place of <sys/queue.h> to get a better performance.
- */
-
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
-#include <sys/cdefs.h>
-__RCSID("$NetBSD: queue.c,v 1.5 2011/08/31 16:24:57 plunky Exp $");
-
-#include <sys/param.h>
-#include <sys/queue.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "grep.h"
-
-struct qentry {
- STAILQ_ENTRY(qentry) list;
- struct str data;
-};
-
-static STAILQ_HEAD(, qentry) queue = STAILQ_HEAD_INITIALIZER(queue);
-static unsigned long long count;
-
-static struct qentry *dequeue(void);
-
-void
-enqueue(struct str *x)
-{
- struct qentry *item;
-
- item = grep_malloc(sizeof(struct qentry));
- item->data.dat = grep_malloc(sizeof(char) * x->len);
- item->data.len = x->len;
- item->data.line_no = x->line_no;
- item->data.off = x->off;
- memcpy(item->data.dat, x->dat, x->len);
- item->data.file = x->file;
-
- STAILQ_INSERT_TAIL(&queue, item, list);
-
- if (++count > Bflag) {
- item = dequeue();
- free(item->data.dat);
- free(item);
- }
-}
-
-static struct qentry *
-dequeue(void)
-{
- struct qentry *item;
-
- item = STAILQ_FIRST(&queue);
- if (item == NULL)
- return (NULL);
-
- STAILQ_REMOVE_HEAD(&queue, list);
- --count;
- return (item);
-}
-
-void
-printqueue(void)
-{
- struct qentry *item;
-
- while ((item = dequeue()) != NULL) {
- printline(&item->data, '-', NULL, 0);
- free(item->data.dat);
- free(item);
- }
-}
-
-void
-clearqueue(void)
-{
- struct qentry *item;
-
- while ((item = dequeue()) != NULL) {
- free(item->data.dat);
- free(item);
- }
-}
diff --git a/toolbox/upstream-netbsd/usr.bin/grep/util.c b/toolbox/upstream-netbsd/usr.bin/grep/util.c
deleted file mode 100644
index a3c9e4c..0000000
--- a/toolbox/upstream-netbsd/usr.bin/grep/util.c
+++ /dev/null
@@ -1,500 +0,0 @@
-/* $NetBSD: util.c,v 1.19 2018/02/05 22:14:26 mrg Exp $ */
-/* $FreeBSD: head/usr.bin/grep/util.c 211496 2010-08-19 09:28:59Z des $ */
-/* $OpenBSD: util.c,v 1.39 2010/07/02 22:18:03 tedu Exp $ */
-
-/*-
- * Copyright (c) 1999 James Howard and Dag-Erling Coïdan Smørgrav
- * Copyright (C) 2008-2010 Gabor Kovesdan <gabor@FreeBSD.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if HAVE_NBTOOL_CONFIG_H
-#include "nbtool_config.h"
-#endif
-
-#include <sys/cdefs.h>
-__RCSID("$NetBSD: util.c,v 1.19 2018/02/05 22:14:26 mrg Exp $");
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <ctype.h>
-#include <err.h>
-#include <errno.h>
-#include <fnmatch.h>
-#include <fts.h>
-#include <libgen.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <wchar.h>
-#include <wctype.h>
-
-#include "grep.h"
-
-static bool first, first_global = true;
-static unsigned long long since_printed;
-
-static int procline(struct str *l, int);
-
-bool
-file_matching(const char *fname)
-{
- char *fname_base, *fname_copy;
- unsigned int i;
- bool ret;
-
- ret = finclude ? false : true;
- fname_copy = grep_strdup(fname);
- fname_base = basename(fname_copy);
-
- for (i = 0; i < fpatterns; ++i) {
- if (fnmatch(fpattern[i].pat, fname, 0) == 0 ||
- fnmatch(fpattern[i].pat, fname_base, 0) == 0) {
- if (fpattern[i].mode == EXCL_PAT) {
- free(fname_copy);
- return (false);
- } else
- ret = true;
- }
- }
- free(fname_copy);
- return (ret);
-}
-
-static inline bool
-dir_matching(const char *dname)
-{
- unsigned int i;
- bool ret;
-
- ret = dinclude ? false : true;
-
- for (i = 0; i < dpatterns; ++i) {
- if (dname != NULL &&
- fnmatch(dname, dpattern[i].pat, 0) == 0) {
- if (dpattern[i].mode == EXCL_PAT)
- return (false);
- else
- ret = true;
- }
- }
- return (ret);
-}
-
-/*
- * Processes a directory when a recursive search is performed with
- * the -R option. Each appropriate file is passed to procfile().
- */
-int
-grep_tree(char **argv)
-{
- FTS *fts;
- FTSENT *p;
- char *d, *dir = NULL;
- int c, fts_flags;
- bool ok;
-
- c = fts_flags = 0;
-
- switch(linkbehave) {
- case LINK_EXPLICIT:
- fts_flags = FTS_COMFOLLOW;
- break;
- case LINK_SKIP:
- fts_flags = FTS_PHYSICAL;
- break;
- default:
- fts_flags = FTS_LOGICAL;
-
- }
-
- fts_flags |= FTS_NOSTAT | FTS_NOCHDIR;
-
- if (!(fts = fts_open(argv, fts_flags, NULL)))
- err(2, "fts_open");
- while ((p = fts_read(fts)) != NULL) {
- switch (p->fts_info) {
- case FTS_DNR:
- /* FALLTHROUGH */
- case FTS_ERR:
- errx(2, "%s: %s", p->fts_path, strerror(p->fts_errno));
- break;
- case FTS_D:
- /* FALLTHROUGH */
- case FTS_DP:
- break;
- case FTS_DC:
- /* Print a warning for recursive directory loop */
- warnx("warning: %s: recursive directory loop",
- p->fts_path);
- break;
- default:
- /* Check for file exclusion/inclusion */
- ok = true;
- if (dexclude || dinclude) {
- if ((d = strrchr(p->fts_path, '/')) != NULL) {
- dir = grep_malloc(sizeof(char) *
- (d - p->fts_path + 1));
- memcpy(dir, p->fts_path,
- d - p->fts_path);
- dir[d - p->fts_path] = '\0';
- }
- ok = dir_matching(dir);
- free(dir);
- dir = NULL;
- }
- if (fexclude || finclude)
- ok &= file_matching(p->fts_path);
-
- if (ok)
- c += procfile(p->fts_path);
- break;
- }
- }
-
- fts_close(fts);
- return (c);
-}
-
-/*
- * Opens a file and processes it. Each file is processed line-by-line
- * passing the lines to procline().
- */
-int
-procfile(const char *fn)
-{
- struct file *f;
- struct stat sb;
- struct str ln;
- mode_t s;
- int c, t;
-
- if (mflag && (mcount <= 0))
- return (0);
-
- if (strcmp(fn, "-") == 0) {
- fn = label != NULL ? label : getstr(1);
- f = grep_open(NULL);
- } else {
- if (!stat(fn, &sb)) {
- /* Check if we need to process the file */
- s = sb.st_mode & S_IFMT;
- if (s == S_IFDIR && dirbehave == DIR_SKIP)
- return (0);
- if ((s == S_IFIFO || s == S_IFCHR || s == S_IFBLK
- || s == S_IFSOCK) && devbehave == DEV_SKIP)
- return (0);
- }
- f = grep_open(fn);
- }
- if (f == NULL) {
- if (!sflag)
- warn("%s", fn);
- if (errno == ENOENT)
- notfound = true;
- return (0);
- }
-
- ln.file = grep_malloc(strlen(fn) + 1);
- strcpy(ln.file, fn);
- ln.line_no = 0;
- ln.len = 0;
- tail = 0;
- ln.off = -1;
-
- for (first = true, c = 0; c == 0 || !(lflag || qflag); ) {
- ln.off += ln.len + 1;
- if ((ln.dat = grep_fgetln(f, &ln.len)) == NULL || ln.len == 0)
- break;
- if (ln.len > 0 && ln.dat[ln.len - 1] == line_sep)
- --ln.len;
- ln.line_no++;
-
- /* Return if we need to skip a binary file */
- if (f->binary && binbehave == BINFILE_SKIP) {
- grep_close(f);
- free(ln.file);
- free(f);
- return (0);
- }
- /* Process the file line-by-line */
- t = procline(&ln, f->binary);
- c += t;
-
- /* Count the matches if we have a match limit */
- if (mflag) {
- mcount -= t;
- if (mcount <= 0)
- break;
- }
- }
- if (Bflag > 0)
- clearqueue();
- grep_close(f);
-
- if (cflag) {
- if (!hflag)
- printf("%s:", ln.file);
- printf("%u%c", c, line_sep);
- }
- if (lflag && !qflag && c != 0)
- printf("%s%c", fn, line_sep);
- if (Lflag && !qflag && c == 0)
- printf("%s%c", fn, line_sep);
- if (c && !cflag && !lflag && !Lflag &&
- binbehave == BINFILE_BIN && f->binary && !qflag)
- printf(getstr(8), fn);
-
- free(ln.file);
- free(f);
- return (c);
-}
-
-#define iswword(x) (iswalnum((x)) || (x) == L'_')
-
-/*
- * Processes a line comparing it with the specified patterns. Each pattern
- * is looped to be compared along with the full string, saving each and every
- * match, which is necessary to colorize the output and to count the
- * matches. The matching lines are passed to printline() to display the
- * appropriate output.
- */
-static int
-procline(struct str *l, int nottext)
-{
- regmatch_t matches[MAX_LINE_MATCHES];
- regmatch_t pmatch;
- size_t st = 0;
- unsigned int i;
- int c = 0, m = 0, r = 0;
-
- /* Loop to process the whole line */
- while (st <= l->len) {
- pmatch.rm_so = st;
- pmatch.rm_eo = l->len;
-
- /* Loop to compare with all the patterns */
- for (i = 0; i < patterns; i++) {
-/*
- * XXX: grep_search() is a workaround for speed up and should be
- * removed in the future. See fastgrep.c.
- */
- if (fg_pattern[i].pattern) {
- r = grep_search(&fg_pattern[i],
- (unsigned char *)l->dat,
- l->len, &pmatch);
- r = (r == 0) ? 0 : REG_NOMATCH;
- st = pmatch.rm_eo;
- } else {
- r = regexec(&r_pattern[i], l->dat, 1,
- &pmatch, eflags);
- r = (r == 0) ? 0 : REG_NOMATCH;
- st = pmatch.rm_eo;
- }
- if (r == REG_NOMATCH)
- continue;
- /* Check for full match */
- if (xflag &&
- (pmatch.rm_so != 0 ||
- (size_t)pmatch.rm_eo != l->len))
- continue;
- /* Check for whole word match */
- if (fg_pattern[i].word && pmatch.rm_so != 0) {
- wchar_t wbegin, wend;
-
- wbegin = wend = L' ';
- if (pmatch.rm_so != 0 &&
- sscanf(&l->dat[pmatch.rm_so - 1],
- "%lc", &wbegin) != 1)
- continue;
- if ((size_t)pmatch.rm_eo != l->len &&
- sscanf(&l->dat[pmatch.rm_eo],
- "%lc", &wend) != 1)
- continue;
- if (iswword(wbegin) || iswword(wend))
- continue;
- }
- c = 1;
- if (m < MAX_LINE_MATCHES)
- matches[m++] = pmatch;
- /* matches - skip further patterns */
- if ((color != NULL && !oflag) || qflag || lflag)
- break;
- }
-
- if (vflag) {
- c = !c;
- break;
- }
- /* One pass if we are not recording matches */
- if ((color != NULL && !oflag) || qflag || lflag)
- break;
-
- if (st == (size_t)pmatch.rm_so)
- break; /* No matches */
- }
-
- if (c && binbehave == BINFILE_BIN && nottext)
- return (c); /* Binary file */
-
- /* Dealing with the context */
- if ((tail || c) && !cflag && !qflag && !lflag && !Lflag) {
- if (c) {
- if ((Aflag || Bflag) && !first_global &&
- (first || since_printed > Bflag))
- printf("--\n");
- tail = Aflag;
- if (Bflag > 0)
- printqueue();
- printline(l, ':', matches, m);
- } else {
- printline(l, '-', matches, m);
- tail--;
- }
- first = false;
- first_global = false;
- since_printed = 0;
- } else {
- if (Bflag)
- enqueue(l);
- since_printed++;
- }
- return (c);
-}
-
-/*
- * Safe malloc() for internal use.
- */
-void *
-grep_malloc(size_t size)
-{
- void *ptr;
-
- if ((ptr = malloc(size)) == NULL)
- err(2, "malloc");
- return (ptr);
-}
-
-/*
- * Safe calloc() for internal use.
- */
-void *
-grep_calloc(size_t nmemb, size_t size)
-{
- void *ptr;
-
- if ((ptr = calloc(nmemb, size)) == NULL)
- err(2, "calloc");
- return (ptr);
-}
-
-/*
- * Safe realloc() for internal use.
- */
-void *
-grep_realloc(void *ptr, size_t size)
-{
-
- if ((ptr = realloc(ptr, size)) == NULL)
- err(2, "realloc");
- return (ptr);
-}
-
-/*
- * Safe strdup() for internal use.
- */
-char *
-grep_strdup(const char *str)
-{
- char *ret;
-
- if ((ret = strdup(str)) == NULL)
- err(2, "strdup");
- return (ret);
-}
-
-/*
- * Prints a matching line according to the command line options.
- */
-void
-printline(struct str *line, int sep, regmatch_t *matches, int m)
-{
- size_t a = 0;
- int i, n = 0;
-
- if (!hflag) {
- if (nullflag == 0)
- fputs(line->file, stdout);
- else {
- printf("%s", line->file);
- putchar(0);
- }
- ++n;
- }
- if (nflag) {
- if (n > 0)
- putchar(sep);
- printf("%d", line->line_no);
- ++n;
- }
- if (bflag) {
- if (n > 0)
- putchar(sep);
- printf("%lld", (long long)line->off);
- ++n;
- }
- if (n)
- putchar(sep);
- /* --color and -o */
- if ((oflag || color) && m > 0) {
- for (i = 0; i < m; i++) {
- if (!oflag)
- fwrite(line->dat + a, matches[i].rm_so - a, 1,
- stdout);
- if (color)
- fprintf(stdout, "\33[%sm\33[K", color);
-
- fwrite(line->dat + matches[i].rm_so,
- matches[i].rm_eo - matches[i].rm_so, 1,
- stdout);
-
- if (color)
- fprintf(stdout, "\33[m\33[K");
- a = matches[i].rm_eo;
- if (oflag)
- putchar('\n');
- }
- if (!oflag) {
- if (line->len - a > 0)
- fwrite(line->dat + a, line->len - a, 1, stdout);
- putchar(line_sep);
- }
- } else {
- fwrite(line->dat, line->len, 1, stdout);
- putchar(line_sep);
- }
-}