Merge "Move get_my_path_darwin to C++."
diff --git a/include/cutils/endian.h b/include/cutils/endian.h
new file mode 100644
index 0000000..3d27ce6
--- /dev/null
+++ b/include/cutils/endian.h
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ */
+
+#ifndef __CUTILS_ENDIAN_H
+#define __CUTILS_ENDIAN_H
+
+#if defined(__linux__) && !defined(TEST_CUTILS_ENDIAN_H)
+#include <endian.h>
+#else
+
+#if !defined(__BYTE_ORDER__)
+/* gcc and clang predefine __BYTE_ORDER__, so this should never happen */
+#error Compiler does not define __BYTE_ORDER__
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#define htobe16(x) (x)
+#define htobe32(x) (x)
+#define htobe64(x) (x)
+#define htole16(x) __builtin_bswap16(x)
+#define htole32(x) __builtin_bswap32(x)
+#define htole64(x) __builtin_bswap64(x)
+#else
+#define htobe16(x) __builtin_bswap16(x)
+#define htobe32(x) __builtin_bswap32(x)
+#define htobe64(x) __builtin_bswap64(x)
+#define htole16(x) (x)
+#define htole32(x) (x)
+#define htole64(x) (x)
+#endif /* __BYTE_ORDER__ */
+
+#define be16toh(x) htobe16(x)
+#define le16toh(x) htole16(x)
+#define be32toh(x) htobe32(x)
+#define le32toh(x) htole32(x)
+#define be64toh(x) htobe64(x)
+#define le64toh(x) htole64(x)
+
+#endif /* defined(__linux__) */
+
+#endif /* __CUTILS_ENDIAN_H */
diff --git a/include/cutils/trace.h b/include/cutils/trace.h
index 9d039e6..e4ed179 100644
--- a/include/cutils/trace.h
+++ b/include/cutils/trace.h
@@ -18,6 +18,7 @@
#define _LIBS_CUTILS_TRACE_H
#include <inttypes.h>
+#include <stdatomic.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
@@ -25,7 +26,6 @@
#include <sys/types.h>
#include <unistd.h>
-#include <cutils/atomic.h>
#include <cutils/compiler.h>
__BEGIN_DECLS
@@ -113,7 +113,7 @@
* Nonzero indicates setup has completed.
* Note: This does NOT indicate whether or not setup was successful.
*/
-extern volatile int32_t atrace_is_ready;
+extern atomic_bool atrace_is_ready;
/**
* Set of ATRACE_TAG flags to trace for, initialized to ATRACE_TAG_NOT_READY.
@@ -136,7 +136,7 @@
#define ATRACE_INIT() atrace_init()
static inline void atrace_init()
{
- if (CC_UNLIKELY(!android_atomic_acquire_load(&atrace_is_ready))) {
+ if (CC_UNLIKELY(!atomic_load_explicit(&atrace_is_ready, memory_order_acquire))) {
atrace_setup();
}
}
diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h
index fed81f8..02fe2b5 100644
--- a/include/private/android_filesystem_config.h
+++ b/include/private/android_filesystem_config.h
@@ -215,6 +215,8 @@
void fs_config(const char *path, int dir,
unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities);
+ssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc);
+
__END_DECLS
#endif
diff --git a/include/system/window.h b/include/system/window.h
index af0418b..a875427 100644
--- a/include/system/window.h
+++ b/include/system/window.h
@@ -300,7 +300,8 @@
NATIVE_WINDOW_SET_POST_TRANSFORM_CROP = 16, /* private */
NATIVE_WINDOW_SET_BUFFERS_STICKY_TRANSFORM = 17,/* private */
NATIVE_WINDOW_SET_SIDEBAND_STREAM = 18,
- NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19
+ NATIVE_WINDOW_SET_BUFFERS_DATASPACE = 19,
+ NATIVE_WINDOW_SET_SURFACE_DAMAGE = 20, /* private */
};
/* parameter for NATIVE_WINDOW_[API_][DIS]CONNECT */
@@ -493,31 +494,12 @@
* DO NOT CALL THIS HOOK DIRECTLY. Instead, use the helper functions
* defined below.
*
- * (*perform)() returns -ENOENT if the 'what' parameter is not supported
- * by the surface's implementation.
+ * (*perform)() returns -ENOENT if the 'what' parameter is not supported
+ * by the surface's implementation.
*
- * The valid operations are:
- * NATIVE_WINDOW_SET_USAGE
- * NATIVE_WINDOW_CONNECT (deprecated)
- * NATIVE_WINDOW_DISCONNECT (deprecated)
- * NATIVE_WINDOW_SET_CROP (private)
- * NATIVE_WINDOW_SET_BUFFER_COUNT
- * NATIVE_WINDOW_SET_BUFFERS_GEOMETRY (deprecated)
- * NATIVE_WINDOW_SET_BUFFERS_TRANSFORM
- * NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP
- * NATIVE_WINDOW_SET_BUFFERS_DATASPACE
- * NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS
- * NATIVE_WINDOW_SET_BUFFERS_FORMAT
- * NATIVE_WINDOW_SET_SCALING_MODE (private)
- * NATIVE_WINDOW_LOCK (private)
- * NATIVE_WINDOW_UNLOCK_AND_POST (private)
- * NATIVE_WINDOW_API_CONNECT (private)
- * NATIVE_WINDOW_API_DISCONNECT (private)
- * NATIVE_WINDOW_SET_BUFFERS_USER_DIMENSIONS (private)
- * NATIVE_WINDOW_SET_POST_TRANSFORM_CROP (private)
- *
+ * See above for a list of valid operations, such as
+ * NATIVE_WINDOW_SET_USAGE or NATIVE_WINDOW_CONNECT
*/
-
int (*perform)(struct ANativeWindow* window,
int operation, ... );
@@ -934,6 +916,30 @@
sidebandHandle);
}
+/*
+ * native_window_set_surface_damage(..., android_native_rect_t* rects, int numRects)
+ * Set the surface damage (i.e., the region of the surface that has changed
+ * since the previous frame). The damage set by this call will be reset (to the
+ * default of full-surface damage) after calling queue, so this must be called
+ * prior to every frame with damage that does not cover the whole surface if the
+ * caller desires downstream consumers to use this optimization.
+ *
+ * The damage region is specified as an array of rectangles, with the important
+ * caveat that the origin of the surface is considered to be the bottom-left
+ * corner, as in OpenGL ES.
+ *
+ * If numRects is set to 0, rects may be NULL, and the surface damage will be
+ * set to the full surface (the same as if this function had not been called for
+ * this frame).
+ */
+static inline int native_window_set_surface_damage(
+ struct ANativeWindow* window,
+ const android_native_rect_t* rects, size_t numRects)
+{
+ return window->perform(window, NATIVE_WINDOW_SET_SURFACE_DAMAGE,
+ rects, numRects);
+}
+
__END_DECLS
#endif /* SYSTEM_CORE_INCLUDE_ANDROID_WINDOW_H */
diff --git a/init/property_service.cpp b/init/property_service.cpp
index 2fa81d4..8544951 100644
--- a/init/property_service.cpp
+++ b/init/property_service.cpp
@@ -508,7 +508,6 @@
void load_all_props() {
load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL);
- load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL);
load_properties_from_file(PROP_PATH_VENDOR_BUILD, NULL);
load_properties_from_file(PROP_PATH_BOOTIMAGE_BUILD, NULL);
load_properties_from_file(PROP_PATH_FACTORY, "ro.*");
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index b875efd..54cace9 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -57,7 +57,6 @@
libbacktrace_shared_libraries := \
libbase \
libunwind \
- libunwind-ptrace \
libbacktrace_shared_libraries_host := \
liblog \
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 659f614..9f8023e 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -19,11 +19,54 @@
** by the device side of adb.
*/
+#define LOG_TAG "fs_config"
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
+#include <sys/types.h>
+#include <log/log.h>
#include <private/android_filesystem_config.h>
+#include <utils/Compat.h>
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* The following structure is stored little endian */
+struct fs_path_config_from_file {
+ uint16_t len;
+ uint16_t mode;
+ uint16_t uid;
+ uint16_t gid;
+ uint64_t capabilities;
+ char prefix[];
+} __attribute__((__aligned__(sizeof(uint64_t))));
+
+/* My kingdom for <endian.h> */
+static inline uint16_t get2LE(const uint8_t* src)
+{
+ return src[0] | (src[1] << 8);
+}
+
+static inline uint64_t get8LE(const uint8_t* src)
+{
+ uint32_t low, high;
+
+ low = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+ high = src[4] | (src[5] << 8) | (src[6] << 16) | (src[7] << 24);
+ return ((uint64_t) high << 32) | (uint64_t) low;
+}
+
+#define ALIGN(x, alignment) ( ((x) + ((alignment) - 1)) & ~((alignment) - 1) )
/* Rules for directories.
** These rules are applied based on "first match", so they
@@ -61,6 +104,9 @@
** way up to the root. Prefixes ending in * denotes wildcard
** and will allow partial matches.
*/
+static const char conf_dir[] = "/system/etc/fs_config_dirs";
+static const char conf_file[] = "/system/etc/fs_config_files";
+
static const struct fs_path_config android_files[] = {
{ 00440, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.rc" },
{ 00550, AID_ROOT, AID_SHELL, 0, "system/etc/init.goldfish.sh" },
@@ -68,6 +114,8 @@
{ 00550, AID_DHCP, AID_SHELL, 0, "system/etc/dhcpcd/dhcpcd-run-hooks" },
{ 00555, AID_ROOT, AID_ROOT, 0, "system/etc/ppp/*" },
{ 00555, AID_ROOT, AID_ROOT, 0, "system/etc/rc.*" },
+ { 00444, AID_ROOT, AID_ROOT, 0, conf_dir + 1 },
+ { 00444, AID_ROOT, AID_ROOT, 0, conf_file + 1 },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app/*" },
{ 00644, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/*" },
{ 00644, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private/*" },
@@ -101,30 +149,102 @@
{ 00644, AID_ROOT, AID_ROOT, 0, 0 },
};
+static int fs_config_open(int dir)
+{
+ int fd = -1;
+
+ const char *out = getenv("OUT");
+ if (out && *out) {
+ char *name = NULL;
+ asprintf(&name, "%s%s", out, dir ? conf_dir : conf_file);
+ if (name) {
+ fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY | O_BINARY));
+ free(name);
+ }
+ }
+ if (fd < 0) {
+ fd = TEMP_FAILURE_RETRY(open(dir ? conf_dir : conf_file, O_RDONLY | O_BINARY));
+ }
+ return fd;
+}
+
+static bool fs_config_cmp(bool dir, const char *prefix, size_t len,
+ const char *path, size_t plen)
+{
+ if (dir) {
+ if (plen < len) {
+ return false;
+ }
+ } else {
+ /* If name ends in * then allow partial matches. */
+ if (prefix[len - 1] == '*') {
+ return !strncmp(prefix, path, len - 1);
+ }
+ if (plen != len) {
+ return false;
+ }
+ }
+ return !strncmp(prefix, path, len);
+}
+
void fs_config(const char *path, int dir,
unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities)
{
const struct fs_path_config *pc;
- int plen;
+ int fd, plen;
if (path[0] == '/') {
path++;
}
- pc = dir ? android_dirs : android_files;
plen = strlen(path);
- for(; pc->prefix; pc++){
- int len = strlen(pc->prefix);
- if (dir) {
- if(plen < len) continue;
- if(!strncmp(pc->prefix, path, len)) break;
- continue;
+
+ fd = fs_config_open(dir);
+ if (fd >= 0) {
+ struct fs_path_config_from_file header;
+
+ while (TEMP_FAILURE_RETRY(read(fd, &header, sizeof(header))) == sizeof(header)) {
+ char *prefix;
+ uint16_t host_len = get2LE((const uint8_t *)&header.len);
+ ssize_t len, remainder = host_len - sizeof(header);
+ if (remainder <= 0) {
+ ALOGE("%s len is corrupted", dir ? conf_dir : conf_file);
+ break;
+ }
+ prefix = calloc(1, remainder);
+ if (!prefix) {
+ ALOGE("%s out of memory", dir ? conf_dir : conf_file);
+ break;
+ }
+ if (TEMP_FAILURE_RETRY(read(fd, prefix, remainder)) != remainder) {
+ free(prefix);
+ ALOGE("%s prefix is truncated", dir ? conf_dir : conf_file);
+ break;
+ }
+ len = strnlen(prefix, remainder);
+ if (len >= remainder) { /* missing a terminating null */
+ free(prefix);
+ ALOGE("%s is corrupted", dir ? conf_dir : conf_file);
+ break;
+ }
+ if (fs_config_cmp(dir, prefix, len, path, plen)) {
+ free(prefix);
+ close(fd);
+ *uid = get2LE((const uint8_t *)&(header.uid));
+ *gid = get2LE((const uint8_t *)&(header.gid));
+ *mode = (*mode & (~07777)) | get2LE((const uint8_t *)&(header.mode));
+ *capabilities = get8LE((const uint8_t *)&(header.capabilities));
+ return;
+ }
+ free(prefix);
}
- /* If name ends in * then allow partial matches. */
- if (pc->prefix[len -1] == '*') {
- if(!strncmp(pc->prefix, path, len - 1)) break;
- } else if (plen == len){
- if(!strncmp(pc->prefix, path, len)) break;
+ close(fd);
+ }
+
+ pc = dir ? android_dirs : android_files;
+ for(; pc->prefix; pc++){
+ if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) {
+ break;
}
}
*uid = pc->uid;
@@ -132,3 +252,22 @@
*mode = (*mode & (~07777)) | pc->mode;
*capabilities = pc->capabilities;
}
+
+ssize_t fs_config_generate(char *buffer, size_t length, const struct fs_path_config *pc)
+{
+ struct fs_path_config_from_file *p = (struct fs_path_config_from_file *)buffer;
+ size_t len = ALIGN(sizeof(*p) + strlen(pc->prefix) + 1, sizeof(uint64_t));
+
+ if ((length < len) || (len > UINT16_MAX)) {
+ return -ENOSPC;
+ }
+ memset(p, 0, len);
+ uint16_t host_len = len;
+ p->len = get2LE((const uint8_t *)&host_len);
+ p->mode = get2LE((const uint8_t *)&(pc->mode));
+ p->uid = get2LE((const uint8_t *)&(pc->uid));
+ p->gid = get2LE((const uint8_t *)&(pc->gid));
+ p->capabilities = get8LE((const uint8_t *)&(pc->capabilities));
+ strcpy(p->prefix, pc->prefix);
+ return len;
+}
diff --git a/libcutils/tests/Android.mk b/libcutils/tests/Android.mk
index cf70345..577b61d 100644
--- a/libcutils/tests/Android.mk
+++ b/libcutils/tests/Android.mk
@@ -16,6 +16,7 @@
test_src_files := \
test_str_parms.cpp \
+ EndianTest.cpp
test_target_only_src_files := \
MemsetTest.cpp \
diff --git a/libcutils/tests/EndianTest.cpp b/libcutils/tests/EndianTest.cpp
new file mode 100644
index 0000000..a484da7
--- /dev/null
+++ b/libcutils/tests/EndianTest.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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 <stdint.h>
+
+#define TEST_CUTILS_ENDIAN_H
+#include <cutils/endian.h>
+#include <gtest/gtest.h>
+
+static const uint16_t host16 = 0x1122;
+static const uint32_t host32 = 0x11223344;
+static const uint64_t host64 = 0x1122334455667788;
+static const uint16_t swapped16 = 0x2211;
+static const uint32_t swapped32 = 0x44332211;
+static const uint64_t swapped64 = 0x8877665544332211;
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+static const uint16_t le16 = swapped16;
+static const uint32_t le32 = swapped32;
+static const uint64_t le64 = swapped64;
+static const uint16_t be16 = native16;
+static const uint32_t be32 = native32;
+static const uint64_t be64 = native64;
+#else
+static const uint16_t le16 = host16;
+static const uint32_t le32 = host32;
+static const uint64_t le64 = host64;
+static const uint16_t be16 = swapped16;
+static const uint32_t be32 = swapped32;
+static const uint64_t be64 = swapped64;
+#endif
+
+TEST(endian, endian) {
+ EXPECT_EQ(le16, htole16(host16));
+ EXPECT_EQ(host16, le16toh(htole16(host16)));
+ EXPECT_EQ(be16, htobe16(host16));
+ EXPECT_EQ(host16, be16toh(htobe16(host16)));
+
+ EXPECT_EQ(le32, htole32(host32));
+ EXPECT_EQ(host32, le32toh(htole32(host32)));
+ EXPECT_EQ(be32, htobe32(host32));
+ EXPECT_EQ(host32, be32toh(htobe32(host32)));
+
+ EXPECT_EQ(le64, htole64(host64));
+ EXPECT_EQ(host64, le64toh(htole64(host64)));
+ EXPECT_EQ(be64, htobe64(host64));
+ EXPECT_EQ(host64, be64toh(htobe64(host64)));
+}
diff --git a/libcutils/trace-dev.c b/libcutils/trace-dev.c
index 4396625..a06987e 100644
--- a/libcutils/trace-dev.c
+++ b/libcutils/trace-dev.c
@@ -18,11 +18,11 @@
#include <fcntl.h>
#include <limits.h>
#include <pthread.h>
+#include <stdatomic.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
-#include <cutils/atomic.h>
#include <cutils/compiler.h>
#include <cutils/properties.h>
#include <cutils/trace.h>
@@ -37,11 +37,11 @@
*/
#define ATRACE_MESSAGE_LENGTH 1024
-volatile int32_t atrace_is_ready = 0;
+atomic_bool atrace_is_ready = ATOMIC_VAR_INIT(false);
int atrace_marker_fd = -1;
uint64_t atrace_enabled_tags = ATRACE_TAG_NOT_READY;
static bool atrace_is_debuggable = false;
-static volatile int32_t atrace_is_enabled = 1;
+static atomic_bool atrace_is_enabled = ATOMIC_VAR_INIT(true);
static pthread_once_t atrace_once_control = PTHREAD_ONCE_INIT;
static pthread_mutex_t atrace_tags_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -58,7 +58,7 @@
// the Zygote process from tracing.
void atrace_set_tracing_enabled(bool enabled)
{
- android_atomic_release_store(enabled ? 1 : 0, &atrace_is_enabled);
+ atomic_store_explicit(&atrace_is_enabled, enabled, memory_order_release);
atrace_update_tags();
}
@@ -155,8 +155,8 @@
void atrace_update_tags()
{
uint64_t tags;
- if (CC_UNLIKELY(android_atomic_acquire_load(&atrace_is_ready))) {
- if (android_atomic_acquire_load(&atrace_is_enabled)) {
+ if (CC_UNLIKELY(atomic_load_explicit(&atrace_is_ready, memory_order_acquire))) {
+ if (atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
tags = atrace_get_property();
pthread_mutex_lock(&atrace_tags_mutex);
atrace_enabled_tags = tags;
@@ -183,7 +183,7 @@
atrace_enabled_tags = atrace_get_property();
done:
- android_atomic_release_store(1, &atrace_is_ready);
+ atomic_store_explicit(&atrace_is_ready, true, memory_order_release);
}
void atrace_setup()
diff --git a/libcutils/trace-host.c b/libcutils/trace-host.c
index b87e543..6478e3e 100644
--- a/libcutils/trace-host.c
+++ b/libcutils/trace-host.c
@@ -20,7 +20,7 @@
#define __unused __attribute__((__unused__))
#endif
-volatile int32_t atrace_is_ready = 1;
+atomic_bool atrace_is_ready = ATOMIC_VAR_INIT(true);
int atrace_marker_fd = -1;
uint64_t atrace_enabled_tags = 0;
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index 65c09e0..311678a 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -238,14 +238,15 @@
struct backed_block *last_bb = NULL;
struct backed_block *bb;
struct backed_block *start;
+ unsigned int last_block = 0;
int64_t file_len = 0;
int ret;
/*
- * overhead is sparse file header, initial skip chunk, split chunk, end
- * skip chunk, and crc chunk.
+ * overhead is sparse file header, the potential end skip
+ * chunk and crc chunk.
*/
- int overhead = sizeof(sparse_header_t) + 4 * sizeof(chunk_header_t) +
+ int overhead = sizeof(sparse_header_t) + 2 * sizeof(chunk_header_t) +
sizeof(uint32_t);
len -= overhead;
@@ -258,6 +259,11 @@
for (bb = start; bb; bb = backed_block_iter_next(bb)) {
count = 0;
+ if (backed_block_block(bb) > last_block)
+ count += sizeof(chunk_header_t);
+ last_block = backed_block_block(bb) +
+ DIV_ROUND_UP(backed_block_len(bb), to->block_size);
+
/* will call out_counter_write to update count */
ret = sparse_file_write_block(out_counter, bb);
if (ret) {
@@ -270,6 +276,7 @@
* requested size, split the chunk. Results in sparse files that
* are at least 7/8ths of the requested size
*/
+ file_len += sizeof(chunk_header_t);
if (!last_bb || (len - file_len > (len / 8))) {
backed_block_split(from->backed_block_list, bb, len - file_len);
last_bb = bb;
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 90370e9..caae54b 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -155,12 +155,14 @@
event->length = htole32(l);
memcpy(event->data, str, l);
- logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid,
- reinterpret_cast<char *>(event),
- (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
+ rc = logbuf->log(LOG_ID_EVENTS, now, uid, pid, tid,
+ reinterpret_cast<char *>(event),
+ (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
free(event);
- notify = true;
+ if (rc >= 0) {
+ notify = true;
+ }
}
// log to main
@@ -197,17 +199,22 @@
strncpy(newstr + 1 + l, str, estr - str);
strcpy(newstr + 1 + l + (estr - str), ecomm);
- logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
- (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
+ rc = logbuf->log(LOG_ID_MAIN, now, uid, pid, tid, newstr,
+ (n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
free(newstr);
- notify = true;
+ if (rc >= 0) {
+ notify = true;
+ }
}
free(str);
if (notify) {
reader->notifyNewLog();
+ if (rc < 0) {
+ rc = n;
+ }
}
return rc;
@@ -216,7 +223,7 @@
int LogAudit::log(char *buf) {
char *audit = strstr(buf, " audit(");
if (!audit) {
- return 0;
+ return -EXDEV;
}
*audit = '\0';
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 260e237..a0436ef 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -15,6 +15,7 @@
*/
#include <ctype.h>
+#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <sys/user.h>
@@ -132,11 +133,11 @@
init();
}
-void LogBuffer::log(log_id_t log_id, log_time realtime,
- uid_t uid, pid_t pid, pid_t tid,
- const char *msg, unsigned short len) {
+int LogBuffer::log(log_id_t log_id, log_time realtime,
+ uid_t uid, pid_t pid, pid_t tid,
+ const char *msg, unsigned short len) {
if ((log_id >= LOG_ID_MAX) || (log_id < 0)) {
- return;
+ return -EINVAL;
}
LogBufferElement *elem = new LogBufferElement(log_id, realtime,
uid, pid, tid, msg, len);
@@ -193,6 +194,8 @@
stats.add(elem);
maybePrune(log_id);
pthread_mutex_unlock(&mLogElementsLock);
+
+ return len;
}
// If we're using more than 256K of memory for log entries, prune
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index a29e015..9ee243d 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -48,9 +48,9 @@
LogBuffer(LastLogTimes *times);
void init();
- void log(log_id_t log_id, log_time realtime,
- uid_t uid, pid_t pid, pid_t tid,
- const char *msg, unsigned short len);
+ int log(log_id_t log_id, log_time realtime,
+ uid_t uid, pid_t pid, pid_t tid,
+ const char *msg, unsigned short len);
uint64_t flushTo(SocketClient *writer, const uint64_t start,
bool privileged,
int (*filter)(const LogBufferElement *element, void *arg) = NULL,
diff --git a/logd/LogListener.cpp b/logd/LogListener.cpp
index 3b4ef88..05ced06 100644
--- a/logd/LogListener.cpp
+++ b/logd/LogListener.cpp
@@ -98,10 +98,11 @@
// NB: hdr.msg_flags & MSG_TRUNC is not tested, silently passing a
// truncated message to the logs.
- logbuf->log((log_id_t)header->id, header->realtime,
- cred->uid, cred->pid, header->tid, msg,
- ((size_t) n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX);
- reader->notifyNewLog();
+ if (logbuf->log((log_id_t)header->id, header->realtime,
+ cred->uid, cred->pid, header->tid, msg,
+ ((size_t) n <= USHRT_MAX) ? (unsigned short) n : USHRT_MAX) >= 0) {
+ reader->notifyNewLog();
+ }
return true;
}
diff --git a/logd/main.cpp b/logd/main.cpp
index 4aa38b3..eb29596 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -367,12 +367,12 @@
int rc = klogctl(KLOG_READ_ALL, buf, len);
- buf[len - 1] = '\0';
+ if (rc >= 0) {
+ buf[len - 1] = '\0';
- for(char *ptr, *tok = buf;
- (rc >= 0) && ((tok = strtok_r(tok, "\r\n", &ptr)));
- tok = NULL) {
- rc = al->log(tok);
+ for (char *ptr, *tok = buf; (tok = strtok_r(tok, "\r\n", &ptr)); tok = NULL) {
+ al->log(tok);
+ }
}
}