Merge "logcat: fortify help on filterspec"
diff --git a/adb/Android.mk b/adb/Android.mk
index adad69f..1749c62 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -17,14 +17,14 @@
# small by moving common files into a static library. Hopefully some day we can
# get enough of adb in here that we no longer need minadb. https://b/17626262
LIBADB_SRC_FILES := \
- adb.c \
- adb_auth.c \
+ adb.cpp \
+ adb_auth.cpp \
adb_io.cpp \
- adb_listeners.c \
- sockets.c \
- transport.c \
- transport_local.c \
- transport_usb.c \
+ adb_listeners.cpp \
+ sockets.cpp \
+ transport.cpp \
+ transport_local.cpp \
+ transport_usb.cpp \
LIBADB_CFLAGS := \
-Wall -Werror \
@@ -32,9 +32,20 @@
-Wno-missing-field-initializers \
-fvisibility=hidden \
-LIBADB_darwin_SRC_FILES := fdevent.cpp get_my_path_darwin.c usb_osx.c
-LIBADB_linux_SRC_FILES := fdevent.cpp get_my_path_linux.c usb_linux.c
-LIBADB_windows_SRC_FILES := get_my_path_windows.c sysdeps_win32.c usb_windows.c
+LIBADB_darwin_SRC_FILES := \
+ fdevent.cpp \
+ get_my_path_darwin.c \
+ usb_osx.c \
+
+LIBADB_linux_SRC_FILES := \
+ fdevent.cpp \
+ get_my_path_linux.cpp \
+ usb_linux.cpp \
+
+LIBADB_windows_SRC_FILES := \
+ get_my_path_windows.cpp \
+ sysdeps_win32.c \
+ usb_windows.cpp \
include $(CLEAR_VARS)
LOCAL_CLANG := $(ADB_CLANG)
@@ -42,10 +53,10 @@
LOCAL_CFLAGS := $(LIBADB_CFLAGS) -DADB_HOST=0
LOCAL_SRC_FILES := \
$(LIBADB_SRC_FILES) \
- adb_auth_client.c \
+ adb_auth_client.cpp \
fdevent.cpp \
- jdwp_service.c \
- qemu_tracing.c \
+ jdwp_service.cpp \
+ qemu_tracing.cpp \
usb_linux_client.c \
include $(BUILD_STATIC_LIBRARY)
@@ -57,7 +68,7 @@
LOCAL_SRC_FILES := \
$(LIBADB_SRC_FILES) \
$(LIBADB_$(HOST_OS)_SRC_FILES) \
- adb_auth_host.c \
+ adb_auth_host.cpp \
# Even though we're building a static library (and thus there's no link step for
# this to take effect), this adds the SSL includes to our path.
@@ -86,7 +97,7 @@
LOCAL_CLANG := $(ADB_CLANG)
LOCAL_MODULE := adb_test
LOCAL_CFLAGS := -DADB_HOST=1 $(LIBADB_CFLAGS)
-LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS) services.c
+LOCAL_SRC_FILES := $(LIBADB_TEST_SRCS) services.cpp
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_STATIC_LIBRARIES := \
libadb \
@@ -126,16 +137,12 @@
LOCAL_CLANG := $(ADB_CLANG)
LOCAL_SRC_FILES := \
- adb_main.c \
- console.c \
- commandline.c \
- adb_client.c \
- services.c \
- file_sync_client.c \
-
-ifneq ($(USE_SYSDEPS_WIN32),)
- LOCAL_SRC_FILES += sysdeps_win32.c
-endif
+ adb_main.cpp \
+ console.cpp \
+ commandline.cpp \
+ adb_client.cpp \
+ services.cpp \
+ file_sync_client.cpp \
LOCAL_CFLAGS += \
-Wall -Werror \
@@ -153,7 +160,7 @@
$(EXTRA_STATIC_LIBS) \
ifeq ($(USE_SYSDEPS_WIN32),)
- LOCAL_STATIC_LIBRARIES += libcutils
+ LOCAL_STATIC_LIBRARIES += libcutils
endif
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
@@ -176,19 +183,19 @@
LOCAL_CLANG := $(ADB_CLANG)
LOCAL_SRC_FILES := \
- adb_main.c \
- services.c \
- file_sync_service.c \
- framebuffer_service.c \
- remount_service.c \
- set_verity_enable_state_service.c \
+ adb_main.cpp \
+ services.cpp \
+ file_sync_service.cpp \
+ framebuffer_service.cpp \
+ remount_service.cpp \
+ set_verity_enable_state_service.cpp \
LOCAL_CFLAGS := \
- -O2 \
- -g \
- -DADB_HOST=0 \
- -D_GNU_SOURCE \
- -Wall -Wno-unused-parameter -Werror -Wno-deprecated-declarations \
+ -DADB_HOST=0 \
+ -D_GNU_SOURCE \
+ -Wall -Werror \
+ -Wno-unused-parameter \
+ -Wno-deprecated-declarations \
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
diff --git a/adb/adb.c b/adb/adb.cpp
similarity index 97%
rename from adb/adb.c
rename to adb/adb.cpp
index 5f244a5..ffa93f4 100644
--- a/adb/adb.c
+++ b/adb/adb.cpp
@@ -140,10 +140,13 @@
}
}
-apacket *get_apacket(void)
+apacket* get_apacket(void)
{
- apacket *p = malloc(sizeof(apacket));
- if(p == 0) fatal("failed to allocate an apacket");
+ apacket* p = reinterpret_cast<apacket*>(malloc(sizeof(apacket)));
+ if (p == nullptr) {
+ fatal("failed to allocate an apacket");
+ }
+
memset(p, 0, sizeof(apacket) - MAX_PAYLOAD);
return p;
}
@@ -293,7 +296,7 @@
}
#if ADB_HOST
-static char *connection_state_name(atransport *t)
+static const char* connection_state_name(atransport *t)
{
if (t == NULL) {
return "unknown";
@@ -713,8 +716,8 @@
// Create the list of forward redirections.
int buffer_size = format_listeners(NULL, 0);
// Add one byte for the trailing zero.
- char* buffer = malloc(buffer_size + 1);
- if (buffer == NULL) {
+ char* buffer = reinterpret_cast<char*>(malloc(buffer_size + 1));
+ if (buffer == nullptr) {
sendfailmsg(reply_fd, "not enough memory");
return 1;
}
@@ -740,7 +743,7 @@
if (!strncmp(service, "forward:",8) ||
!strncmp(service, "killforward:",12)) {
- char *local, *remote, *err;
+ char *local, *remote;
int r;
atransport *transport;
@@ -777,6 +780,7 @@
}
}
+ const char* err;
transport = acquire_one_transport(CS_ANY, ttype, serial, &err);
if (!transport) {
sendfailmsg(reply_fd, err);
@@ -835,7 +839,6 @@
// "transport-local:" is used for switching transport to the only local transport
// "transport-any:" is used for switching transport to the only transport
if (!strncmp(service, "transport", strlen("transport"))) {
- char* error_string = "unknown failure";
transport_type type = kTransportAny;
if (!strncmp(service, "transport-usb", strlen("transport-usb"))) {
@@ -849,6 +852,7 @@
serial = service;
}
+ const char* error_string = "unknown failure";
transport = acquire_one_transport(CS_ANY, type, serial, &error_string);
if (transport) {
@@ -911,8 +915,8 @@
}
if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
- char *out = "unknown";
- transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
+ const char *out = "unknown";
+ transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
if (transport && transport->serial) {
out = transport->serial;
}
@@ -920,8 +924,8 @@
return 0;
}
if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
- char *out = "unknown";
- transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
+ const char *out = "unknown";
+ transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
if (transport && transport->devpath) {
out = transport->devpath;
}
@@ -938,7 +942,7 @@
if(!strncmp(service,"get-state",strlen("get-state"))) {
transport = acquire_one_transport(CS_ANY, ttype, serial, NULL);
- char *state = connection_state_name(transport);
+ const char *state = connection_state_name(transport);
send_msg_with_okay(reply_fd, state, strlen(state));
return 0;
}
diff --git a/adb/adb.h b/adb/adb.h
index 9a68871..1aeac6b 100644
--- a/adb/adb.h
+++ b/adb/adb.h
@@ -239,8 +239,8 @@
fdevent fde;
int fd;
- const char *local_name;
- const char *connect_to;
+ char *local_name;
+ char *connect_to;
atransport *transport;
adisconnect disconnect;
};
@@ -348,7 +348,7 @@
int is_adb_interface(int vid, int pid, int usb_class, int usb_subclass, int usb_protocol);
#endif
-int adb_commandline(int argc, char **argv);
+int adb_commandline(int argc, const char **argv);
int connection_state(atransport *t);
diff --git a/adb/adb_auth.c b/adb/adb_auth.cpp
similarity index 100%
rename from adb/adb_auth.c
rename to adb/adb_auth.cpp
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index cece5e3..1487287 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -40,7 +40,8 @@
#if ADB_HOST
-int adb_auth_sign(void *key, void *token, size_t token_size, void *sig);
+int adb_auth_sign(void *key, const unsigned char* token, size_t token_size,
+ unsigned char* sig);
void *adb_auth_nextkey(void *current);
int adb_auth_get_userkey(unsigned char *data, size_t len);
@@ -50,12 +51,15 @@
#else // !ADB_HOST
-static inline int adb_auth_sign(void* key, void *token, size_t token_size, void *sig) { return 0; }
+static inline int adb_auth_sign(void* key, const unsigned char* token,
+ size_t token_size, unsigned char* sig) {
+ return 0;
+}
static inline void *adb_auth_nextkey(void *current) { return NULL; }
static inline int adb_auth_get_userkey(unsigned char *data, size_t len) { return 0; }
int adb_auth_generate_token(void *token, size_t token_size);
-int adb_auth_verify(void *token, void *sig, int siglen);
+int adb_auth_verify(uint8_t* token, uint8_t* sig, int siglen);
void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t);
#endif // ADB_HOST
diff --git a/adb/adb_auth_client.c b/adb/adb_auth_client.cpp
similarity index 93%
rename from adb/adb_auth_client.c
rename to adb/adb_auth_client.cpp
index 7be883c..deb0a5d 100644
--- a/adb/adb_auth_client.c
+++ b/adb/adb_auth_client.cpp
@@ -37,7 +37,7 @@
RSAPublicKey key;
};
-static char *key_paths[] = {
+static const char *key_paths[] = {
"/adb_keys",
"/data/misc/adb/adb_keys",
NULL
@@ -53,7 +53,6 @@
static void read_keys(const char *file, struct listnode *list)
{
- struct adb_public_key *key;
FILE *f;
char buf[MAX_PAYLOAD];
char *sep;
@@ -67,8 +66,9 @@
while (fgets(buf, sizeof(buf), f)) {
/* Allocate 4 extra bytes to decode the base64 data in-place */
- key = calloc(1, sizeof(*key) + 4);
- if (!key) {
+ auto key = reinterpret_cast<adb_public_key*>(
+ calloc(1, sizeof(adb_public_key) + 4));
+ if (key == nullptr) {
D("Can't malloc key\n");
break;
}
@@ -109,8 +109,8 @@
static void load_keys(struct listnode *list)
{
- char *path;
- char **paths = key_paths;
+ const char* path;
+ const char** paths = key_paths;
struct stat buf;
list_init(list);
@@ -138,10 +138,9 @@
return ret * token_size;
}
-int adb_auth_verify(void *token, void *sig, int siglen)
+int adb_auth_verify(uint8_t* token, uint8_t* sig, int siglen)
{
struct listnode *item;
- struct adb_public_key *key;
struct listnode key_list;
int ret = 0;
@@ -151,7 +150,7 @@
load_keys(&key_list);
list_for_each(item, &key_list) {
- key = node_to_item(item, struct adb_public_key, node);
+ adb_public_key* key = node_to_item(item, struct adb_public_key, node);
ret = RSA_verify(&key->key, sig, siglen, token, SHA_DIGEST_SIZE);
if (ret)
break;
diff --git a/adb/adb_auth_host.c b/adb/adb_auth_host.cpp
similarity index 91%
rename from adb/adb_auth_host.c
rename to adb/adb_auth_host.cpp
index 1d48667..aba23d4 100644
--- a/adb/adb_auth_host.c
+++ b/adb/adb_auth_host.cpp
@@ -157,7 +157,7 @@
RSAPublicKey pkey;
FILE *outfile = NULL;
char path[PATH_MAX], info[MAX_PAYLOAD];
- uint8_t *encoded = NULL;
+ uint8_t* encoded = nullptr;
size_t encoded_length;
int ret = 0;
@@ -191,8 +191,8 @@
encoded_length = 1 + ((sizeof(pkey) + 2) / 3 * 4);
#endif
- encoded = malloc(encoded_length);
- if (encoded == NULL) {
+ encoded = reinterpret_cast<uint8_t*>(malloc(encoded_length));
+ if (encoded == nullptr) {
D("Allocation failure");
goto out;
}
@@ -272,18 +272,16 @@
static int read_key(const char *file, struct listnode *list)
{
- struct adb_private_key *key;
- FILE *f;
-
D("read_key '%s'\n", file);
- f = fopen(file, "r");
+ FILE* f = fopen(file, "r");
if (!f) {
D("Failed to open '%s'\n", file);
return 0;
}
- key = malloc(sizeof(*key));
+ adb_private_key* key = reinterpret_cast<adb_private_key*>(
+ malloc(sizeof(adb_private_key)));
if (!key) {
D("Failed to alloc key\n");
fclose(f);
@@ -390,7 +388,8 @@
}
}
-int adb_auth_sign(void *node, void *token, size_t token_size, void *sig)
+int adb_auth_sign(void *node, const unsigned char* token, size_t token_size,
+ unsigned char* sig)
{
unsigned int len;
struct adb_private_key *key = node_to_item(node, struct adb_private_key, node);
@@ -433,31 +432,33 @@
int adb_auth_get_userkey(unsigned char *data, size_t len)
{
char path[PATH_MAX];
- char *file;
- int ret;
-
- ret = get_user_keyfilepath(path, sizeof(path) - 4);
+ int ret = get_user_keyfilepath(path, sizeof(path) - 4);
if (ret < 0 || ret >= (signed)(sizeof(path) - 4)) {
D("Error getting user key filename");
return 0;
}
strcat(path, ".pub");
- file = load_file(path, (unsigned*)&ret);
- if (!file) {
+ // TODO(danalbert): ReadFileToString
+ unsigned size;
+ char* file_data = reinterpret_cast<char*>(load_file(path, &size));
+ if (file_data == nullptr) {
D("Can't load '%s'\n", path);
return 0;
}
- if (len < (size_t)(ret + 1)) {
- D("%s: Content too large ret=%d\n", path, ret);
+ if (len < (size_t)(size + 1)) {
+ D("%s: Content too large ret=%d\n", path, size);
+ free(file_data);
return 0;
}
- memcpy(data, file, ret);
- data[ret] = '\0';
+ memcpy(data, file_data, size);
+ free(file_data);
+ file_data = nullptr;
+ data[size] = '\0';
- return ret + 1;
+ return size + 1;
}
int adb_auth_keygen(const char* filename) {
diff --git a/adb/adb_client.c b/adb/adb_client.cpp
similarity index 98%
rename from adb/adb_client.c
rename to adb/adb_client.cpp
index 5d2bbd7..d677db8 100644
--- a/adb/adb_client.c
+++ b/adb/adb_client.cpp
@@ -115,7 +115,7 @@
if (__adb_serial)
snprintf(service, sizeof service, "host:transport:%s", __adb_serial);
else {
- char* transport_type = "???";
+ const char* transport_type = "???";
switch (__adb_transport) {
case kTransportUsb:
@@ -328,8 +328,8 @@
char *adb_query(const char *service)
{
char buf[5];
- unsigned n;
- char *tmp;
+ unsigned long n;
+ char* tmp;
D("adb_query: %s\n", service);
int fd = adb_connect(service);
@@ -347,7 +347,7 @@
goto oops;
}
- tmp = malloc(n + 1);
+ tmp = reinterpret_cast<char*>(malloc(n + 1));
if(tmp == 0) goto oops;
if(!ReadFdExactly(fd, tmp, n) == 0) {
diff --git a/adb/adb_client.h b/adb/adb_client.h
index 6ba3b38..9af176f 100644
--- a/adb/adb_client.h
+++ b/adb/adb_client.h
@@ -47,7 +47,7 @@
* is zero, or more than one emulator connected (or if you use -s <serial>
* with a <serial> that does not designate an emulator)
*/
-int adb_send_emulator_command(int argc, char** argv);
+int adb_send_emulator_command(int argc, const char** argv);
/* return verbose error string from last operation */
const char *adb_error(void);
diff --git a/adb/adb_io.cpp b/adb/adb_io.cpp
index ca208ad..4dd9f4d 100644
--- a/adb/adb_io.cpp
+++ b/adb/adb_io.cpp
@@ -33,7 +33,7 @@
D("readx: fd=%d wanted=%zu\n", fd, len);
while (len > 0) {
- int r = TEMP_FAILURE_RETRY(adb_read(fd, p, len));
+ int r = adb_read(fd, p, len);
if (r > 0) {
len -= r;
p += r;
@@ -69,7 +69,7 @@
#endif
while (len > 0) {
- r = TEMP_FAILURE_RETRY(adb_write(fd, p, len));
+ r = adb_write(fd, p, len);
if (r == -1) {
D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno));
if (errno == EAGAIN) {
diff --git a/adb/adb_listeners.c b/adb/adb_listeners.cpp
similarity index 76%
rename from adb/adb_listeners.c
rename to adb/adb_listeners.cpp
index f68b876..84b9c64 100644
--- a/adb/adb_listeners.c
+++ b/adb/adb_listeners.cpp
@@ -54,24 +54,26 @@
}
}
-void listener_event_func(int _fd, unsigned ev, void *_l)
+void listener_event_func(int _fd, unsigned ev, void* _l)
{
- alistener *l = _l;
+ alistener* listener = reinterpret_cast<alistener*>(_l);
asocket *s;
- if(ev & FDE_READ) {
+ if (ev & FDE_READ) {
struct sockaddr addr;
socklen_t alen;
int fd;
alen = sizeof(addr);
fd = adb_socket_accept(_fd, &addr, &alen);
- if(fd < 0) return;
+ if (fd < 0) {
+ return;
+ }
s = create_local_socket(fd);
- if(s) {
- s->transport = l->transport;
- connect_to_remote(s, l->connect_to);
+ if (s) {
+ s->transport = listener->transport;
+ connect_to_remote(s, listener->connect_to);
return;
}
@@ -102,11 +104,9 @@
free(l);
}
-void listener_disconnect(void* _l, atransport* t)
+void listener_disconnect(void* listener, atransport* t)
{
- alistener* l = _l;
-
- free_listener(l);
+ free_listener(reinterpret_cast<alistener*>(listener));
}
int local_name_to_fd(const char *name)
@@ -220,20 +220,16 @@
atransport* transport,
int no_rebind)
{
- alistener *l;
+ for (alistener* l = listener_list.next; l != &listener_list; l = l->next) {
+ if (strcmp(local_name, l->local_name) == 0) {
+ char* cto;
- //printf("install_listener('%s','%s')\n", local_name, connect_to);
-
- for(l = listener_list.next; l != &listener_list; l = l->next){
- if(strcmp(local_name, l->local_name) == 0) {
- char *cto;
-
- /* can't repurpose a smartsocket */
+ /* can't repurpose a smartsocket */
if(l->connect_to[0] == '*') {
return INSTALL_STATUS_INTERNAL_ERROR;
}
- /* can't repurpose a listener if 'no_rebind' is true */
+ /* can't repurpose a listener if 'no_rebind' is true */
if (no_rebind) {
return INSTALL_STATUS_CANNOT_REBIND;
}
@@ -243,7 +239,6 @@
return INSTALL_STATUS_INTERNAL_ERROR;
}
- //printf("rebinding '%s' to '%s'\n", local_name, connect_to);
free((void*) l->connect_to);
l->connect_to = cto;
if (l->transport != transport) {
@@ -255,38 +250,51 @@
}
}
- if((l = calloc(1, sizeof(alistener))) == 0) goto nomem;
- if((l->local_name = strdup(local_name)) == 0) goto nomem;
- if((l->connect_to = strdup(connect_to)) == 0) goto nomem;
+ alistener* listener = reinterpret_cast<alistener*>(
+ calloc(1, sizeof(alistener)));
+ if (listener == nullptr) {
+ goto nomem;
+ }
+ listener->local_name = strdup(local_name);
+ if (listener->local_name == nullptr) {
+ goto nomem;
+ }
- l->fd = local_name_to_fd(local_name);
- if(l->fd < 0) {
- free((void*) l->local_name);
- free((void*) l->connect_to);
- free(l);
+ listener->connect_to = strdup(connect_to);
+ if (listener->connect_to == nullptr) {
+ goto nomem;
+ }
+
+ listener->fd = local_name_to_fd(local_name);
+ if (listener->fd < 0) {
+ free(listener->local_name);
+ free(listener->connect_to);
+ free(listener);
printf("cannot bind '%s'\n", local_name);
- return -2;
+ return INSTALL_STATUS_CANNOT_BIND;
}
- close_on_exec(l->fd);
- if(!strcmp(l->connect_to, "*smartsocket*")) {
- fdevent_install(&l->fde, l->fd, ss_listener_event_func, l);
+ close_on_exec(listener->fd);
+ if (!strcmp(listener->connect_to, "*smartsocket*")) {
+ fdevent_install(&listener->fde, listener->fd, ss_listener_event_func,
+ listener);
} else {
- fdevent_install(&l->fde, l->fd, listener_event_func, l);
+ fdevent_install(&listener->fde, listener->fd, listener_event_func,
+ listener);
}
- fdevent_set(&l->fde, FDE_READ);
+ fdevent_set(&listener->fde, FDE_READ);
- l->next = &listener_list;
- l->prev = listener_list.prev;
- l->next->prev = l;
- l->prev->next = l;
- l->transport = transport;
+ listener->next = &listener_list;
+ listener->prev = listener_list.prev;
+ listener->next->prev = listener;
+ listener->prev->next = listener;
+ listener->transport = transport;
if (transport) {
- l->disconnect.opaque = l;
- l->disconnect.func = listener_disconnect;
- add_transport_disconnect(transport, &l->disconnect);
+ listener->disconnect.opaque = listener;
+ listener->disconnect.func = listener_disconnect;
+ add_transport_disconnect(transport, &listener->disconnect);
}
return INSTALL_STATUS_OK;
diff --git a/adb/adb_main.c b/adb/adb_main.cpp
similarity index 98%
rename from adb/adb_main.c
rename to adb/adb_main.cpp
index f8475c7..b0816ce 100644
--- a/adb/adb_main.c
+++ b/adb/adb_main.cpp
@@ -387,7 +387,7 @@
adb_sysdeps_init();
adb_trace_init();
D("Handling commandline()\n");
- return adb_commandline(argc - 1, argv + 1);
+ return adb_commandline(argc - 1, const_cast<const char**>(argv + 1));
#else
/* If adbd runs inside the emulator this will enable adb tracing via
* adb-debug qemud service in the emulator. */
diff --git a/adb/commandline.c b/adb/commandline.cpp
similarity index 95%
rename from adb/commandline.c
rename to adb/commandline.cpp
index a8ad7bd..ecaab83 100644
--- a/adb/commandline.c
+++ b/adb/commandline.cpp
@@ -40,31 +40,30 @@
#include "adb_io.h"
#include "file_sync_service.h"
-static int do_cmd(transport_type ttype, char* serial, char *cmd, ...);
+static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...);
-void get_my_path(char *s, size_t maxLen);
int find_sync_dirs(const char *srcarg,
char **android_srcdir_out, char **data_srcdir_out, char **vendor_srcdir_out);
-int install_app(transport_type transport, char* serial, int argc, char** argv);
-int install_multiple_app(transport_type transport, char* serial, int argc, char** argv);
-int uninstall_app(transport_type transport, char* serial, int argc, char** argv);
+int install_app(transport_type transport, const char* serial, int argc,
+ const char** argv);
+int install_multiple_app(transport_type transport, const char* serial, int argc,
+ const char** argv);
+int uninstall_app(transport_type transport, const char* serial, int argc,
+ const char** argv);
static const char *gProductOutPath = NULL;
extern int gListenAll;
static char *product_file(const char *extra)
{
- int n;
- char *x;
-
if (gProductOutPath == NULL) {
fprintf(stderr, "adb: Product directory not specified; "
"use -p or define ANDROID_PRODUCT_OUT\n");
exit(1);
}
- n = strlen(gProductOutPath) + strlen(extra) + 2;
- x = malloc(n);
+ int n = strlen(gProductOutPath) + strlen(extra) + 2;
+ char* x = reinterpret_cast<char*>(malloc(n));
if (x == 0) {
fprintf(stderr, "adb: Out of memory (product_file())\n");
exit(1);
@@ -422,7 +421,6 @@
{
adb_thread_t thr;
int fdi, fd;
- int *fds;
fd = adb_connect("shell:");
if(fd < 0) {
@@ -431,7 +429,7 @@
}
fdi = 0; //dup(0);
- fds = malloc(sizeof(int) * 2);
+ int* fds = reinterpret_cast<int*>(malloc(sizeof(int) * 2));
fds[0] = fd;
fds[1] = fdi;
@@ -464,7 +462,6 @@
char buf[4096];
unsigned total;
int fd;
- const unsigned char *ptr;
sprintf(buf,"%s:%d", service, sz);
fd = adb_connect(buf);
@@ -477,7 +474,7 @@
opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
total = sz;
- ptr = data;
+ const uint8_t* ptr = reinterpret_cast<const uint8_t*>(data);
if(progress) {
char *x = strrchr(service, ':');
@@ -557,14 +554,15 @@
* we hang up.
*/
int adb_sideload_host(const char* fn) {
- uint8_t* data;
unsigned sz;
size_t xfer = 0;
int status;
+ int last_percent = -1;
+ int opt = SIDELOAD_HOST_BLOCK_SIZE;
printf("loading: '%s'", fn);
fflush(stdout);
- data = load_file(fn, &sz);
+ uint8_t* data = reinterpret_cast<uint8_t*>(load_file(fn, &sz));
if (data == 0) {
printf("\n");
fprintf(stderr, "* cannot read '%s' *\n", fn);
@@ -582,10 +580,8 @@
goto done;
}
- int opt = SIDELOAD_HOST_BLOCK_SIZE;
opt = adb_setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *) &opt, sizeof(opt));
- int last_percent = -1;
for (;;) {
if (!ReadFdExactly(fd, buf, 8)) {
fprintf(stderr, "* failed to read command: %s\n", adb_error());
@@ -739,13 +735,12 @@
* ppp dev:/dev/omap_csmi_tty0 <ppp options>
*
*/
-int ppp(int argc, char **argv)
+int ppp(int argc, const char **argv)
{
#if defined(_WIN32)
fprintf(stderr, "error: adb %s not implemented on Win32\n", argv[0]);
return -1;
#else
- char *adb_service_name;
pid_t pid;
int fd;
@@ -756,8 +751,7 @@
return 1;
}
- adb_service_name = argv[1];
-
+ const char* adb_service_name = argv[1];
fd = adb_connect(adb_service_name);
if(fd < 0) {
@@ -807,7 +801,8 @@
#endif /* !defined(_WIN32) */
}
-static int send_shellcommand(transport_type transport, char* serial, char* buf)
+static int send_shellcommand(transport_type transport, const char* serial,
+ char* buf)
{
int fd, ret;
@@ -828,7 +823,8 @@
return ret;
}
-static int logcat(transport_type transport, char* serial, int argc, char **argv)
+static int logcat(transport_type transport, const char* serial, int argc,
+ const char** argv)
{
char buf[4096];
@@ -877,7 +873,7 @@
return 0;
}
-static int backup(int argc, char** argv) {
+static int backup(int argc, const char** argv) {
char buf[4096];
char default_name[32];
const char* filename = strcpy(default_name, "./backup.ab");
@@ -933,7 +929,7 @@
return 0;
}
-static int restore(int argc, char** argv) {
+static int restore(int argc, const char** argv) {
const char* filename;
int fd, tarFd;
@@ -1102,8 +1098,9 @@
return path_buf;
}
-static void parse_push_pull_args(char **arg, int narg, char const **path1, char const **path2,
- int *show_progress, int *copy_attrs) {
+static void parse_push_pull_args(const char **arg, int narg, char const **path1,
+ char const **path2, int *show_progress,
+ int *copy_attrs) {
*show_progress = 0;
*copy_attrs = 0;
@@ -1130,7 +1127,7 @@
}
}
-int adb_commandline(int argc, char **argv)
+int adb_commandline(int argc, const char **argv)
{
char buf[4096];
int no_daemon = 0;
@@ -1139,8 +1136,8 @@
int persist = 0;
int r;
transport_type ttype = kTransportAny;
- char* serial = NULL;
- char* server_port_str = NULL;
+ const char* serial = NULL;
+ const char* server_port_str = NULL;
/* If defined, this should be an absolute path to
* the directory containing all of the various system images
@@ -1274,7 +1271,7 @@
/* handle wait-for-* prefix */
if (!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
- char* service = argv[0];
+ const char* service = argv[0];
if (!strncmp(service, "wait-for-device", strlen("wait-for-device"))) {
if (ttype == kTransportUsb) {
service = "wait-for-usb";
@@ -1308,7 +1305,7 @@
/* adb_connect() commands */
if (!strcmp(argv[0], "devices")) {
char *tmp;
- char *listopt;
+ const char *listopt;
if (argc < 2)
listopt = "";
else if (argc == 2 && !strcmp(argv[1], "-l"))
@@ -1635,7 +1632,8 @@
return uninstall_app(ttype, serial, argc, argv);
}
else if (!strcmp(argv[0], "sync")) {
- char *srcarg, *android_srcpath, *data_srcpath, *vendor_srcpath;
+ const char* srcarg;
+ char *android_srcpath, *data_srcpath, *vendor_srcpath;
int listonly = 0;
int ret;
@@ -1736,9 +1734,9 @@
}
#define MAX_ARGV_LENGTH 16
-static int do_cmd(transport_type ttype, char* serial, char *cmd, ...)
+static int do_cmd(transport_type ttype, const char* serial, const char *cmd, ...)
{
- char *argv[MAX_ARGV_LENGTH];
+ const char *argv[MAX_ARGV_LENGTH];
int argc;
va_list ap;
@@ -1818,8 +1816,8 @@
return 0;
}
-static int pm_command(transport_type transport, char* serial,
- int argc, char** argv)
+static int pm_command(transport_type transport, const char* serial,
+ int argc, const char** argv)
{
char buf[4096];
@@ -1836,7 +1834,8 @@
return 0;
}
-int uninstall_app(transport_type transport, char* serial, int argc, char** argv)
+int uninstall_app(transport_type transport, const char* serial, int argc,
+ const char** argv)
{
/* if the user choose the -k option, we refuse to do it until devices are
out with the option to uninstall the remaining data somehow (adb/ui) */
@@ -1854,7 +1853,7 @@
return pm_command(transport, serial, argc, argv);
}
-static int delete_file(transport_type transport, char* serial, char* filename)
+static int delete_file(transport_type transport, const char* serial, char* filename)
{
char buf[4096];
char* quoted;
@@ -1879,7 +1878,8 @@
}
}
-int install_app(transport_type transport, char* serial, int argc, char** argv)
+int install_app(transport_type transport, const char* serial, int argc,
+ const char** argv)
{
static const char *const DATA_DEST = "/data/local/tmp/%s";
static const char *const SD_DEST = "/sdcard/tmp/%s";
@@ -1897,7 +1897,7 @@
// All other arguments passed through verbatim.
int last_apk = -1;
for (i = argc - 1; i >= 0; i--) {
- char* file = argv[i];
+ const char* file = argv[i];
char* dot = strrchr(file, '.');
if (dot && !strcasecmp(dot, ".apk")) {
if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
@@ -1915,7 +1915,7 @@
return -1;
}
- char* apk_file = argv[last_apk];
+ const char* apk_file = argv[last_apk];
char apk_dest[PATH_MAX];
snprintf(apk_dest, sizeof apk_dest, where, get_basename(apk_file));
int err = do_sync_push(apk_file, apk_dest, 0 /* no show progress */);
@@ -1932,7 +1932,8 @@
return err;
}
-int install_multiple_app(transport_type transport, char* serial, int argc, char** argv)
+int install_multiple_app(transport_type transport, const char* serial, int argc,
+ const char** argv)
{
char buf[1024];
int i;
@@ -1943,7 +1944,7 @@
// All other arguments passed through verbatim.
int first_apk = -1;
for (i = argc - 1; i >= 0; i--) {
- char* file = argv[i];
+ const char* file = argv[i];
char* dot = strrchr(file, '.');
if (dot && !strcasecmp(dot, ".apk")) {
if (stat(file, &sb) == -1 || !S_ISREG(sb.st_mode)) {
@@ -1998,7 +1999,7 @@
// Valid session, now stream the APKs
int success = 1;
for (i = first_apk; i < argc; i++) {
- char* file = argv[i];
+ const char* file = argv[i];
if (stat(file, &sb) == -1) {
fprintf(stderr, "Failed to stat %s\n", file);
success = 0;
diff --git a/adb/console.c b/adb/console.cpp
similarity index 93%
rename from adb/console.c
rename to adb/console.cpp
index b813d33..452ee41 100644
--- a/adb/console.c
+++ b/adb/console.cpp
@@ -24,7 +24,7 @@
}
-int adb_send_emulator_command(int argc, char** argv)
+int adb_send_emulator_command(int argc, const char** argv)
{
int fd, nn;
diff --git a/adb/file_sync_client.c b/adb/file_sync_client.cpp
similarity index 97%
rename from adb/file_sync_client.c
rename to adb/file_sync_client.cpp
index 3a0c666..8ce4ee2 100644
--- a/adb/file_sync_client.c
+++ b/adb/file_sync_client.cpp
@@ -580,7 +580,8 @@
int ssize = slen + nlen + 2;
int dsize = dlen + nlen + 2;
- copyinfo *ci = malloc(sizeof(copyinfo) + ssize + dsize);
+ copyinfo *ci = reinterpret_cast<copyinfo*>(
+ malloc(sizeof(copyinfo) + ssize + dsize));
if(ci == 0) {
fprintf(stderr,"out of memory\n");
abort();
@@ -684,14 +685,14 @@
if((lpath[0] == 0) || (rpath[0] == 0)) return -1;
if(lpath[strlen(lpath) - 1] != '/') {
int tmplen = strlen(lpath)+2;
- char *tmp = malloc(tmplen);
+ char *tmp = reinterpret_cast<char*>(malloc(tmplen));
if(tmp == 0) return -1;
snprintf(tmp, tmplen, "%s/",lpath);
lpath = tmp;
}
if(rpath[strlen(rpath) - 1] != '/') {
int tmplen = strlen(rpath)+2;
- char *tmp = malloc(tmplen);
+ char *tmp = reinterpret_cast<char*>(malloc(tmplen));
if(tmp == 0) return -1;
snprintf(tmp, tmplen, "%s/",rpath);
rpath = tmp;
@@ -784,7 +785,8 @@
name++;
}
int tmplen = strlen(name) + strlen(rpath) + 2;
- char *tmp = malloc(strlen(name) + strlen(rpath) + 2);
+ char *tmp = reinterpret_cast<char*>(
+ malloc(strlen(name) + strlen(rpath) + 2));
if(tmp == 0) return 1;
snprintf(tmp, tmplen, "%s/%s", rpath, name);
rpath = tmp;
@@ -872,7 +874,7 @@
return 0;
}
-static int set_time_and_mode(const char *lpath, unsigned int time, unsigned int mode)
+static int set_time_and_mode(const char *lpath, time_t time, unsigned int mode)
{
struct utimbuf times = { time, time };
int r1 = utime(lpath, ×);
@@ -890,7 +892,7 @@
{
if (path[strlen(path) - 1] != '/') {
size_t len = strlen(path) + 2;
- char *path_with_slash = malloc(len);
+ char *path_with_slash = reinterpret_cast<char*>(malloc(len));
if (path_with_slash == NULL)
return NULL;
snprintf(path_with_slash, len, "%s/", path);
@@ -999,7 +1001,7 @@
name++;
}
int tmplen = strlen(name) + strlen(lpath) + 2;
- char *tmp = malloc(tmplen);
+ char *tmp = reinterpret_cast<char*>(malloc(tmplen));
if(tmp == 0) return 1;
snprintf(tmp, tmplen, "%s/%s", lpath, name);
lpath = tmp;
diff --git a/adb/file_sync_service.c b/adb/file_sync_service.cpp
similarity index 98%
rename from adb/file_sync_service.c
rename to adb/file_sync_service.cpp
index 0b289e8..2864b38 100644
--- a/adb/file_sync_service.c
+++ b/adb/file_sync_service.cpp
@@ -151,7 +151,7 @@
msg.dent.size = 0;
msg.dent.time = 0;
msg.dent.namelen = 0;
- return !WriteFdExactly(s, &msg.dent, sizeof(msg.dent)) ? 0 : -1;
+ return WriteFdExactly(s, &msg.dent, sizeof(msg.dent)) ? 0 : -1;
}
static int fail_message(int s, const char *reason)
@@ -420,7 +420,7 @@
char name[1025];
unsigned namelen;
- char *buffer = malloc(SYNC_DATA_MAX);
+ char *buffer = reinterpret_cast<char*>(malloc(SYNC_DATA_MAX));
if(buffer == 0) goto fail;
for(;;) {
diff --git a/adb/framebuffer_service.c b/adb/framebuffer_service.cpp
similarity index 98%
rename from adb/framebuffer_service.c
rename to adb/framebuffer_service.cpp
index 9d17d2c..7baad8b 100644
--- a/adb/framebuffer_service.c
+++ b/adb/framebuffer_service.cpp
@@ -62,10 +62,11 @@
int fd_screencap;
int w, h, f;
int fds[2];
+ pid_t pid;
if (pipe2(fds, O_CLOEXEC) < 0) goto pipefail;
- pid_t pid = fork();
+ pid = fork();
if (pid < 0) goto done;
if (pid == 0) {
diff --git a/adb/get_my_path_darwin.c b/adb/get_my_path_darwin.c
index ff1396c..b0c962e 100644
--- a/adb/get_my_path_darwin.c
+++ b/adb/get_my_path_darwin.c
@@ -17,6 +17,8 @@
#import <Carbon/Carbon.h>
#include <unistd.h>
+#include "adb.h"
+
void get_my_path(char *s, size_t maxLen)
{
CFBundleRef mainBundle = CFBundleGetMainBundle();
diff --git a/adb/get_my_path_linux.c b/adb/get_my_path_linux.cpp
similarity index 97%
rename from adb/get_my_path_linux.c
rename to adb/get_my_path_linux.cpp
index 179c3dd..11c0b21 100644
--- a/adb/get_my_path_linux.c
+++ b/adb/get_my_path_linux.cpp
@@ -14,10 +14,12 @@
* limitations under the License.
*/
-#include <sys/types.h>
-#include <unistd.h>
#include <limits.h>
#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "adb.h"
void get_my_path(char *exe, size_t maxLen)
{
diff --git a/adb/get_my_path_windows.c b/adb/get_my_path_windows.cpp
similarity index 97%
rename from adb/get_my_path_windows.c
rename to adb/get_my_path_windows.cpp
index ddf2816..9d23e1c 100644
--- a/adb/get_my_path_windows.c
+++ b/adb/get_my_path_windows.cpp
@@ -14,10 +14,12 @@
* limitations under the License.
*/
-#include <limits.h>
#include <assert.h>
+#include <limits.h>
#include <windows.h>
+#include "adb.h"
+
void get_my_path(char *exe, size_t maxLen)
{
char *r;
diff --git a/adb/jdwp_service.c b/adb/jdwp_service.cpp
similarity index 98%
rename from adb/jdwp_service.c
rename to adb/jdwp_service.cpp
index 3074e42..f0b4ba7 100644
--- a/adb/jdwp_service.c
+++ b/adb/jdwp_service.cpp
@@ -194,7 +194,8 @@
static JdwpProcess*
jdwp_process_alloc( int socket )
{
- JdwpProcess* proc = calloc(1,sizeof(*proc));
+ JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(
+ calloc(1, sizeof(*proc)));
if (proc == NULL) {
D("not enough memory to create new JDWP process\n");
@@ -234,7 +235,7 @@
static void
jdwp_process_event( int socket, unsigned events, void* _proc )
{
- JdwpProcess* proc = _proc;
+ JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc);
if (events & FDE_READ) {
if (proc->pid < 0) {
@@ -601,7 +602,7 @@
asocket*
create_jdwp_service_socket( void )
{
- JdwpSocket* s = calloc(sizeof(*s),1);
+ JdwpSocket* s = reinterpret_cast<JdwpSocket*>(calloc(sizeof(*s), 1));
if (s == NULL)
return NULL;
@@ -696,7 +697,7 @@
asocket*
create_jdwp_tracker_service_socket( void )
{
- JdwpTracker* t = calloc(sizeof(*t),1);
+ JdwpTracker* t = reinterpret_cast<JdwpTracker*>(calloc(sizeof(*t), 1));
if (t == NULL)
return NULL;
diff --git a/adb/qemu_tracing.c b/adb/qemu_tracing.cpp
similarity index 100%
rename from adb/qemu_tracing.c
rename to adb/qemu_tracing.cpp
diff --git a/adb/remount_service.c b/adb/remount_service.cpp
similarity index 100%
rename from adb/remount_service.c
rename to adb/remount_service.cpp
diff --git a/adb/services.c b/adb/services.cpp
similarity index 96%
rename from adb/services.c
rename to adb/services.cpp
index 84f2137..600eb30 100644
--- a/adb/services.c
+++ b/adb/services.cpp
@@ -51,7 +51,7 @@
void *service_bootstrap_func(void *x)
{
- stinfo *sti = x;
+ stinfo* sti = reinterpret_cast<stinfo*>(x);
sti->func(sti->fd, sti->cookie);
free(sti);
return 0;
@@ -161,7 +161,7 @@
void reverse_service(int fd, void* arg)
{
- const char* command = arg;
+ const char* command = reinterpret_cast<const char*>(arg);
if (handle_forward_request(command, kTransportAny, NULL, fd) < 0) {
sendfailmsg(fd, "not a reverse forwarding command");
@@ -174,23 +174,23 @@
static int create_service_thread(void (*func)(int, void *), void *cookie)
{
- stinfo *sti;
- adb_thread_t t;
int s[2];
-
- if(adb_socketpair(s)) {
+ if (adb_socketpair(s)) {
printf("cannot create service socket pair\n");
return -1;
}
D("socketpair: (%d,%d)", s[0], s[1]);
- sti = malloc(sizeof(stinfo));
- if(sti == 0) fatal("cannot allocate stinfo");
+ stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
+ if (sti == nullptr) {
+ fatal("cannot allocate stinfo");
+ }
sti->func = func;
sti->cookie = cookie;
sti->fd = s[1];
- if(adb_thread_create( &t, service_bootstrap_func, sti)){
+ adb_thread_t t;
+ if (adb_thread_create(&t, service_bootstrap_func, sti)) {
free(sti);
adb_close(s[0]);
adb_close(s[1]);
@@ -359,7 +359,6 @@
static int create_subproc_thread(const char *name, const subproc_mode mode)
{
- stinfo *sti;
adb_thread_t t;
int ret_fd;
pid_t pid = -1;
@@ -384,7 +383,7 @@
}
D("create_subproc ret_fd=%d pid=%d\n", ret_fd, pid);
- sti = malloc(sizeof(stinfo));
+ stinfo* sti = reinterpret_cast<stinfo*>(malloc(sizeof(stinfo)));
if(sti == 0) fatal("cannot allocate stinfo");
sti->func = subproc_waiter_service;
sti->cookie = (void*) (uintptr_t) pid;
@@ -512,11 +511,11 @@
static void wait_for_state(int fd, void* cookie)
{
- struct state_info* sinfo = cookie;
- char* err = "unknown error";
+ state_info* sinfo = reinterpret_cast<state_info*>(cookie);
D("wait_for_state %d\n", sinfo->state);
+ const char* err = "unknown error";
atransport *t = acquire_one_transport(sinfo->state, sinfo->transport, sinfo->serial, &err);
if(t != 0) {
WriteFdExactly(fd, "OKAY", 4);
@@ -635,7 +634,7 @@
{
char buf[4096];
char resp[4096];
- char *host = cookie;
+ char *host = reinterpret_cast<char*>(cookie);
if (!strncmp(host, "emu:", 4)) {
connect_emulator(host + 4, buf, sizeof(buf));
@@ -656,7 +655,7 @@
if (!strcmp(name,"track-devices")) {
return create_device_tracker();
} else if (!strncmp(name, "wait-for-", strlen("wait-for-"))) {
- struct state_info* sinfo = malloc(sizeof(struct state_info));
+ auto sinfo = reinterpret_cast<state_info*>(malloc(sizeof(state_info)));
if (serial)
sinfo->serial = strdup(serial);
diff --git a/adb/set_verity_enable_state_service.c b/adb/set_verity_enable_state_service.cpp
similarity index 98%
rename from adb/set_verity_enable_state_service.c
rename to adb/set_verity_enable_state_service.cpp
index 184674d..85637f2 100644
--- a/adb/set_verity_enable_state_service.c
+++ b/adb/set_verity_enable_state_service.cpp
@@ -90,7 +90,7 @@
uint32_t magic_number;
const uint32_t new_magic = enable ? VERITY_METADATA_MAGIC_NUMBER
: VERITY_METADATA_MAGIC_DISABLE;
- uint64_t device_length;
+ uint64_t device_length = 0;
int device = -1;
int retval = -1;
@@ -140,7 +140,7 @@
if (magic_number != VERITY_METADATA_MAGIC_NUMBER
&& magic_number != VERITY_METADATA_MAGIC_DISABLE) {
write_console(fd,
- "Couldn't find verity metadata at offset %"PRIu64"!\n",
+ "Couldn't find verity metadata at offset %" PRIu64 "!\n",
device_length);
goto errout;
}
diff --git a/adb/sockets.c b/adb/sockets.cpp
similarity index 92%
rename from adb/sockets.c
rename to adb/sockets.cpp
index d34f8c6..12bc8d8 100644
--- a/adb/sockets.c
+++ b/adb/sockets.cpp
@@ -284,98 +284,101 @@
insert_local_socket(s, &local_socket_closing_list);
}
-static void local_socket_event_func(int fd, unsigned ev, void *_s)
+static void local_socket_event_func(int fd, unsigned ev, void* _s)
{
- asocket *s = _s;
-
+ asocket* s = reinterpret_cast<asocket*>(_s);
D("LS(%d): event_func(fd=%d(==%d), ev=%04x)\n", s->id, s->fd, fd, ev);
/* put the FDE_WRITE processing before the FDE_READ
** in order to simplify the code.
*/
- if(ev & FDE_WRITE){
- apacket *p;
-
- while((p = s->pkt_first) != 0) {
- while(p->len > 0) {
+ if (ev & FDE_WRITE) {
+ apacket* p;
+ while ((p = s->pkt_first) != nullptr) {
+ while (p->len > 0) {
int r = adb_write(fd, p->ptr, p->len);
- if(r > 0) {
+ if (r == -1) {
+ /* returning here is ok because FDE_READ will
+ ** be processed in the next iteration loop
+ */
+ if (errno == EAGAIN) {
+ return;
+ }
+ } else if (r > 0) {
p->ptr += r;
p->len -= r;
continue;
}
- if(r < 0) {
- /* returning here is ok because FDE_READ will
- ** be processed in the next iteration loop
- */
- if(errno == EAGAIN) return;
- if(errno == EINTR) continue;
- }
+
D(" closing after write because r=%d and errno is %d\n", r, errno);
s->close(s);
return;
}
- if(p->len == 0) {
+ if (p->len == 0) {
s->pkt_first = p->next;
- if(s->pkt_first == 0) s->pkt_last = 0;
+ if (s->pkt_first == 0) {
+ s->pkt_last = 0;
+ }
put_apacket(p);
}
}
- /* if we sent the last packet of a closing socket,
- ** we can now destroy it.
- */
+ /* if we sent the last packet of a closing socket,
+ ** we can now destroy it.
+ */
if (s->closing) {
D(" closing because 'closing' is set after write\n");
s->close(s);
return;
}
- /* no more packets queued, so we can ignore
- ** writable events again and tell our peer
- ** to resume writing
- */
+ /* no more packets queued, so we can ignore
+ ** writable events again and tell our peer
+ ** to resume writing
+ */
fdevent_del(&s->fde, FDE_WRITE);
s->peer->ready(s->peer);
}
- if(ev & FDE_READ){
+ if (ev & FDE_READ) {
apacket *p = get_apacket();
unsigned char *x = p->data;
size_t avail = MAX_PAYLOAD;
int r;
int is_eof = 0;
- while(avail > 0) {
+ while (avail > 0) {
r = adb_read(fd, x, avail);
- D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu\n", s->id, s->fd, r, r<0?errno:0, avail);
- if(r > 0) {
+ D("LS(%d): post adb_read(fd=%d,...) r=%d (errno=%d) avail=%zu\n",
+ s->id, s->fd, r, r < 0 ? errno : 0, avail);
+ if (r == -1) {
+ if (errno == EAGAIN) {
+ break;
+ }
+ } else if (r > 0) {
avail -= r;
x += r;
continue;
}
- if(r < 0) {
- if(errno == EAGAIN) break;
- if(errno == EINTR) continue;
- }
- /* r = 0 or unhandled error */
+ /* r = 0 or unhandled error */
is_eof = 1;
break;
}
D("LS(%d): fd=%d post avail loop. r=%d is_eof=%d forced_eof=%d\n",
s->id, s->fd, r, is_eof, s->fde.force_eof);
- if((avail == MAX_PAYLOAD) || (s->peer == 0)) {
+ if ((avail == MAX_PAYLOAD) || (s->peer == 0)) {
put_apacket(p);
} else {
p->len = MAX_PAYLOAD - avail;
r = s->peer->enqueue(s->peer, p);
- D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd, r);
+ D("LS(%d): fd=%d post peer->enqueue(). r=%d\n", s->id, s->fd,
+ r);
- if(r < 0) {
+ if (r < 0) {
/* error return means they closed us as a side-effect
** and we must return immediately.
**
@@ -387,7 +390,7 @@
return;
}
- if(r > 0) {
+ if (r > 0) {
/* if the remote cannot accept further events,
** we disable notification of READs. They'll
** be enabled again when we get a call to ready()
@@ -396,13 +399,14 @@
}
}
/* Don't allow a forced eof if data is still there */
- if((s->fde.force_eof && !r) || is_eof) {
- D(" closing because is_eof=%d r=%d s->fde.force_eof=%d\n", is_eof, r, s->fde.force_eof);
+ if ((s->fde.force_eof && !r) || is_eof) {
+ D(" closing because is_eof=%d r=%d s->fde.force_eof=%d\n",
+ is_eof, r, s->fde.force_eof);
s->close(s);
}
}
- if(ev & FDE_ERROR){
+ if (ev & FDE_ERROR){
/* this should be caught be the next read or write
** catching it here means we may skip the last few
** bytes of readable data.
@@ -415,7 +419,7 @@
asocket *create_local_socket(int fd)
{
- asocket *s = calloc(1, sizeof(asocket));
+ asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket)));
if (s == NULL) fatal("cannot allocate socket");
s->fd = fd;
s->enqueue = local_socket_enqueue;
@@ -539,8 +543,8 @@
static void remote_socket_disconnect(void* _s, atransport* t)
{
- asocket* s = _s;
- asocket* peer = s->peer;
+ asocket* s = reinterpret_cast<asocket*>(_s);
+ asocket* peer = s->peer;
D("remote_socket_disconnect RS(%d)\n", s->id);
if (peer) {
@@ -557,12 +561,9 @@
Returns a new non-NULL asocket handle. */
asocket *create_remote_socket(unsigned id, atransport *t)
{
- asocket* s;
- adisconnect* dis;
-
if (id == 0) fatal("invalid remote socket id (0)");
- s = calloc(1, sizeof(aremotesocket));
- dis = &((aremotesocket*)s)->disconnect;
+ asocket* s = reinterpret_cast<asocket*>(calloc(1, sizeof(aremotesocket)));
+ adisconnect* dis = &reinterpret_cast<aremotesocket*>(s)->disconnect;
if (s == NULL) fatal("cannot allocate socket");
s->id = id;
@@ -824,7 +825,7 @@
}
#else /* !ADB_HOST */
if (s->transport == NULL) {
- char* error_string = "unknown failure";
+ const char* error_string = "unknown failure";
s->transport = acquire_one_transport (CS_ANY,
kTransportAny, NULL, &error_string);
@@ -892,7 +893,7 @@
static asocket *create_smart_socket(void)
{
D("Creating smart socket \n");
- asocket *s = calloc(1, sizeof(asocket));
+ asocket *s = reinterpret_cast<asocket*>(calloc(1, sizeof(asocket)));
if (s == NULL) fatal("cannot allocate socket");
s->enqueue = smart_socket_enqueue;
s->ready = smart_socket_ready;
diff --git a/adb/test_track_devices.c b/adb/test_track_devices.cpp
similarity index 100%
rename from adb/test_track_devices.c
rename to adb/test_track_devices.cpp
diff --git a/adb/test_track_jdwp.c b/adb/test_track_jdwp.cpp
similarity index 100%
rename from adb/test_track_jdwp.c
rename to adb/test_track_jdwp.cpp
diff --git a/adb/tests/test_adb.py b/adb/tests/test_adb.py
index 49ead73..f111b043 100755
--- a/adb/tests/test_adb.py
+++ b/adb/tests/test_adb.py
@@ -237,16 +237,36 @@
version_num = True
self.assertTrue(version_num)
- def test_root_unroot(self):
- """Make sure that adb root and adb unroot work, using id(1)."""
+ def _test_root(self):
adb = AdbWrapper()
adb.root()
adb.wait()
self.assertEqual("root", adb.shell("id -un").strip())
+
+ def _test_unroot(self):
+ adb = AdbWrapper()
adb.unroot()
adb.wait()
self.assertEqual("shell", adb.shell("id -un").strip())
+ def test_root_unroot(self):
+ """Make sure that adb root and adb unroot work, using id(1)."""
+ adb = AdbWrapper()
+ original_user = adb.shell("id -un").strip()
+ try:
+ if original_user == "root":
+ self._test_unroot()
+ self._test_root()
+ elif original_user == "shell":
+ self._test_root()
+ self._test_unroot()
+ finally:
+ if original_user == "root":
+ adb.root()
+ else:
+ adb.unroot()
+ adb.wait()
+
class AdbFile(unittest.TestCase):
SCRATCH_DIR = "/data/local/tmp"
diff --git a/adb/transport.c b/adb/transport.cpp
similarity index 97%
rename from adb/transport.c
rename to adb/transport.cpp
index e2c204e..1f8ac03 100644
--- a/adb/transport.c
+++ b/adb/transport.cpp
@@ -221,7 +221,7 @@
static void transport_socket_events(int fd, unsigned events, void *_t)
{
- atransport *t = _t;
+ atransport *t = reinterpret_cast<atransport*>(_t);
D("transport_socket_events(fd=%d, events=%04x,...)\n", fd, events);
if(events & FDE_READ){
apacket *p = 0;
@@ -278,7 +278,7 @@
static void *output_thread(void *_t)
{
- atransport *t = _t;
+ atransport *t = reinterpret_cast<atransport*>(_t);
apacket *p;
D("%s: starting transport output thread on fd %d, SYNC online (%d)\n",
@@ -333,7 +333,7 @@
static void *input_thread(void *_t)
{
- atransport *t = _t;
+ atransport *t = reinterpret_cast<atransport*>(_t);
apacket *p;
int active = 0;
@@ -494,7 +494,8 @@
asocket*
create_device_tracker(void)
{
- device_tracker* tracker = calloc(1,sizeof(*tracker));
+ device_tracker* tracker = reinterpret_cast<device_tracker*>(
+ calloc(1, sizeof(*tracker)));
if(tracker == 0) fatal("cannot allocate device tracker");
@@ -799,7 +800,8 @@
return !*to_test;
}
-atransport *acquire_one_transport(int state, transport_type ttype, const char* serial, char** error_out)
+atransport *acquire_one_transport(int state, transport_type ttype,
+ const char* serial, const char** error_out)
{
atransport *t;
atransport *result = NULL;
@@ -1007,7 +1009,8 @@
int register_socket_transport(int s, const char *serial, int port, int local)
{
- atransport *t = calloc(1, sizeof(atransport));
+ atransport *t = reinterpret_cast<atransport*>(
+ calloc(1, sizeof(atransport)));
atransport *n;
char buff[32];
@@ -1106,7 +1109,8 @@
void register_usb_transport(usb_handle *usb, const char *serial, const char *devpath, unsigned writeable)
{
- atransport *t = calloc(1, sizeof(atransport));
+ atransport *t = reinterpret_cast<atransport*>(
+ calloc(1, sizeof(atransport)));
D("transport: %p init'ing for usb_handle %p (sn='%s')\n", t, usb,
serial ? serial : "");
init_usb_transport(t, usb, (writeable ? CS_OFFLINE : CS_NOPERM));
diff --git a/adb/transport.h b/adb/transport.h
index 352bbe4..36a0e40 100644
--- a/adb/transport.h
+++ b/adb/transport.h
@@ -37,7 +37,7 @@
* If no suitable transport is found, error is set.
*/
atransport* acquire_one_transport(int state, transport_type ttype,
- const char* serial, char** error_out);
+ const char* serial, const char** error_out);
void add_transport_disconnect(atransport* t, adisconnect* dis);
void remove_transport_disconnect(atransport* t, adisconnect* dis);
void kick_transport(atransport* t);
diff --git a/adb/transport_local.c b/adb/transport_local.cpp
similarity index 100%
rename from adb/transport_local.c
rename to adb/transport_local.cpp
diff --git a/adb/transport_usb.c b/adb/transport_usb.cpp
similarity index 100%
rename from adb/transport_usb.c
rename to adb/transport_usb.cpp
diff --git a/adb/usb_linux.c b/adb/usb_linux.cpp
similarity index 98%
rename from adb/usb_linux.c
rename to adb/usb_linux.cpp
index d03f8be..c01ec8c 100644
--- a/adb/usb_linux.c
+++ b/adb/usb_linux.cpp
@@ -574,7 +574,6 @@
unsigned char ep_in, unsigned char ep_out,
int interface, int serial_index, unsigned zero_mask)
{
- usb_handle* usb = 0;
int n = 0;
char serial[256];
@@ -587,8 +586,9 @@
** name, we have no further work to do.
*/
adb_mutex_lock(&usb_lock);
- for(usb = handle_list.next; usb != &handle_list; usb = usb->next){
- if(!strcmp(usb->fname, dev_name)) {
+ for (usb_handle* usb = handle_list.next; usb != &handle_list;
+ usb = usb->next) {
+ if (!strcmp(usb->fname, dev_name)) {
adb_mutex_unlock(&usb_lock);
return;
}
@@ -597,7 +597,8 @@
D("[ usb located new device %s (%d/%d/%d) ]\n",
dev_name, ep_in, ep_out, interface);
- usb = calloc(1, sizeof(usb_handle));
+ usb_handle* usb = reinterpret_cast<usb_handle*>(
+ calloc(1, sizeof(usb_handle)));
strcpy(usb->fname, dev_name);
usb->ep_in = ep_in;
usb->ep_out = ep_out;
diff --git a/adb/usb_windows.c b/adb/usb_windows.cpp
similarity index 100%
rename from adb/usb_windows.c
rename to adb/usb_windows.cpp
diff --git a/adf/libadf/Android.mk b/adf/libadf/Android.mk
index 908aa6c..7df354b 100644
--- a/adf/libadf/Android.mk
+++ b/adf/libadf/Android.mk
@@ -18,6 +18,7 @@
LOCAL_SRC_FILES := adf.c
LOCAL_MODULE := libadf
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS += -Werror
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += $(LOCAL_EXPORT_C_INCLUDE_DIRS)
include $(BUILD_STATIC_LIBRARY)
diff --git a/adf/libadf/tests/Android.mk b/adf/libadf/tests/Android.mk
index 93efafa..68e5817 100644
--- a/adf/libadf/tests/Android.mk
+++ b/adf/libadf/tests/Android.mk
@@ -19,4 +19,5 @@
LOCAL_SRC_FILES := adf_test.cpp
LOCAL_MODULE := adf-unit-tests
LOCAL_STATIC_LIBRARIES := libadf
+LOCAL_CFLAGS += -Werror
include $(BUILD_NATIVE_TEST)
diff --git a/adf/libadf/tests/adf_test.cpp b/adf/libadf/tests/adf_test.cpp
index d95330d..01b2785 100644
--- a/adf/libadf/tests/adf_test.cpp
+++ b/adf/libadf/tests/adf_test.cpp
@@ -182,9 +182,9 @@
ASSERT_GE(err, 0) << "getting ADF device data failed: " << strerror(-err);
EXPECT_LT(data.n_attachments, ADF_MAX_ATTACHMENTS);
- EXPECT_GT(data.n_allowed_attachments, 0);
+ EXPECT_GT(data.n_allowed_attachments, 0U);
EXPECT_LT(data.n_allowed_attachments, ADF_MAX_ATTACHMENTS);
- EXPECT_LT(data.custom_data_size, ADF_MAX_CUSTOM_DATA_SIZE);
+ EXPECT_LT(data.custom_data_size, (size_t)ADF_MAX_CUSTOM_DATA_SIZE);
adf_free_device_data(&data);
}
@@ -195,8 +195,8 @@
EXPECT_LT(data.type, ADF_INTF_TYPE_MAX);
EXPECT_LE(data.dpms_state, DRM_MODE_DPMS_OFF);
EXPECT_EQ(1, data.hotplug_detect);
- EXPECT_GT(data.n_available_modes, 0);
- EXPECT_LT(data.custom_data_size, ADF_MAX_CUSTOM_DATA_SIZE);
+ EXPECT_GT(data.n_available_modes, 0U);
+ EXPECT_LT(data.custom_data_size, (size_t)ADF_MAX_CUSTOM_DATA_SIZE);
adf_free_interface_data(&data);
}
@@ -206,9 +206,9 @@
ASSERT_GE(err, 0) << "getting ADF overlay engine failed: " <<
strerror(-err);
- EXPECT_GT(data.n_supported_formats, 0);
+ EXPECT_GT(data.n_supported_formats, 0U);
EXPECT_LT(data.n_supported_formats, ADF_MAX_SUPPORTED_FORMATS);
- EXPECT_LT(data.custom_data_size, ADF_MAX_CUSTOM_DATA_SIZE);
+ EXPECT_LT(data.custom_data_size, (size_t)ADF_MAX_CUSTOM_DATA_SIZE);
adf_free_overlay_engine_data(&data);
}
diff --git a/adf/libadfhwc/Android.mk b/adf/libadfhwc/Android.mk
index acea322..898f9c9 100644
--- a/adf/libadfhwc/Android.mk
+++ b/adf/libadfhwc/Android.mk
@@ -19,7 +19,7 @@
LOCAL_MODULE := libadfhwc
LOCAL_MODULE_TAGS := optional
LOCAL_STATIC_LIBRARIES := libadf liblog libutils
-LOCAL_CFLAGS += -DLOG_TAG=\"adfhwc\"
+LOCAL_CFLAGS += -DLOG_TAG=\"adfhwc\" -Werror
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
LOCAL_C_INCLUDES += $(LOCAL_EXPORT_C_INCLUDE_DIRS)
include $(BUILD_STATIC_LIBRARY)
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index fbaac39..8cc4682 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -12,7 +12,7 @@
LOCAL_SRC_FILES_arm := arm/machine.cpp
LOCAL_SRC_FILES_arm64 := arm64/machine.cpp
LOCAL_SRC_FILES_mips := mips/machine.cpp
-LOCAL_SRC_FILES_mips64 := mips/machine.cpp
+LOCAL_SRC_FILES_mips64 := mips64/machine.cpp
LOCAL_SRC_FILES_x86 := x86/machine.cpp
LOCAL_SRC_FILES_x86_64 := x86_64/machine.cpp
@@ -49,7 +49,7 @@
LOCAL_SRC_FILES_arm := arm/crashglue.S
LOCAL_SRC_FILES_arm64 := arm64/crashglue.S
LOCAL_SRC_FILES_mips := mips/crashglue.S
-LOCAL_SRC_FILES_mips64 := mips/crashglue.S
+LOCAL_SRC_FILES_mips64 := mips64/crashglue.S
LOCAL_SRC_FILES_x86 := x86/crashglue.S
LOCAL_SRC_FILES_x86_64 := x86_64/crashglue.S
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
diff --git a/debuggerd/mips64/crashglue.S b/debuggerd/mips64/crashglue.S
new file mode 100644
index 0000000..70a6641
--- /dev/null
+++ b/debuggerd/mips64/crashglue.S
@@ -0,0 +1,48 @@
+ .set noat
+
+ .globl crash1
+ .globl crashnostack
+
+crash1:
+ li $0,0xdead0000+0
+ li $1,0xdead0000+1
+ li $2,0xdead0000+2
+ li $3,0xdead0000+3
+ li $4,0xdead0000+4
+ li $5,0xdead0000+5
+ li $6,0xdead0000+6
+ li $7,0xdead0000+7
+ li $8,0xdead0000+8
+ li $9,0xdead0000+9
+ li $10,0xdead0000+10
+ li $11,0xdead0000+11
+ li $12,0xdead0000+12
+ li $13,0xdead0000+13
+ li $14,0xdead0000+14
+ li $15,0xdead0000+15
+ li $16,0xdead0000+16
+ li $17,0xdead0000+17
+ li $18,0xdead0000+18
+ li $19,0xdead0000+19
+ li $20,0xdead0000+20
+ li $21,0xdead0000+21
+ li $22,0xdead0000+22
+ li $23,0xdead0000+23
+ li $24,0xdead0000+24
+ li $25,0xdead0000+25
+ li $26,0xdead0000+26
+ li $27,0xdead0000+27
+ li $28,0xdead0000+28
+ # don't trash the stack otherwise the signal handler won't run
+ #li $29,0xdead0000+29
+ li $30,0xdead0000+30
+ li $31,0xdead0000+31
+
+ lw $zero,($0)
+ b .
+
+
+crashnostack:
+ li $sp, 0
+ lw $zero,($0)
+ b .
diff --git a/debuggerd/mips64/machine.cpp b/debuggerd/mips64/machine.cpp
new file mode 100644
index 0000000..ef9092f
--- /dev/null
+++ b/debuggerd/mips64/machine.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2014, 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 <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/ptrace.h>
+
+#include <sys/user.h>
+
+#include "../utility.h"
+#include "../machine.h"
+
+#define R(x) (static_cast<unsigned long>(x))
+
+// If configured to do so, dump memory around *all* registers
+// for the crashing thread.
+void dump_memory_and_code(log_t* log, pid_t tid) {
+ pt_regs r;
+ if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
+ return;
+ }
+
+ static const char REG_NAMES[] = "$0atv0v1a0a1a2a3a4a5a6a7t0t1t2t3s0s1s2s3s4s5s6s7t8t9k0k1gpsps8ra";
+
+ for (int reg = 0; reg < 32; reg++) {
+ // skip uninteresting registers
+ if (reg == 0 // $0
+ || reg == 26 // $k0
+ || reg == 27 // $k1
+ || reg == 31 // $ra (done below)
+ )
+ continue;
+
+ uintptr_t addr = R(r.regs[reg]);
+
+ // Don't bother if it looks like a small int or ~= null, or if
+ // it's in the kernel area.
+ if (addr < 4096 || addr >= 0x4000000000000000) {
+ continue;
+ }
+
+ _LOG(log, logtype::MEMORY, "\nmemory near %.2s:\n", ®_NAMES[reg * 2]);
+ dump_memory(log, tid, addr);
+ }
+
+ unsigned long pc = R(r.cp0_epc);
+ unsigned long ra = R(r.regs[31]);
+
+ _LOG(log, logtype::MEMORY, "\ncode around pc:\n");
+ dump_memory(log, tid, (uintptr_t)pc);
+
+ if (pc != ra) {
+ _LOG(log, logtype::MEMORY, "\ncode around ra:\n");
+ dump_memory(log, tid, (uintptr_t)ra);
+ }
+}
+
+void dump_registers(log_t* log, pid_t tid) {
+ pt_regs r;
+ if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
+ _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ return;
+ }
+
+ _LOG(log, logtype::REGISTERS, " zr %016lx at %016lx v0 %016lx v1 %016lx\n",
+ R(r.regs[0]), R(r.regs[1]), R(r.regs[2]), R(r.regs[3]));
+ _LOG(log, logtype::REGISTERS, " a0 %016lx a1 %016lx a2 %016lx a3 %016lx\n",
+ R(r.regs[4]), R(r.regs[5]), R(r.regs[6]), R(r.regs[7]));
+ _LOG(log, logtype::REGISTERS, " a4 %016lx a5 %016lx a6 %016lx a7 %016lx\n",
+ R(r.regs[8]), R(r.regs[9]), R(r.regs[10]), R(r.regs[11]));
+ _LOG(log, logtype::REGISTERS, " t0 %016lx t1 %016lx t2 %016lx t3 %016lx\n",
+ R(r.regs[12]), R(r.regs[13]), R(r.regs[14]), R(r.regs[15]));
+ _LOG(log, logtype::REGISTERS, " s0 %016lx s1 %016lx s2 %016lx s3 %016lx\n",
+ R(r.regs[16]), R(r.regs[17]), R(r.regs[18]), R(r.regs[19]));
+ _LOG(log, logtype::REGISTERS, " s4 %016lx s5 %016lx s6 %016lx s7 %016lx\n",
+ R(r.regs[20]), R(r.regs[21]), R(r.regs[22]), R(r.regs[23]));
+ _LOG(log, logtype::REGISTERS, " t8 %016lx t9 %016lx k0 %016lx k1 %016lx\n",
+ R(r.regs[24]), R(r.regs[25]), R(r.regs[26]), R(r.regs[27]));
+ _LOG(log, logtype::REGISTERS, " gp %016lx sp %016lx s8 %016lx ra %016lx\n",
+ R(r.regs[28]), R(r.regs[29]), R(r.regs[30]), R(r.regs[31]));
+ _LOG(log, logtype::REGISTERS, " hi %016lx lo %016lx bva %016lx epc %016lx\n",
+ R(r.hi), R(r.lo), R(r.cp0_badvaddr), R(r.cp0_epc));
+}
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index 58a882c..49b46e8 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -26,8 +26,10 @@
#define ABI_STRING "arm"
#elif defined(__aarch64__)
#define ABI_STRING "arm64"
-#elif defined(__mips__)
+#elif defined(__mips__) && !defined(__LP64__)
#define ABI_STRING "mips"
+#elif defined(__mips__) && defined(__LP64__)
+#define ABI_STRING "mips64"
#elif defined(__i386__)
#define ABI_STRING "x86"
#elif defined(__x86_64__)
diff --git a/fs_mgr/fs_mgr.c b/fs_mgr/fs_mgr.c
index f9a6ba2..d4daed6 100644
--- a/fs_mgr/fs_mgr.c
+++ b/fs_mgr/fs_mgr.c
@@ -154,9 +154,10 @@
} else if (!strcmp(fs_type, "f2fs")) {
char *f2fs_fsck_argv[] = {
F2FS_FSCK_BIN,
+ "-f",
blk_device
};
- INFO("Running %s on %s\n", F2FS_FSCK_BIN, blk_device);
+ INFO("Running %s -f %s\n", F2FS_FSCK_BIN, blk_device);
ret = android_fork_execvp_ext(ARRAY_SIZE(f2fs_fsck_argv), f2fs_fsck_argv,
&status, true, LOG_KLOG | LOG_FILE,
@@ -490,7 +491,9 @@
/* Deal with encryptability. */
if (!mret) {
/* If this is encryptable, need to trigger encryption */
- if (fs_mgr_is_encryptable(&fstab->recs[attempted_idx])) {
+ if ( (fstab->recs[attempted_idx].fs_mgr_flags & MF_FORCECRYPT)
+ || (device_is_force_encrypted()
+ && fs_mgr_is_encryptable(&fstab->recs[attempted_idx]))) {
if (umount(fstab->recs[attempted_idx].mount_point) == 0) {
if (encryptable == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
ERROR("Will try to encrypt %s %s\n", fstab->recs[attempted_idx].mount_point,
diff --git a/fs_mgr/fs_mgr_fstab.c b/fs_mgr/fs_mgr_fstab.c
index 9d536bd..ab8f128 100644
--- a/fs_mgr/fs_mgr_fstab.c
+++ b/fs_mgr/fs_mgr_fstab.c
@@ -428,11 +428,6 @@
return fstab->fs_mgr_flags & (MF_CRYPT | MF_FORCECRYPT);
}
-int fs_mgr_is_force_encrypted(struct fstab_rec *fstab)
-{
- return fstab->fs_mgr_flags & MF_FORCECRYPT;
-}
-
int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab)
{
return fstab->fs_mgr_flags & MF_NOEMULATEDSD;
diff --git a/fs_mgr/fs_mgr_verity.c b/fs_mgr/fs_mgr_verity.c
index 028791c..feb3c19 100644
--- a/fs_mgr/fs_mgr_verity.c
+++ b/fs_mgr/fs_mgr_verity.c
@@ -101,11 +101,11 @@
static int verify_table(char *signature, char *table, int table_length)
{
RSAPublicKey *key;
- uint8_t hash_buf[SHA_DIGEST_SIZE];
+ uint8_t hash_buf[SHA256_DIGEST_SIZE];
int retval = -1;
// Hash the table
- SHA_hash((uint8_t*)table, table_length, hash_buf);
+ SHA256_hash((uint8_t*)table, table_length, hash_buf);
// Now get the public key from the keyfile
key = load_key(VERITY_TABLE_RSA_KEY);
@@ -119,7 +119,7 @@
(uint8_t*) signature,
RSANUMBYTES,
(uint8_t*) hash_buf,
- SHA_DIGEST_SIZE)) {
+ SHA256_DIGEST_SIZE)) {
ERROR("Couldn't verify table.");
goto out;
}
@@ -381,27 +381,6 @@
return -1;
}
-static int set_verified_property(char *name) {
- int ret;
- char *key;
- ret = asprintf(&key, "partition.%s.verified", name);
- if (ret < 0) {
- ERROR("Error formatting verified property\n");
- return ret;
- }
- ret = PROP_NAME_MAX - strlen(key);
- if (ret < 0) {
- ERROR("Verified property name is too long\n");
- free(key);
- return -1;
- }
- ret = property_set(key, "1");
- if (ret < 0)
- ERROR("Error setting verified property %s: %d\n", key, ret);
- free(key);
- return ret;
-}
-
static int check_verity_restart(const char *fname)
{
char buffer[VERITY_KMSG_BUFSIZE + 1];
@@ -774,12 +753,7 @@
goto out;
}
- if (mode == VERITY_MODE_LOGGING) {
- retval = FS_MGR_SETUP_VERITY_SUCCESS;
- } else {
- // set the property indicating that the partition is verified
- retval = set_verified_property(mount_point);
- }
+ retval = FS_MGR_SETUP_VERITY_SUCCESS;
out:
if (fd != -1) {
diff --git a/fs_mgr/include/fs_mgr.h b/fs_mgr/include/fs_mgr.h
index 57600ef..0437d45 100644
--- a/fs_mgr/include/fs_mgr.h
+++ b/fs_mgr/include/fs_mgr.h
@@ -93,7 +93,6 @@
int fs_mgr_is_nonremovable(struct fstab_rec *fstab);
int fs_mgr_is_verified(struct fstab_rec *fstab);
int fs_mgr_is_encryptable(struct fstab_rec *fstab);
-int fs_mgr_is_force_encrypted(struct fstab_rec *fstab);
int fs_mgr_is_noemulatedsd(struct fstab_rec *fstab);
int fs_mgr_swapon_all(struct fstab *fstab);
#ifdef __cplusplus
diff --git a/healthd/BatteryMonitor.cpp b/healthd/BatteryMonitor.cpp
index 06497c2..7ea8250 100644
--- a/healthd/BatteryMonitor.cpp
+++ b/healthd/BatteryMonitor.cpp
@@ -265,10 +265,10 @@
"battery none");
}
- KLOG_INFO(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
- props.chargerAcOnline ? "a" : "",
- props.chargerUsbOnline ? "u" : "",
- props.chargerWirelessOnline ? "w" : "");
+ KLOG_WARNING(LOG_TAG, "%s chg=%s%s%s\n", dmesgline,
+ props.chargerAcOnline ? "a" : "",
+ props.chargerUsbOnline ? "u" : "",
+ props.chargerWirelessOnline ? "w" : "");
}
healthd_mode_ops->battery_update(&props);
@@ -511,7 +511,7 @@
if (!mChargerNames.size())
KLOG_ERROR(LOG_TAG, "No charger supplies found\n");
if (!mBatteryDevicePresent) {
- KLOG_INFO(LOG_TAG, "No battery devices found\n");
+ KLOG_WARNING(LOG_TAG, "No battery devices found\n");
hc->periodic_chores_interval_fast = -1;
hc->periodic_chores_interval_slow = -1;
} else {
diff --git a/healthd/healthd.cpp b/healthd/healthd.cpp
index b34583d..1fee855 100644
--- a/healthd/healthd.cpp
+++ b/healthd/healthd.cpp
@@ -53,6 +53,7 @@
.batteryCurrentAvgPath = String8(String8::kEmptyString),
.batteryChargeCounterPath = String8(String8::kEmptyString),
.energyCounter = NULL,
+ .screen_on = NULL,
};
static int eventct;
@@ -313,8 +314,8 @@
return -1;
}
- healthd_mode_ops->init(&healthd_config);
healthd_board_init(&healthd_config);
+ healthd_mode_ops->init(&healthd_config);
wakealarm_init();
uevent_init();
gBatteryMonitor = new BatteryMonitor();
diff --git a/healthd/healthd.h b/healthd/healthd.h
index 972e728..4704f0b 100644
--- a/healthd/healthd.h
+++ b/healthd/healthd.h
@@ -67,6 +67,7 @@
android::String8 batteryChargeCounterPath;
int (*energyCounter)(int64_t *);
+ bool (*screen_on)(android::BatteryProperties *props);
};
// Global helper functions
diff --git a/healthd/healthd_mode_charger.cpp b/healthd/healthd_mode_charger.cpp
index 291cb6c..9ed5944 100644
--- a/healthd/healthd_mode_charger.cpp
+++ b/healthd/healthd_mode_charger.cpp
@@ -68,14 +68,13 @@
#define UNPLUGGED_SHUTDOWN_TIME (10 * MSEC_PER_SEC)
#define BATTERY_FULL_THRESH 95
-#define SCREEN_ON_BATTERY_THRESH 0
#define LAST_KMSG_PATH "/proc/last_kmsg"
#define LAST_KMSG_PSTORE_PATH "/sys/fs/pstore/console-ramoops"
#define LAST_KMSG_MAX_SZ (32 * 1024)
#define LOGE(x...) do { KLOG_ERROR("charger", x); } while (0)
-#define LOGI(x...) do { KLOG_INFO("charger", x); } while (0)
+#define LOGW(x...) do { KLOG_WARNING("charger", x); } while (0)
#define LOGV(x...) do { KLOG_DEBUG("charger", x); } while (0)
struct key_state {
@@ -109,7 +108,6 @@
struct charger {
bool have_battery_state;
bool charger_connected;
- int capacity;
int64_t next_screen_transition;
int64_t next_key_check;
int64_t next_pwr_check;
@@ -170,7 +168,8 @@
};
static struct charger charger_state;
-
+static struct healthd_config *healthd_config;
+static struct android::BatteryProperties *batt_prop;
static int char_width;
static int char_height;
static bool minui_inited;
@@ -198,15 +197,15 @@
unsigned sz = 0;
int len;
- LOGI("\n");
- LOGI("*************** LAST KMSG ***************\n");
- LOGI("\n");
+ LOGW("\n");
+ LOGW("*************** LAST KMSG ***************\n");
+ LOGW("\n");
buf = (char *)load_file(LAST_KMSG_PSTORE_PATH, &sz);
if (!buf || !sz) {
buf = (char *)load_file(LAST_KMSG_PATH, &sz);
if (!buf || !sz) {
- LOGI("last_kmsg not found. Cold reset?\n");
+ LOGW("last_kmsg not found. Cold reset?\n");
goto out;
}
}
@@ -225,7 +224,7 @@
yoink = ptr[cnt];
ptr[cnt] = '\0';
- klog_write(6, "<6>%s", ptr);
+ klog_write(6, "<4>%s", ptr);
ptr[cnt] = yoink;
len -= cnt;
@@ -235,14 +234,9 @@
free(buf);
out:
- LOGI("\n");
- LOGI("************* END LAST KMSG *************\n");
- LOGI("\n");
-}
-
-static int get_battery_capacity()
-{
- return charger_state.capacity;
+ LOGW("\n");
+ LOGW("************* END LAST KMSG *************\n");
+ LOGW("\n");
}
#ifdef CHARGER_ENABLE_SUSPEND
@@ -356,15 +350,16 @@
return;
if (!minui_inited) {
- int batt_cap = get_battery_capacity();
- if (batt_cap < SCREEN_ON_BATTERY_THRESH) {
- LOGV("[%" PRId64 "] level %d, leave screen off\n", now, batt_cap);
- batt_anim->run = false;
- charger->next_screen_transition = -1;
- if (charger->charger_connected)
- request_suspend(true);
- return;
+ if (healthd_config && healthd_config->screen_on) {
+ if (!healthd_config->screen_on(batt_prop)) {
+ LOGV("[%" PRId64 "] leave screen off\n", now);
+ batt_anim->run = false;
+ charger->next_screen_transition = -1;
+ if (charger->charger_connected)
+ request_suspend(true);
+ return;
+ }
}
gr_init();
@@ -391,16 +386,14 @@
/* animation starting, set up the animation */
if (batt_anim->cur_frame == 0) {
- int batt_cap;
LOGV("[%" PRId64 "] animation starting\n", now);
- batt_cap = get_battery_capacity();
- if (batt_cap >= 0 && batt_anim->num_frames != 0) {
+ if (batt_prop && batt_prop->batteryLevel >= 0 && batt_anim->num_frames != 0) {
int i;
/* find first frame given current capacity */
for (i = 1; i < batt_anim->num_frames; i++) {
- if (batt_cap < batt_anim->frames[i].min_capacity)
+ if (batt_prop->batteryLevel < batt_anim->frames[i].min_capacity)
break;
}
batt_anim->cur_frame = i - 1;
@@ -408,8 +401,8 @@
/* show the first frame for twice as long */
disp_time = batt_anim->frames[batt_anim->cur_frame].disp_time * 2;
}
-
- batt_anim->capacity = batt_cap;
+ if (batt_prop)
+ batt_anim->capacity = batt_prop->batteryLevel;
}
/* unblank the screen on first cycle */
@@ -524,10 +517,10 @@
all devices. Check the property and continue booting or reboot
accordingly. */
if (property_get_bool("ro.enable_boot_charger_mode", false)) {
- LOGI("[%" PRId64 "] booting from charger mode\n", now);
+ LOGW("[%" PRId64 "] booting from charger mode\n", now);
property_set("sys.boot_from_charger_mode", "1");
} else {
- LOGI("[%" PRId64 "] rebooting\n", now);
+ LOGW("[%" PRId64 "] rebooting\n", now);
android_reboot(ANDROID_RB_RESTART, 0, 0);
}
} else {
@@ -565,10 +558,10 @@
request_suspend(false);
if (charger->next_pwr_check == -1) {
charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME;
- LOGI("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n",
+ LOGW("[%" PRId64 "] device unplugged: shutting down in %" PRId64 " (@ %" PRId64 ")\n",
now, (int64_t)UNPLUGGED_SHUTDOWN_TIME, charger->next_pwr_check);
} else if (now >= charger->next_pwr_check) {
- LOGI("[%" PRId64 "] shutting down\n", now);
+ LOGW("[%" PRId64 "] shutting down\n", now);
android_reboot(ANDROID_RB_POWEROFF, 0, 0);
} else {
/* otherwise we already have a shutdown timer scheduled */
@@ -576,7 +569,7 @@
} else {
/* online supply present, reset shutdown timer if set */
if (charger->next_pwr_check != -1) {
- LOGI("[%" PRId64 "] device plugged in: shutdown cancelled\n", now);
+ LOGW("[%" PRId64 "] device plugged in: shutdown cancelled\n", now);
kick_animation(charger->batt_anim);
}
charger->next_pwr_check = -1;
@@ -605,7 +598,6 @@
charger->charger_connected =
props->chargerAcOnline || props->chargerUsbOnline ||
props->chargerWirelessOnline;
- charger->capacity = props->batteryLevel;
if (!charger->have_battery_state) {
charger->have_battery_state = true;
@@ -613,6 +605,7 @@
reset_animation(charger->batt_anim);
kick_animation(charger->batt_anim);
}
+ batt_prop = props;
}
int healthd_mode_charger_preparetowait(void)
@@ -663,7 +656,7 @@
ev_dispatch();
}
-void healthd_mode_charger_init(struct healthd_config* /*config*/)
+void healthd_mode_charger_init(struct healthd_config* config)
{
int ret;
struct charger *charger = &charger_state;
@@ -672,7 +665,7 @@
dump_last_kmsg();
- LOGI("--------------- STARTING CHARGER MODE ---------------\n");
+ LOGW("--------------- STARTING CHARGER MODE ---------------\n");
ret = ev_init(input_callback, charger);
if (!ret) {
@@ -711,4 +704,5 @@
charger->next_screen_transition = -1;
charger->next_key_check = -1;
charger->next_pwr_check = -1;
+ healthd_config = config;
}
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index 5efe2e1..101cacd 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -252,7 +252,6 @@
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/librank" },
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procrank" },
{ 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" },
- { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/tcpdump" },
{ 04770, AID_ROOT, AID_RADIO, 0, "system/bin/pppd-ril" },
/* the following files have enhanced capabilities and ARE included in user builds. */
diff --git a/include/system/audio.h b/include/system/audio.h
index 9a25cfb..181a171 100644
--- a/include/system/audio.h
+++ b/include/system/audio.h
@@ -57,10 +57,14 @@
* and must be routed to speaker
*/
AUDIO_STREAM_DTMF = 8,
- AUDIO_STREAM_TTS = 9,
-
- AUDIO_STREAM_CNT,
- AUDIO_STREAM_MAX = AUDIO_STREAM_CNT - 1,
+ AUDIO_STREAM_TTS = 9, /* Transmitted Through Speaker.
+ * Plays over speaker only, silent on other devices.
+ */
+ AUDIO_STREAM_ACCESSIBILITY = 10, /* For accessibility talk back prompts */
+ AUDIO_STREAM_REROUTING = 11, /* For dynamic policy output mixes */
+ AUDIO_STREAM_PATCH = 12, /* For internal audio flinger tracks. Fixed volume */
+ AUDIO_STREAM_PUBLIC_CNT = AUDIO_STREAM_TTS + 1,
+ AUDIO_STREAM_CNT = AUDIO_STREAM_PATCH + 1,
} audio_stream_type_t;
/* Do not change these values without updating their counterparts
@@ -96,6 +100,7 @@
AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12,
AUDIO_USAGE_ASSISTANCE_SONIFICATION = 13,
AUDIO_USAGE_GAME = 14,
+ AUDIO_USAGE_VIRTUAL_SOURCE = 15,
AUDIO_USAGE_CNT,
AUDIO_USAGE_MAX = AUDIO_USAGE_CNT - 1,
@@ -135,6 +140,7 @@
/* play the mix captured by this audio source. */
AUDIO_SOURCE_CNT,
AUDIO_SOURCE_MAX = AUDIO_SOURCE_CNT - 1,
+ AUDIO_SOURCE_FM_TUNER = 1998,
AUDIO_SOURCE_HOTWORD = 1999, /* A low-priority, preemptible audio source for
for background software hotword detection.
Same tuning as AUDIO_SOURCE_VOICE_RECOGNITION.
diff --git a/init/Android.mk b/init/Android.mk
index a3b01e1..ec2861b 100644
--- a/init/Android.mk
+++ b/init/Android.mk
@@ -75,6 +75,7 @@
include $(CLEAR_VARS)
LOCAL_MODULE := init_tests
LOCAL_SRC_FILES := \
+ init_parser_test.cpp \
util_test.cpp \
LOCAL_SHARED_LIBRARIES += \
diff --git a/init/builtins.cpp b/init/builtins.cpp
index b4204d8..86c9c2e 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -172,11 +172,16 @@
return 0;
}
-int do_exec(int nargs, char **args)
-{
- return -1;
+int do_exec(int nargs, char** args) {
+ service* svc = make_exec_oneshot_service(nargs, args);
+ if (svc == NULL) {
+ return -1;
+ }
+ service_start(svc, NULL);
+ return 0;
}
+// TODO: remove execonce when exec is available.
int do_execonce(int nargs, char **args)
{
pid_t child;
@@ -566,15 +571,6 @@
return 0;
}
-int do_setenforce(int nargs, char **args) {
- if (is_selinux_enabled() <= 0)
- return 0;
- if (security_setenforce(atoi(args[1])) < 0) {
- return -errno;
- }
- return 0;
-}
-
int do_setkey(int nargs, char **args)
{
struct kbentry kbe;
diff --git a/init/init.cpp b/init/init.cpp
index 41ceb0a..e090620 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -14,37 +14,37 @@
* limitations under the License.
*/
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <signal.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <ctype.h>
-#include <signal.h>
-#include <sys/wait.h>
#include <sys/mount.h>
-#include <sys/stat.h>
#include <sys/poll.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <mtd/mtd-user.h>
-#include <sys/types.h>
#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <sys/un.h>
+#include <sys/wait.h>
+#include <termios.h>
+#include <unistd.h>
+
+#include <mtd/mtd-user.h>
#include <selinux/selinux.h>
#include <selinux/label.h>
#include <selinux/android.h>
-#include <libgen.h>
-
-#include <cutils/list.h>
#include <cutils/android_reboot.h>
-#include <cutils/sockets.h>
-#include <cutils/iosched_policy.h>
#include <cutils/fs.h>
+#include <cutils/iosched_policy.h>
+#include <cutils/list.h>
+#include <cutils/sockets.h>
#include <private/android_filesystem_config.h>
-#include <termios.h>
#include "devices.h"
#include "init.h"
@@ -72,22 +72,35 @@
static struct action *cur_action = NULL;
static struct command *cur_command = NULL;
-void notify_service_state(const char *name, const char *state)
-{
- char pname[PROP_NAME_MAX];
- int len = strlen(name);
- if ((len + 10) > PROP_NAME_MAX)
- return;
- snprintf(pname, sizeof(pname), "init.svc.%s", name);
- property_set(pname, state);
-}
-
static int have_console;
static char console_name[PROP_VALUE_MAX] = "/dev/console";
static time_t process_needs_restart;
static const char *ENV[32];
+bool waiting_for_exec = false;
+
+void service::NotifyStateChange(const char* new_state) {
+ if (!properties_inited()) {
+ // If properties aren't available yet, we can't set them.
+ return;
+ }
+
+ if ((flags & SVC_EXEC) != 0) {
+ // 'exec' commands don't have properties tracking their state.
+ return;
+ }
+
+ char prop_name[PROP_NAME_MAX];
+ if (snprintf(prop_name, sizeof(prop_name), "init.svc.%s", name) >= PROP_NAME_MAX) {
+ // If the property name would be too long, we can't set it.
+ ERROR("Property name \"init.svc.%s\" too long; not setting to %s\n", name, new_state);
+ return;
+ }
+
+ property_set(prop_name, new_state);
+}
+
/* add_environment - add "key=value" to the current environment */
int add_environment(const char *key, const char *val)
{
@@ -160,35 +173,26 @@
void service_start(struct service *svc, const char *dynamic_args)
{
- struct stat s;
- pid_t pid;
- int needs_console;
- char *scon = NULL;
- int rc;
-
- /* starting a service removes it from the disabled or reset
- * state and immediately takes it out of the restarting
- * state if it was in there
- */
+ // Starting a service removes it from the disabled or reset state and
+ // immediately takes it out of the restarting state if it was in there.
svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
svc->time_started = 0;
- /* running processes require no additional work -- if
- * they're in the process of exiting, we've ensured
- * that they will immediately restart on exit, unless
- * they are ONESHOT
- */
+ // Running processes require no additional work --- if they're in the
+ // process of exiting, we've ensured that they will immediately restart
+ // on exit, unless they are ONESHOT.
if (svc->flags & SVC_RUNNING) {
return;
}
- needs_console = (svc->flags & SVC_CONSOLE) ? 1 : 0;
- if (needs_console && (!have_console)) {
+ bool needs_console = (svc->flags & SVC_CONSOLE);
+ if (needs_console && !have_console) {
ERROR("service '%s' requires console\n", svc->name);
svc->flags |= SVC_DISABLED;
return;
}
+ struct stat s;
if (stat(svc->args[0], &s) != 0) {
ERROR("cannot find '%s', disabling '%s'\n", svc->args[0], svc->name);
svc->flags |= SVC_DISABLED;
@@ -202,6 +206,7 @@
return;
}
+ char* scon = NULL;
if (is_selinux_enabled() > 0) {
if (svc->seclabel) {
scon = strdup(svc->seclabel);
@@ -213,7 +218,7 @@
char *mycon = NULL, *fcon = NULL;
INFO("computing context for service '%s'\n", svc->args[0]);
- rc = getcon(&mycon);
+ int rc = getcon(&mycon);
if (rc < 0) {
ERROR("could not get context while starting '%s'\n", svc->name);
return;
@@ -241,8 +246,7 @@
NOTICE("starting '%s'\n", svc->name);
- pid = fork();
-
+ pid_t pid = fork();
if (pid == 0) {
struct socketinfo *si;
struct svcenvinfo *ei;
@@ -298,7 +302,7 @@
setpgid(0, getpid());
- /* as requested, set our gid, supplemental gids, and uid */
+ // As requested, set our gid, supplemental gids, and uid.
if (svc->gid) {
if (setgid(svc->gid) != 0) {
ERROR("setgid failed: %s\n", strerror(errno));
@@ -361,8 +365,13 @@
svc->pid = pid;
svc->flags |= SVC_RUNNING;
- if (properties_inited())
- notify_service_state(svc->name, "running");
+ if ((svc->flags & SVC_EXEC) != 0) {
+ INFO("SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...\n",
+ svc->pid, svc->uid, svc->gid, svc->nr_supp_gids, svc->seclabel);
+ waiting_for_exec = true;
+ }
+
+ svc->NotifyStateChange("running");
}
/* The how field should be either SVC_DISABLED, SVC_RESET, or SVC_RESTART */
@@ -388,9 +397,9 @@
if (svc->pid) {
NOTICE("service '%s' is being killed\n", svc->name);
kill(-svc->pid, SIGKILL);
- notify_service_state(svc->name, "stopping");
+ svc->NotifyStateChange("stopping");
} else {
- notify_service_state(svc->name, "stopped");
+ svc->NotifyStateChange("stopped");
}
}
@@ -969,28 +978,18 @@
security_setenforce(is_enforcing);
}
-int main(int argc, char **argv)
-{
- size_t fd_count = 0;
- struct pollfd ufds[4];
- int property_set_fd_init = 0;
- int signal_fd_init = 0;
- int keychord_fd_init = 0;
- bool is_charger = false;
-
+int main(int argc, char** argv) {
if (!strcmp(basename(argv[0]), "ueventd"))
return ueventd_main(argc, argv);
if (!strcmp(basename(argv[0]), "watchdogd"))
return watchdogd_main(argc, argv);
- /* clear the umask */
+ // Clear the umask.
umask(0);
- /* Get the basic filesystem setup we need put
- * together in the initramdisk on / and then we'll
- * let the rc file figure out the rest.
- */
+ // Get the basic filesystem setup we need put together in the initramdisk
+ // on / and then we'll let the rc file figure out the rest.
mkdir("/dev", 0755);
mkdir("/proc", 0755);
mkdir("/sys", 0755);
@@ -1002,15 +1001,13 @@
mount("proc", "/proc", "proc", 0, NULL);
mount("sysfs", "/sys", "sysfs", 0, NULL);
- /* indicate that booting is in progress to background fw loaders, etc */
+ // Indicate that booting is in progress to background fw loaders, etc.
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
- /* We must have some place other than / to create the
- * device nodes for kmsg and null, otherwise we won't
- * be able to remount / read-only later on.
- * Now that tmpfs is mounted on /dev, we can actually
- * talk to the outside world.
- */
+ // We must have some place other than / to create the device nodes for
+ // kmsg and null, otherwise we won't be able to remount / read-only
+ // later on. Now that tmpfs is mounted on /dev, we can actually talk
+ // to the outside world.
open_devnull_stdio();
klog_init();
property_init();
@@ -1019,25 +1016,22 @@
process_kernel_cmdline();
- union selinux_callback cb;
+ selinux_callback cb;
cb.func_log = log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
-
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
selinux_initialize();
- /* These directories were necessarily created before initial policy load
- * and therefore need their security context restored to the proper value.
- * This must happen before /dev is populated by ueventd.
- */
+
+ // These directories were necessarily created before initial policy load
+ // and therefore need their security context restored to the proper value.
+ // This must happen before /dev is populated by ueventd.
restorecon("/dev");
restorecon("/dev/socket");
restorecon("/dev/__properties__");
restorecon_recursive("/sys");
- is_charger = !strcmp(bootmode, "charger");
-
INFO("property init\n");
property_load_boot_defaults();
@@ -1050,50 +1044,58 @@
queue_builtin_action(keychord_init_action, "keychord_init");
queue_builtin_action(console_init_action, "console_init");
- /* execute all the boot actions to get us started */
+ // Execute all the boot actions to get us started.
action_for_each_trigger("init", action_add_queue_tail);
- /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
- * wasn't ready immediately after wait_for_coldboot_done
- */
+ // Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random
+ // wasn't ready immediately after wait_for_coldboot_done
queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");
queue_builtin_action(property_service_init_action, "property_service_init");
queue_builtin_action(signal_init_action, "signal_init");
- /* Don't mount filesystems or start core system services if in charger mode. */
- if (is_charger) {
+ // Don't mount filesystems or start core system services in charger mode.
+ if (strcmp(bootmode, "charger") == 0) {
action_for_each_trigger("charger", action_add_queue_tail);
} else {
action_for_each_trigger("late-init", action_add_queue_tail);
}
- /* run all property triggers based on current state of the properties */
+ // Run all property triggers based on current state of the properties.
queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");
+ // TODO: why do we only initialize ufds after execute_one_command and restart_processes?
+ size_t fd_count = 0;
+ struct pollfd ufds[3];
+ bool property_set_fd_init = false;
+ bool signal_fd_init = false;
+ bool keychord_fd_init = false;
+
for (;;) {
- execute_one_command();
- restart_processes();
+ if (!waiting_for_exec) {
+ execute_one_command();
+ restart_processes();
+ }
if (!property_set_fd_init && get_property_set_fd() > 0) {
ufds[fd_count].fd = get_property_set_fd();
ufds[fd_count].events = POLLIN;
ufds[fd_count].revents = 0;
fd_count++;
- property_set_fd_init = 1;
+ property_set_fd_init = true;
}
if (!signal_fd_init && get_signal_fd() > 0) {
ufds[fd_count].fd = get_signal_fd();
ufds[fd_count].events = POLLIN;
ufds[fd_count].revents = 0;
fd_count++;
- signal_fd_init = 1;
+ signal_fd_init = true;
}
if (!keychord_fd_init && get_keychord_fd() > 0) {
ufds[fd_count].fd = get_keychord_fd();
ufds[fd_count].events = POLLIN;
ufds[fd_count].revents = 0;
fd_count++;
- keychord_fd_init = 1;
+ keychord_fd_init = true;
}
int timeout = -1;
diff --git a/init/init.h b/init/init.h
index eedec27..a104af6 100644
--- a/init/init.h
+++ b/init/init.h
@@ -17,13 +17,11 @@
#ifndef _INIT_INIT_H
#define _INIT_INIT_H
+#include <sys/types.h>
+
#include <cutils/list.h>
#include <cutils/iosched_policy.h>
-#include <sys/stat.h>
-
-void handle_control_message(const char *msg, const char *arg);
-
struct command
{
/* list of commands in an action */
@@ -59,8 +57,6 @@
struct command *current;
};
-void build_triggers_string(char *name_str, int length, struct action *cur_action);
-
struct socketinfo {
struct socketinfo *next;
const char *name;
@@ -77,27 +73,29 @@
const char *value;
};
-#define SVC_DISABLED 0x01 /* do not autostart with class */
-#define SVC_ONESHOT 0x02 /* do not restart on exit */
-#define SVC_RUNNING 0x04 /* currently active */
-#define SVC_RESTARTING 0x08 /* waiting to restart */
-#define SVC_CONSOLE 0x10 /* requires console */
-#define SVC_CRITICAL 0x20 /* will reboot into recovery if keeps crashing */
-#define SVC_RESET 0x40 /* Use when stopping a process, but not disabling
- so it can be restarted with its class */
-#define SVC_RC_DISABLED 0x80 /* Remember if the disabled flag was set in the rc script */
-#define SVC_RESTART 0x100 /* Use to safely restart (stop, wait, start) a service */
-#define SVC_DISABLED_START 0x200 /* a start was requested but it was disabled at the time */
+#define SVC_DISABLED 0x001 // do not autostart with class
+#define SVC_ONESHOT 0x002 // do not restart on exit
+#define SVC_RUNNING 0x004 // currently active
+#define SVC_RESTARTING 0x008 // waiting to restart
+#define SVC_CONSOLE 0x010 // requires console
+#define SVC_CRITICAL 0x020 // will reboot into recovery if keeps crashing
+#define SVC_RESET 0x040 // Use when stopping a process, but not disabling so it can be restarted with its class.
+#define SVC_RC_DISABLED 0x080 // Remember if the disabled flag was set in the rc script.
+#define SVC_RESTART 0x100 // Use to safely restart (stop, wait, start) a service.
+#define SVC_DISABLED_START 0x200 // A start was requested but it was disabled at the time.
+#define SVC_EXEC 0x400 // This synthetic service corresponds to an 'exec'.
#define NR_SVC_SUPP_GIDS 12 /* twelve supplementary groups */
#define COMMAND_RETRY_TIMEOUT 5
struct service {
+ void NotifyStateChange(const char* new_state);
+
/* list of all services */
struct listnode slist;
- const char *name;
+ char *name;
const char *classname;
unsigned flags;
@@ -105,19 +103,19 @@
time_t time_started; /* time of last start */
time_t time_crashed; /* first crash within inspection window */
int nr_crashed; /* number of times crashed within window */
-
+
uid_t uid;
gid_t gid;
gid_t supp_gids[NR_SVC_SUPP_GIDS];
size_t nr_supp_gids;
- char *seclabel;
+ const char* seclabel;
struct socketinfo *sockets;
struct svcenvinfo *envvars;
struct action onrestart; /* Actions to execute on restart. */
-
+
/* keycodes for triggering this service via /dev/keychord */
int *keycodes;
int nkeycodes;
@@ -131,7 +129,13 @@
char *args[1];
}; /* ^-------'args' MUST be at the end of this struct! */
-void notify_service_state(const char *name, const char *state);
+extern bool waiting_for_exec;
+extern struct selabel_handle *sehandle;
+extern struct selabel_handle *sehandle_prop;
+
+void build_triggers_string(char *name_str, int length, struct action *cur_action);
+
+void handle_control_message(const char *msg, const char *arg);
struct service *service_find_by_name(const char *name);
struct service *service_find_by_pid(pid_t pid);
@@ -147,9 +151,8 @@
void service_start(struct service *svc, const char *dynamic_args);
void property_changed(const char *name, const char *value);
-extern struct selabel_handle *sehandle;
-extern struct selabel_handle *sehandle_prop;
-extern int selinux_reload_policy(void);
+int selinux_reload_policy(void);
+
void zap_stdio(void);
#endif /* _INIT_INIT_H */
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 3932357..5cd46fa 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -185,7 +186,6 @@
if (!strcmp(s, "eclabel")) return K_seclabel;
if (!strcmp(s, "ervice")) return K_service;
if (!strcmp(s, "etcon")) return K_setcon;
- if (!strcmp(s, "etenforce")) return K_setenforce;
if (!strcmp(s, "etenv")) return K_setenv;
if (!strcmp(s, "etkey")) return K_setkey;
if (!strcmp(s, "etprop")) return K_setprop;
@@ -440,7 +440,7 @@
}
int init_parse_config_file(const char* path) {
- INFO("Parsing %s...", path);
+ INFO("Parsing %s...\n", path);
std::string data;
if (!read_file(path, &data)) {
return -1;
@@ -663,6 +663,65 @@
return list_empty(&action_queue);
}
+service* make_exec_oneshot_service(int nargs, char** args) {
+ // Parse the arguments: exec [SECLABEL [UID [GID]*] --] COMMAND ARGS...
+ int command_arg = 1;
+ for (int i = 1; i < nargs; ++i) {
+ if (strcmp(args[i], "--") == 0) {
+ command_arg = i + 1;
+ break;
+ }
+ }
+ if (command_arg > 4 + NR_SVC_SUPP_GIDS) {
+ ERROR("exec called with too many supplementary group ids\n");
+ return NULL;
+ }
+
+ int argc = nargs - command_arg;
+ char** argv = (args + command_arg);
+ if (argc < 1) {
+ ERROR("exec called without command\n");
+ return NULL;
+ }
+
+ service* svc = (service*) calloc(1, sizeof(*svc) + sizeof(char*) * argc);
+ if (svc == NULL) {
+ ERROR("Couldn't allocate service for exec of '%s': %s", argv[0], strerror(errno));
+ return NULL;
+ }
+
+ if (command_arg > 2) {
+ svc->seclabel = args[1];
+ }
+ if (command_arg > 3) {
+ svc->uid = decode_uid(args[2]);
+ }
+ if (command_arg > 4) {
+ svc->gid = decode_uid(args[3]);
+ svc->nr_supp_gids = command_arg - 1 /* -- */ - 4 /* exec SECLABEL UID GID */;
+ for (size_t i = 0; i < svc->nr_supp_gids; ++i) {
+ svc->supp_gids[i] = decode_uid(args[4 + i]);
+ }
+ }
+
+ static int exec_count; // Every service needs a unique name.
+ char* name = NULL;
+ asprintf(&name, "exec %d (%s)", exec_count++, argv[0]);
+ if (name == NULL) {
+ ERROR("Couldn't allocate name for exec service '%s'\n", argv[0]);
+ free(svc);
+ return NULL;
+ }
+ svc->name = name;
+ svc->classname = "default";
+ svc->flags = SVC_EXEC | SVC_ONESHOT;
+ svc->nargs = argc;
+ memcpy(svc->args, argv, sizeof(char*) * svc->nargs);
+ svc->args[argc] = NULL;
+ list_add_tail(&service_list, &svc->slist);
+ return svc;
+}
+
static void *parse_service(struct parse_state *state, int nargs, char **args)
{
if (nargs < 3) {
@@ -686,7 +745,7 @@
parse_error(state, "out of memory\n");
return 0;
}
- svc->name = args[1];
+ svc->name = strdup(args[1]);
svc->classname = "default";
memcpy(svc->args, args + 2, sizeof(char*) * nargs);
trigger* cur_trigger = (trigger*) calloc(1, sizeof(*cur_trigger));
diff --git a/init/init_parser.h b/init/init_parser.h
index 0047da7..6348607 100644
--- a/init/init_parser.h
+++ b/init/init_parser.h
@@ -20,6 +20,7 @@
#define INIT_PARSER_MAXARGS 64
struct action;
+struct service;
struct action *action_remove_queue_head(void);
void action_add_queue_tail(struct action *act);
@@ -33,4 +34,6 @@
int init_parse_config_file(const char *fn);
int expand_props(char *dst, const char *src, int len);
+service* make_exec_oneshot_service(int argc, char** argv);
+
#endif
diff --git a/init/init_parser_test.cpp b/init/init_parser_test.cpp
new file mode 100644
index 0000000..170a73a
--- /dev/null
+++ b/init/init_parser_test.cpp
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2015 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 "init_parser.h"
+
+#include "init.h"
+#include "util.h"
+
+#include <errno.h>
+#include <gtest/gtest.h>
+
+TEST(init_parser, make_exec_oneshot_service_invalid_syntax) {
+ char* argv[10];
+ memset(argv, 0, sizeof(argv));
+
+ // Nothing.
+ ASSERT_EQ(nullptr, make_exec_oneshot_service(0, argv));
+
+ // No arguments to 'exec'.
+ argv[0] = const_cast<char*>("exec");
+ ASSERT_EQ(nullptr, make_exec_oneshot_service(1, argv));
+
+ // No command in "exec --".
+ argv[1] = const_cast<char*>("--");
+ ASSERT_EQ(nullptr, make_exec_oneshot_service(2, argv));
+}
+
+TEST(init_parser, make_exec_oneshot_service_too_many_supplementary_gids) {
+ int argc = 0;
+ char* argv[4 + NR_SVC_SUPP_GIDS + 3];
+ argv[argc++] = const_cast<char*>("exec");
+ argv[argc++] = const_cast<char*>("seclabel");
+ argv[argc++] = const_cast<char*>("root"); // uid.
+ argv[argc++] = const_cast<char*>("root"); // gid.
+ for (int i = 0; i < NR_SVC_SUPP_GIDS; ++i) {
+ argv[argc++] = const_cast<char*>("root"); // Supplementary gid.
+ }
+ argv[argc++] = const_cast<char*>("--");
+ argv[argc++] = const_cast<char*>("/system/bin/id");
+ argv[argc] = nullptr;
+ ASSERT_EQ(nullptr, make_exec_oneshot_service(argc, argv));
+}
+
+static void Test_make_exec_oneshot_service(bool dash_dash, bool seclabel, bool uid, bool gid, bool supplementary_gids) {
+ int argc = 0;
+ char* argv[10];
+ argv[argc++] = const_cast<char*>("exec");
+ if (seclabel) {
+ argv[argc++] = const_cast<char*>("u:r:su:s0"); // seclabel
+ if (uid) {
+ argv[argc++] = const_cast<char*>("log"); // uid
+ if (gid) {
+ argv[argc++] = const_cast<char*>("shell"); // gid
+ if (supplementary_gids) {
+ argv[argc++] = const_cast<char*>("system"); // supplementary gid 0
+ argv[argc++] = const_cast<char*>("adb"); // supplementary gid 1
+ }
+ }
+ }
+ }
+ if (dash_dash) {
+ argv[argc++] = const_cast<char*>("--");
+ }
+ argv[argc++] = const_cast<char*>("/system/bin/toybox");
+ argv[argc++] = const_cast<char*>("id");
+ argv[argc] = nullptr;
+ service* svc = make_exec_oneshot_service(argc, argv);
+ ASSERT_NE(nullptr, svc);
+
+ if (seclabel) {
+ ASSERT_STREQ("u:r:su:s0", svc->seclabel);
+ } else {
+ ASSERT_EQ(nullptr, svc->seclabel);
+ }
+ if (uid) {
+ ASSERT_EQ(decode_uid("log"), svc->uid);
+ } else {
+ ASSERT_EQ(0U, svc->uid);
+ }
+ if (gid) {
+ ASSERT_EQ(decode_uid("shell"), svc->gid);
+ } else {
+ ASSERT_EQ(0U, svc->gid);
+ }
+ if (supplementary_gids) {
+ ASSERT_EQ(2U, svc->nr_supp_gids);
+ ASSERT_EQ(decode_uid("system"), svc->supp_gids[0]);
+ ASSERT_EQ(decode_uid("adb"), svc->supp_gids[1]);
+ } else {
+ ASSERT_EQ(0U, svc->nr_supp_gids);
+ }
+
+ ASSERT_EQ(2, svc->nargs);
+ ASSERT_EQ("/system/bin/toybox", svc->args[0]);
+ ASSERT_EQ("id", svc->args[1]);
+ ASSERT_EQ(nullptr, svc->args[2]);
+}
+
+TEST(init_parser, make_exec_oneshot_service_with_everything) {
+ Test_make_exec_oneshot_service(true, true, true, true, true);
+}
+
+TEST(init_parser, make_exec_oneshot_service_with_seclabel_uid_gid) {
+ Test_make_exec_oneshot_service(true, true, true, true, false);
+}
+
+TEST(init_parser, make_exec_oneshot_service_with_seclabel_uid) {
+ Test_make_exec_oneshot_service(true, true, true, false, false);
+}
+
+TEST(init_parser, make_exec_oneshot_service_with_seclabel) {
+ Test_make_exec_oneshot_service(true, true, false, false, false);
+}
+
+TEST(init_parser, make_exec_oneshot_service_with_just_command) {
+ Test_make_exec_oneshot_service(true, false, false, false, false);
+}
+
+TEST(init_parser, make_exec_oneshot_service_with_just_command_no_dash) {
+ Test_make_exec_oneshot_service(false, false, false, false, false);
+}
diff --git a/init/keywords.h b/init/keywords.h
index 60931f1..b203d2d 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -23,7 +23,6 @@
int do_rm(int nargs, char **args);
int do_rmdir(int nargs, char **args);
int do_setcon(int nargs, char **args);
-int do_setenforce(int nargs, char **args);
int do_setkey(int nargs, char **args);
int do_setprop(int nargs, char **args);
int do_setrlimit(int nargs, char **args);
@@ -84,7 +83,6 @@
KEYWORD(seclabel, OPTION, 0, 0)
KEYWORD(service, SECTION, 0, 0)
KEYWORD(setcon, COMMAND, 1, do_setcon)
- KEYWORD(setenforce, COMMAND, 1, do_setenforce)
KEYWORD(setenv, OPTION, 2, 0)
KEYWORD(setkey, COMMAND, 0, do_setkey)
KEYWORD(setprop, COMMAND, 2, do_setprop)
diff --git a/init/readme.txt b/init/readme.txt
index 9c24220..3af7924 100644
--- a/init/readme.txt
+++ b/init/readme.txt
@@ -70,11 +70,11 @@
setenv <name> <value>
Set the environment variable <name> to <value> in the launched process.
-socket <name> <type> <perm> [ <user> [ <group> [ <context> ] ] ]
+socket <name> <type> <perm> [ <user> [ <group> [ <seclabel> ] ] ]
Create a unix domain socket named /dev/socket/<name> and pass
its fd to the launched process. <type> must be "dgram", "stream" or "seqpacket".
User and group default to 0.
- Context is the SELinux security context for the socket.
+ 'seclabel' is the SELinux security context for the socket.
It defaults to the service security context, as specified by seclabel or
computed based on the service executable file security context.
@@ -91,8 +91,8 @@
supplemental groups of the process (via setgroups()).
Currently defaults to root. (??? probably should default to nobody)
-seclabel <securitycontext>
- Change to securitycontext before exec'ing this service.
+seclabel <seclabel>
+ Change to 'seclabel' before exec'ing this service.
Primarily for use by services run from the rootfs, e.g. ueventd, adbd.
Services on the system partition can instead use policy-defined transitions
based on their file security context.
@@ -137,14 +137,17 @@
Commands
--------
-exec <path> [ <argument> ]*
- This command is not implemented.
+exec [ <seclabel> [ <user> [ <group> ]* ] ] -- <command> [ <argument> ]*
+ Fork and execute command with the given arguments. The command starts
+ after "--" so that an optional security context, user, and supplementary
+ groups can be provided. No other commands will be run until this one
+ finishes.
execonce <path> [ <argument> ]*
Fork and execute a program (<path>). This will block until
the program completes execution. This command can be run at most
once during init's lifetime. Subsequent invocations are ignored.
- It is best to avoid exec as unlike the builtin commands, it runs
+ It is best to avoid execonce as unlike the builtin commands, it runs
the risk of getting init "stuck".
export <name> <value>
@@ -220,15 +223,11 @@
Recursively restore the directory tree named by <path> to the
security contexts specified in the file_contexts configuration.
-setcon <securitycontext>
+setcon <seclabel>
Set the current process security context to the specified string.
This is typically only used from early-init to set the init context
before any other process is started.
-setenforce 0|1
- Set the SELinux system-wide enforcing status.
- 0 is permissive (i.e. log but do not deny), 1 is enforcing.
-
setkey
TBD
@@ -275,7 +274,7 @@
Init updates some system properties to provide some insight into
what it's doing:
-init.action
+init.action
Equal to the name of the action currently being executed or "" if none
init.command
diff --git a/init/signal_handler.cpp b/init/signal_handler.cpp
index c0898fb..c428b96 100644
--- a/init/signal_handler.cpp
+++ b/init/signal_handler.cpp
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#include <stdio.h>
#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
@@ -27,34 +27,28 @@
#include <cutils/list.h>
#include "init.h"
-#include "util.h"
#include "log.h"
+#include "util.h"
static int signal_fd = -1;
static int signal_recv_fd = -1;
-static void sigchld_handler(int s)
-{
+static void sigchld_handler(int s) {
write(signal_fd, &s, 1);
}
#define CRITICAL_CRASH_THRESHOLD 4 /* if we crash >4 times ... */
-#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery*/
+#define CRITICAL_CRASH_WINDOW (4*60) /* ... in 4 minutes, goto recovery */
-static int wait_for_one_process(int block)
-{
+static int wait_for_one_process() {
int status;
- struct service *svc;
- struct socketinfo *si;
- time_t now;
- struct listnode *node;
- struct command *cmd;
-
- pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, block ? 0 : WNOHANG));
- if (pid <= 0) return -1;
+ pid_t pid = TEMP_FAILURE_RETRY(waitpid(-1, &status, WNOHANG));
+ if (pid <= 0) {
+ return -1;
+ }
INFO("waitpid returned pid %d, status = %08x\n", pid, status);
- svc = service_find_by_pid(pid);
+ service* svc = service_find_by_pid(pid);
if (!svc) {
if (WIFEXITED(status)) {
ERROR("untracked pid %d exited with status %d\n", pid, WEXITSTATUS(status));
@@ -68,36 +62,47 @@
return 0;
}
+ // TODO: all the code from here down should be a member function on service.
+
NOTICE("process '%s', pid %d exited\n", svc->name, pid);
if (!(svc->flags & SVC_ONESHOT) || (svc->flags & SVC_RESTART)) {
- kill(-pid, SIGKILL);
NOTICE("process '%s' killing any children in process group\n", svc->name);
+ kill(-pid, SIGKILL);
}
- /* remove any sockets we may have created */
- for (si = svc->sockets; si; si = si->next) {
+ // Remove any sockets we may have created.
+ for (socketinfo* si = svc->sockets; si; si = si->next) {
char tmp[128];
snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s", si->name);
unlink(tmp);
}
+ if (svc->flags & SVC_EXEC) {
+ INFO("SVC_EXEC pid %d finished...\n", svc->pid);
+ waiting_for_exec = false;
+ list_remove(&svc->slist);
+ free(svc->name);
+ free(svc);
+ return 0;
+ }
+
svc->pid = 0;
svc->flags &= (~SVC_RUNNING);
- /* oneshot processes go into the disabled state on exit,
- * except when manually restarted. */
+ // Oneshot processes go into the disabled state on exit,
+ // except when manually restarted.
if ((svc->flags & SVC_ONESHOT) && !(svc->flags & SVC_RESTART)) {
svc->flags |= SVC_DISABLED;
}
- /* disabled and reset processes do not get restarted automatically */
- if (svc->flags & (SVC_DISABLED | SVC_RESET) ) {
- notify_service_state(svc->name, "stopped");
+ // Disabled and reset processes do not get restarted automatically.
+ if (svc->flags & (SVC_DISABLED | SVC_RESET)) {
+ svc->NotifyStateChange("stopped");
return 0;
}
- now = gettime();
+ time_t now = gettime();
if ((svc->flags & SVC_CRITICAL) && !(svc->flags & SVC_RESTART)) {
if (svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {
if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {
@@ -116,36 +121,33 @@
svc->flags &= (~SVC_RESTART);
svc->flags |= SVC_RESTARTING;
- /* Execute all onrestart commands for this service. */
+ // Execute all onrestart commands for this service.
+ struct listnode* node;
list_for_each(node, &svc->onrestart.commands) {
- cmd = node_to_item(node, struct command, clist);
+ command* cmd = node_to_item(node, struct command, clist);
cmd->func(cmd->nargs, cmd->args);
}
- notify_service_state(svc->name, "restarting");
+ svc->NotifyStateChange("restarting");
return 0;
}
-void handle_signal(void)
-{
+void handle_signal() {
+ // We got a SIGCHLD - reap and restart as needed.
char tmp[32];
-
- /* we got a SIGCHLD - reap and restart as needed */
read(signal_recv_fd, tmp, sizeof(tmp));
- while (!wait_for_one_process(0))
- ;
+ while (!wait_for_one_process()) {
+ }
}
-void signal_init(void)
-{
- int s[2];
-
+void signal_init() {
struct sigaction act;
memset(&act, 0, sizeof(act));
act.sa_handler = sigchld_handler;
act.sa_flags = SA_NOCLDSTOP;
sigaction(SIGCHLD, &act, 0);
- /* create a signalling mechanism for the sigchld handler */
+ // Create a signalling mechanism for the sigchld handler.
+ int s[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0, s) == 0) {
signal_fd = s[0];
signal_recv_fd = s[1];
@@ -154,7 +156,6 @@
handle_signal();
}
-int get_signal_fd()
-{
+int get_signal_fd() {
return signal_recv_fd;
}
diff --git a/init/util_test.cpp b/init/util_test.cpp
index e9a1581..5b3ab50 100644
--- a/init/util_test.cpp
+++ b/init/util_test.cpp
@@ -35,3 +35,9 @@
s[5] = 0;
EXPECT_STREQ("Linux", s.c_str());
}
+
+TEST(util, decode_uid) {
+ EXPECT_EQ(0U, decode_uid("root"));
+ EXPECT_EQ(-1U, decode_uid("toot"));
+ EXPECT_EQ(123U, decode_uid("123"));
+}
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.c
index 4089968..9a4a5bb 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.c
@@ -30,9 +30,11 @@
native_handle_t* h = malloc(
sizeof(native_handle_t) + sizeof(int)*(numFds+numInts));
- h->version = sizeof(native_handle_t);
- h->numFds = numFds;
- h->numInts = numInts;
+ if (h) {
+ h->version = sizeof(native_handle_t);
+ h->numFds = numFds;
+ h->numInts = numInts;
+ }
return h;
}
diff --git a/libcutils/sched_policy.c b/libcutils/sched_policy.c
index 2a9d96b..dfc8777 100644
--- a/libcutils/sched_policy.c
+++ b/libcutils/sched_policy.c
@@ -45,8 +45,6 @@
#define POLICY_DEBUG 0
-#define CAN_SET_SP_SYSTEM 0 // non-zero means to implement set_sched_policy(tid, SP_SYSTEM)
-
// This prctl is only available in Android kernels.
#define PR_SET_TIMERSLACK_PID 41
@@ -60,9 +58,6 @@
// File descriptors open to /dev/cpuctl/../tasks, setup by initialize, or -1 on error.
static int bg_cgroup_fd = -1;
static int fg_cgroup_fd = -1;
-#if CAN_SET_SP_SYSTEM
-static int system_cgroup_fd = -1;
-#endif
/* Add tid to the scheduling group defined by the policy */
static int add_tid_to_cgroup(int tid, SchedPolicy policy)
@@ -78,11 +73,6 @@
case SP_AUDIO_SYS:
fd = fg_cgroup_fd;
break;
-#if CAN_SET_SP_SYSTEM
- case SP_SYSTEM:
- fd = system_cgroup_fd;
- break;
-#endif
default:
fd = -1;
break;
@@ -123,21 +113,13 @@
if (!access("/dev/cpuctl/tasks", F_OK)) {
__sys_supports_schedgroups = 1;
-#if CAN_SET_SP_SYSTEM
filename = "/dev/cpuctl/tasks";
- system_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);
- if (system_cgroup_fd < 0) {
- SLOGV("open of %s failed: %s\n", filename, strerror(errno));
- }
-#endif
-
- filename = "/dev/cpuctl/apps/tasks";
fg_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);
if (fg_cgroup_fd < 0) {
SLOGE("open of %s failed: %s\n", filename, strerror(errno));
}
- filename = "/dev/cpuctl/apps/bg_non_interactive/tasks";
+ filename = "/dev/cpuctl/bg_non_interactive/tasks";
bg_cgroup_fd = open(filename, O_WRONLY | O_CLOEXEC);
if (bg_cgroup_fd < 0) {
SLOGE("open of %s failed: %s\n", filename, strerror(errno));
@@ -231,11 +213,9 @@
if (getSchedulerGroup(tid, grpBuf, sizeof(grpBuf)) < 0)
return -1;
if (grpBuf[0] == '\0') {
- *policy = SP_SYSTEM;
- } else if (!strcmp(grpBuf, "apps/bg_non_interactive")) {
- *policy = SP_BACKGROUND;
- } else if (!strcmp(grpBuf, "apps")) {
*policy = SP_FOREGROUND;
+ } else if (!strcmp(grpBuf, "bg_non_interactive")) {
+ *policy = SP_BACKGROUND;
} else {
errno = ERANGE;
return -1;
diff --git a/liblog/Android.mk b/liblog/Android.mk
index 4e6424a..d7766f5 100644
--- a/liblog/Android.mk
+++ b/liblog/Android.mk
@@ -83,6 +83,10 @@
LOCAL_MODULE := liblog
LOCAL_WHOLE_STATIC_LIBRARIES := liblog
LOCAL_CFLAGS := -Werror $(liblog_cflags)
+
+# TODO: This is to work around b/19059885. Remove after root cause is fixed
+LOCAL_LDFLAGS_arm := -Wl,--hash-style=both
+
include $(BUILD_SHARED_LIBRARY)
include $(call first-makefiles-under,$(LOCAL_PATH))
diff --git a/libnativebridge/tests/CompleteFlow_test.cpp b/libnativebridge/tests/CompleteFlow_test.cpp
index cf06d2c..b033792 100644
--- a/libnativebridge/tests/CompleteFlow_test.cpp
+++ b/libnativebridge/tests/CompleteFlow_test.cpp
@@ -36,6 +36,7 @@
// Unload
UnloadNativeBridge();
+
ASSERT_FALSE(NativeBridgeAvailable());
ASSERT_FALSE(NativeBridgeError());
diff --git a/logd/Android.mk b/logd/Android.mk
index 188511f..127a66b 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -26,7 +26,16 @@
libcutils \
libutils
-LOCAL_CFLAGS := -Werror $(shell sed -n 's/^\([0-9]*\)[ \t]*auditd[ \t].*/-DAUDITD_LOG_TAG=\1/p' $(LOCAL_PATH)/event.logtags)
+# This is what we want to do:
+# event_logtags = $(shell \
+# sed -n \
+# "s/^\([0-9]*\)[ \t]*$1[ \t].*/-D`echo $1 | tr a-z A-Z`_LOG_TAG=\1/p" \
+# $(LOCAL_PATH)/$2/event.logtags)
+# event_flag := $(call event_logtags,auditd)
+# so make sure we do not regret hard-coding it as follows:
+event_flag := -DAUDITD_LOG_TAG=1003
+
+LOCAL_CFLAGS := -Werror $(event_flag)
include $(BUILD_EXECUTABLE)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 2a599ac..e3b5db9 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -118,25 +118,18 @@
mount cgroup none /dev/cpuctl cpu
chown system system /dev/cpuctl
chown system system /dev/cpuctl/tasks
- chmod 0660 /dev/cpuctl/tasks
+ chmod 0666 /dev/cpuctl/tasks
write /dev/cpuctl/cpu.shares 1024
- write /dev/cpuctl/cpu.rt_runtime_us 950000
+ write /dev/cpuctl/cpu.rt_runtime_us 800000
write /dev/cpuctl/cpu.rt_period_us 1000000
- mkdir /dev/cpuctl/apps
- chown system system /dev/cpuctl/apps/tasks
- chmod 0666 /dev/cpuctl/apps/tasks
- write /dev/cpuctl/apps/cpu.shares 1024
- write /dev/cpuctl/apps/cpu.rt_runtime_us 800000
- write /dev/cpuctl/apps/cpu.rt_period_us 1000000
-
- mkdir /dev/cpuctl/apps/bg_non_interactive
- chown system system /dev/cpuctl/apps/bg_non_interactive/tasks
- chmod 0666 /dev/cpuctl/apps/bg_non_interactive/tasks
+ mkdir /dev/cpuctl/bg_non_interactive
+ chown system system /dev/cpuctl/bg_non_interactive/tasks
+ chmod 0666 /dev/cpuctl/bg_non_interactive/tasks
# 5.0 %
- write /dev/cpuctl/apps/bg_non_interactive/cpu.shares 52
- write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_runtime_us 700000
- write /dev/cpuctl/apps/bg_non_interactive/cpu.rt_period_us 1000000
+ write /dev/cpuctl/bg_non_interactive/cpu.shares 52
+ write /dev/cpuctl/bg_non_interactive/cpu.rt_runtime_us 700000
+ write /dev/cpuctl/bg_non_interactive/cpu.rt_period_us 1000000
# qtaguid will limit access to specific data based on group memberships.
# net_bw_acct grants impersonation of socket owners.
@@ -572,7 +565,7 @@
# encryption) or trigger_restart_min_framework (other encryption)
# One shot invocation to encrypt unencrypted volumes
-service encrypt /system/bin/vdc --wait cryptfs maybeenabledefaultcrypto
+service encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default
disabled
oneshot
# vold will set vold.decrypt to trigger_restart_framework (default
diff --git a/rootdir/ueventd.rc b/rootdir/ueventd.rc
index 43d7bc9..9cf9ed9 100644
--- a/rootdir/ueventd.rc
+++ b/rootdir/ueventd.rc
@@ -89,6 +89,7 @@
/dev/ppp 0660 radio vpn
# sysfs properties
+/sys/devices/platform/trusty.* trusty_version 0440 root log
/sys/devices/virtual/input/input* enable 0660 root input
/sys/devices/virtual/input/input* poll_delay 0660 root input
/sys/devices/virtual/usb_composite/* enable 0664 root system
diff --git a/toolbox/Android.mk b/toolbox/Android.mk
index d60dab4..2c7544c 100644
--- a/toolbox/Android.mk
+++ b/toolbox/Android.mk
@@ -56,6 +56,7 @@
nandread \
newfs_msdos \
ps \
+ prlimit \
renice \
restorecon \
route \
diff --git a/toolbox/prlimit.c b/toolbox/prlimit.c
new file mode 100644
index 0000000..8cf202a
--- /dev/null
+++ b/toolbox/prlimit.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2014, The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google, Inc. nor the names of its contributors
+ * may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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
+ * COPYRIGHT OWNER 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.
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+static void
+usage(const char *s)
+{
+ fprintf(stderr, "usage: %s pid resource cur max\n", s);
+ exit(EXIT_FAILURE);
+}
+
+int prlimit_main(int argc, char *argv[])
+{
+ pid_t pid;
+ struct rlimit64 rl;
+ int resource;
+ int rc;
+
+ if (argc != 5)
+ usage(*argv);
+
+ if (sscanf(argv[1], "%d", &pid) != 1)
+ usage(*argv);
+
+ if (sscanf(argv[2], "%d", &resource) != 1)
+ usage(*argv);
+
+ if (sscanf(argv[3], "%llu", &rl.rlim_cur) != 1)
+ usage(*argv);
+
+ if (sscanf(argv[4], "%llu", &rl.rlim_max) != 1)
+ usage(*argv);
+
+ printf("setting resource %d of pid %d to [%llu,%llu]\n", resource, pid,
+ rl.rlim_cur, rl.rlim_max);
+ rc = prlimit64(pid, resource, &rl, NULL);
+ if (rc < 0) {
+ perror("prlimit");
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
diff --git a/toolbox/ps.c b/toolbox/ps.c
index d0a8db3..cf3f05a 100644
--- a/toolbox/ps.c
+++ b/toolbox/ps.c
@@ -1,6 +1,7 @@
#include <ctype.h>
#include <dirent.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -29,6 +30,12 @@
#define SHOW_NUMERIC_UID 32
#define SHOW_ABI 64
+#if __LP64__
+#define PC_WIDTH 10 /* Realistically, the top bits will be 0, so don't waste space. */
+#else
+#define PC_WIDTH (2*sizeof(uintptr_t))
+#endif
+
static int display_flags = 0;
static int ppid_filter = 0;
@@ -44,7 +51,8 @@
int fd, r;
char *ptr, *name, *state;
int ppid;
- unsigned wchan, rss, vss, eip;
+ unsigned rss, vss;
+ uintptr_t eip;
unsigned utime, stime;
int prio, nice, rtprio, sched, psr;
struct passwd *pw;
@@ -124,7 +132,7 @@
nexttok(&ptr); // blocked
nexttok(&ptr); // sigignore
nexttok(&ptr); // sigcatch
- wchan = strtoul(nexttok(&ptr), 0, 10); // wchan
+ nexttok(&ptr); // wchan
nexttok(&ptr); // nswap
nexttok(&ptr); // cnswap
nexttok(&ptr); // exit signal
@@ -176,7 +184,16 @@
else
printf(" %.2s ", get_sched_policy_name(p));
}
- printf(" %08x %08x %s ", wchan, eip, state);
+ char path[PATH_MAX];
+ snprintf(path, sizeof(path), "/proc/%d/wchan", pid);
+ char wchan[10];
+ int fd = open(path, O_RDONLY);
+ ssize_t wchan_len = read(fd, wchan, sizeof(wchan));
+ if (wchan_len == -1) {
+ wchan[wchan_len = 0] = '\0';
+ }
+ close(fd);
+ printf(" %10.*s %0*" PRIxPTR " %s ", (int) wchan_len, wchan, (int) PC_WIDTH, eip, state);
if (display_flags & SHOW_ABI) {
print_exe_abi(pid);
}
@@ -285,12 +302,13 @@
}
if (display_flags & SHOW_MACLABEL) {
- printf("LABEL USER PID PPID NAME\n");
+ printf("LABEL USER PID PPID NAME\n");
} else {
- printf("USER PID PPID VSIZE RSS %s%s %s WCHAN PC %sNAME\n",
+ printf("USER PID PPID VSIZE RSS %s%s %sWCHAN %*s %sNAME\n",
(display_flags&SHOW_CPU)?"CPU ":"",
(display_flags&SHOW_PRIO)?"PRIO NICE RTPRI SCHED ":"",
(display_flags&SHOW_POLICY)?"PCY " : "",
+ (int) PC_WIDTH, "PC",
(display_flags&SHOW_ABI)?"ABI " : "");
}
while((de = readdir(d)) != 0){