dumpsys: make timeout value an argument
Also rework the args parsing using getopt_long.
Bug: 27788406
Change-Id: I60fd8e614616334d47b8de574f3c81a121a6ac0a
Signed-off-by: Thierry Strudel <tstrudel@google.com>
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 003fcc3..db06e99 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -43,9 +43,10 @@
"usage: dumpsys\n"
" To dump all services.\n"
"or:\n"
- " dumpsys [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
+ " dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
" --help: shows this help\n"
" -l: only list services, do not dump them\n"
+ " -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
" --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
" SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
}
@@ -74,44 +75,80 @@
Vector<String16> args;
Vector<String16> skippedServices;
bool showListOnly = false;
- if (argc == 2) {
- // 1 argument: check for special cases (-l or --help)
- if (strcmp(argv[1], "--help") == 0) {
- usage();
- return 0;
+ bool skipServices = false;
+ int timeoutArg = 10;
+ static struct option longOptions[] = {
+ {"skip", no_argument, 0, 0 },
+ {"help", no_argument, 0, 0 },
+ { 0, 0, 0, 0 }
+ };
+
+ while (1) {
+ int c;
+ int optionIndex = 0;
+
+ c = getopt_long(argc, argv, "+t:l", longOptions, &optionIndex);
+
+ if (c == -1) {
+ break;
}
- if (strcmp(argv[1], "-l") == 0) {
+
+ switch (c) {
+ case 0:
+ if (!strcmp(longOptions[optionIndex].name, "skip")) {
+ skipServices = true;
+ } else if (!strcmp(longOptions[optionIndex].name, "help")) {
+ usage();
+ return 0;
+ }
+ break;
+
+ case 't':
+ {
+ char *endptr;
+ timeoutArg = strtol(optarg, &endptr, 10);
+ if (*endptr != '\0' || timeoutArg <= 0) {
+ fprintf(stderr, "Error: invalid timeout number: '%s'\n", optarg);
+ return -1;
+ }
+ }
+ break;
+
+ case 'l':
showListOnly = true;
+ break;
+
+ default:
+ fprintf(stderr, "\n");
+ usage();
+ return -1;
}
}
- if (argc == 3) {
- // 2 arguments: check for special cases (--skip SERVICES)
- if (strcmp(argv[1], "--skip") == 0) {
- char* token = strtok(argv[2], ",");
- while (token != NULL) {
- skippedServices.add(String16(token));
- token = strtok(NULL, ",");
+
+ for (int i = optind; i < argc; i++) {
+ if (skipServices) {
+ skippedServices.add(String16(argv[i]));
+ } else {
+ if (i == optind) {
+ services.add(String16(argv[i]));
+ } else {
+ args.add(String16(argv[i]));
}
}
}
- bool dumpAll = argc == 1;
- if (dumpAll || !skippedServices.empty() || showListOnly) {
+
+ if ((skipServices && skippedServices.empty()) ||
+ (!skipServices && !showListOnly && services.empty()) ||
+ (showListOnly && (!services.empty() || !skippedServices.empty()))) {
+ usage();
+ return -1;
+ }
+
+ if (!skippedServices.empty() || showListOnly) {
// gets all services
services = sm->listServices();
services.sort(sort_func);
args.add(String16("-a"));
- } else {
- // gets a specific service:
- // first check if its name is not a special argument...
- if (strcmp(argv[1], "--skip") == 0 || strcmp(argv[1], "-l") == 0) {
- usage();
- return -1;
- }
- // ...then gets its arguments
- services.add(String16(argv[1]));
- for (int i=2; i<argc; i++) {
- args.add(String16(argv[i]));
- }
}
const size_t N = services.size();
@@ -173,8 +210,7 @@
}
});
- // TODO: Make this configurable at runtime.
- constexpr auto timeout = std::chrono::seconds(10);
+ auto timeout = std::chrono::seconds(timeoutArg);
auto end = std::chrono::steady_clock::now() + timeout;
struct pollfd pfd = {