Merge "Move trace.h to stdatomic."
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/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 11d4225..9f8023e 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -23,7 +23,6 @@
#define _GNU_SOURCE
-#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
@@ -31,13 +30,16 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <cutils/fs.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 {
@@ -49,6 +51,23 @@
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
** should start with the most specific path and work their
@@ -139,12 +158,12 @@
char *name = NULL;
asprintf(&name, "%s%s", out, dir ? conf_dir : conf_file);
if (name) {
- fd = TEMP_FAILURE_RETRY(open(name, O_RDONLY));
+ 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));
+ fd = TEMP_FAILURE_RETRY(open(dir ? conf_dir : conf_file, O_RDONLY | O_BINARY));
}
return fd;
}
@@ -172,21 +191,7 @@
unsigned *uid, unsigned *gid, unsigned *mode, uint64_t *capabilities)
{
const struct fs_path_config *pc;
- int plen;
- struct stat st;
- void *address = NULL;
-
- int fd = fs_config_open(dir);
- if ((fd >= 0)
- && (TEMP_FAILURE_RETRY(fstat(fd, &st)) >= 0)
- && (size_t)st.st_size) {
- address = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (address == MAP_FAILED) {
- address = NULL;
- }
- } else if (fd >= 0) {
- close(fd);
- }
+ int fd, plen;
if (path[0] == '/') {
path++;
@@ -194,44 +199,46 @@
plen = strlen(path);
- if (address) {
- const struct fs_path_config_from_file *p = (const struct fs_path_config_from_file *)
- address;
- const char *end = (const char *)address + st.st_size;
- const struct fs_path_config_from_file *e = (const struct fs_path_config_from_file *)
- (end - sizeof(*p));
- for (; p < e; p = (const struct fs_path_config_from_file *)(((const char *)p) + le16toh(p->len))) {
- ssize_t len, remainder = le16toh(p->len) - sizeof(*p);
+ 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 is truncated", dir ? conf_dir : conf_file);
- p = e;
+ ALOGE("%s len is corrupted", dir ? conf_dir : conf_file);
break;
}
- len = (const char *)e - (const char *)p;
- if (remainder > len) {
- remainder = len;
+ prefix = calloc(1, remainder);
+ if (!prefix) {
+ ALOGE("%s out of memory", dir ? conf_dir : conf_file);
+ break;
}
- len = strnlen(p->prefix, remainder);
+ 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);
- p = e;
break;
}
- if (fs_config_cmp(dir, p->prefix, len, path, plen)) {
- 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 (p < e) {
- *uid = le16toh(p->uid);
- *gid = le16toh(p->gid);
- *mode = (*mode & (~07777)) | le16toh(p->mode);
- *capabilities = le64toh(p->capabilities);
- }
- munmap(address, st.st_size);
close(fd);
- if (p < e) {
- return;
- }
}
pc = dir ? android_dirs : android_files;
@@ -245,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/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);
+ }
}
}