toolbox: add setprop, start, and stop
Move these from toybox as they're Android specific and more easily maintained here. A few changes during the conversion: * Report error in setprop if value is not a UTF8 string; this would previously fail only after attempting to set the property * Inform users to check dmesg for further failure messages for all three programs * Only start/stop zygote_secondary if the device is not single arch Bug: 117321744 Bug: 133901248 Test: setprop works, start and stop work on single and multi-arch. Change-Id: Id2194cf2b65221bde38aff91f0e86b33edb37f42
This commit is contained in:
parent
c76078e4b6
commit
65a1ee83a8
5 changed files with 205 additions and 0 deletions
|
@ -211,3 +211,32 @@ tac tail tar taskset tee time timeout top touch tr traceroute traceroute6
|
|||
true truncate tty tunctl ulimit umount uname uniq unix2dos unlink
|
||||
unshare uptime usleep uudecode uuencode uuidgen vconfig vmstat watch
|
||||
wc which whoami xargs xxd yes zcat
|
||||
|
||||
## Android R
|
||||
|
||||
BSD: grep fsck\_msdos newfs\_msdos
|
||||
|
||||
bzip2: bzcat bzip2 bunzip2
|
||||
|
||||
one-true-awk: awk
|
||||
|
||||
toolbox: getevent getprop setprop start stop
|
||||
|
||||
toybox: acpi base64 basename bc blkid blockdev cal cat chattr chcon chgrp
|
||||
chmod chown chroot chrt cksum clear cmp comm cp cpio cut date dd df
|
||||
diff dirname dmesg dos2unix du echo egrep env expand expr fallocate
|
||||
false fgrep file find flock fmt free freeramdisk fsfreeze getconf
|
||||
getenforce getfattr grep groups gunzip gzip head help hostname hwclock
|
||||
i2cdetect i2cdump i2cget i2cset iconv id ifconfig inotifyd insmod
|
||||
install ionice iorenice iotop kill killall ln load\_policy log logname
|
||||
losetup ls lsattr lsmod lsof lspci lsusb makedevs md5sum microcom
|
||||
mkdir mkfifo mknod mkswap mktemp modinfo modprobe more mount mountpoint
|
||||
mv nbd-client nc netcat netstat nice nl nohup nproc nsenter od partprobe
|
||||
paste patch pgrep pidof ping ping6 pivot\_root pkill pmap printenv
|
||||
printf prlimit ps pwd pwdx readlink realpath renice restorecon rev
|
||||
rfkill rm rmdir rmmod runcon sed sendevent seq setenforce setfattr
|
||||
setsid sha1sum sha224sum sha256sum sha384sum sha512sum sleep sort split
|
||||
stat strings stty swapoff swapon sync sysctl tac tail tar taskset tee
|
||||
time timeout top touch tr traceroute traceroute6 true truncate tty tunctl
|
||||
ulimit umount uname uniq unix2dos unlink unshare uptime usleep uudecode
|
||||
uuencode uuidgen vconfig vmstat watch wc which whoami xargs xxd yes zcat
|
||||
|
|
|
@ -28,6 +28,8 @@ cc_defaults {
|
|||
"toolbox.c",
|
||||
"getevent.c",
|
||||
"getprop.cpp",
|
||||
"setprop.cpp",
|
||||
"start.cpp",
|
||||
],
|
||||
generated_headers: [
|
||||
"toolbox_input_labels",
|
||||
|
@ -40,6 +42,9 @@ cc_defaults {
|
|||
symlinks: [
|
||||
"getevent",
|
||||
"getprop",
|
||||
"setprop",
|
||||
"start",
|
||||
"stop",
|
||||
],
|
||||
}
|
||||
|
||||
|
|
79
toolbox/setprop.cpp
Normal file
79
toolbox/setprop.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/system_properties.h>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <android-base/properties.h>
|
||||
#include <android-base/strings.h>
|
||||
|
||||
using android::base::SetProperty;
|
||||
using android::base::StartsWith;
|
||||
|
||||
extern "C" int setprop_main(int argc, char** argv) {
|
||||
if (argc != 3) {
|
||||
std::cout << "usage: setprop NAME VALUE\n"
|
||||
"\n"
|
||||
"Sets an Android system property."
|
||||
<< std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
auto name = std::string{argv[1]};
|
||||
auto value = std::string{argv[2]};
|
||||
|
||||
// SetProperty() doesn't tell us why it failed, and actually can't recognize most failures, so
|
||||
// we duplicate some of init's checks here to help the user.
|
||||
|
||||
if (name.front() == '.' || name.back() == '.') {
|
||||
std::cerr << "Property names must not start or end with a '.'" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (name.find("..") != std::string::npos) {
|
||||
std::cerr << "'..' is not allowed in a property name" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for (const auto& c : name) {
|
||||
if (!isalnum(c) && !strchr(":@_.-", c)) {
|
||||
std::cerr << "Invalid character '" << c << "' in name '" << name << "'" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (value.size() >= PROP_VALUE_MAX && !StartsWith(value, "ro.")) {
|
||||
std::cerr << "Value '" << value << "' is too long, " << value.size()
|
||||
<< " bytes vs a max of " << PROP_VALUE_MAX << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (mbstowcs(nullptr, value.data(), 0) == static_cast<std::size_t>(-1)) {
|
||||
std::cerr << "Value '" << value << "' is not a UTF8 encoded string" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (!SetProperty(name, value)) {
|
||||
std::cerr << "Failed to set property '" << name << "' to '" << value
|
||||
<< "'.\nSee dmesg for error reason." << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
89
toolbox/start.cpp
Normal file
89
toolbox/start.cpp
Normal file
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (C) 2019 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/properties.h>
|
||||
|
||||
using android::base::GetProperty;
|
||||
using android::base::SetProperty;
|
||||
using namespace std::literals;
|
||||
|
||||
static void ControlService(bool start, const std::string& service) {
|
||||
if (!android::base::SetProperty(start ? "ctl.start" : "ctl.stop", service)) {
|
||||
std::cerr << "Unable to " << (start ? "start" : "stop") << " service '" << service
|
||||
<< "'\nSee dmesg for error reason." << std::endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
static void ControlDefaultServices(bool start) {
|
||||
std::vector<std::string> services = {"netd", "surfaceflinger", "zygote"};
|
||||
|
||||
// Only start zygote_secondary if not single arch.
|
||||
std::string zygote_configuration = GetProperty("ro.zygote", "");
|
||||
if (zygote_configuration != "zygote32" && zygote_configuration != "zygote64") {
|
||||
services.emplace_back("zygote_secondary");
|
||||
}
|
||||
|
||||
if (start) {
|
||||
for (const auto& service : services) {
|
||||
ControlService(true, service);
|
||||
}
|
||||
} else {
|
||||
for (auto it = services.crbegin(); it != services.crend(); ++it) {
|
||||
ControlService(false, *it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int StartStop(int argc, char** argv, bool start) {
|
||||
if (getuid()) {
|
||||
std::cerr << "Must be root" << std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
ControlDefaultServices(start);
|
||||
}
|
||||
|
||||
if (argc == 2 && argv[1] == "--help"s) {
|
||||
std::cout << "usage: " << (start ? "start" : "stop")
|
||||
<< " [SERVICE...]\n"
|
||||
"\n"
|
||||
<< (start ? "Starts" : "Stops")
|
||||
<< " the given system service, or netd/surfaceflinger/zygotes." << std::endl;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
ControlService(start, argv[i]);
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
extern "C" int start_main(int argc, char** argv) {
|
||||
return StartStop(argc, argv, true);
|
||||
}
|
||||
|
||||
extern "C" int stop_main(int argc, char** argv) {
|
||||
return StartStop(argc, argv, false);
|
||||
}
|
|
@ -1,3 +1,6 @@
|
|||
TOOL(getevent)
|
||||
TOOL(getprop)
|
||||
TOOL(setprop)
|
||||
TOOL(start)
|
||||
TOOL(stop)
|
||||
TOOL(toolbox)
|
||||
|
|
Loading…
Reference in a new issue