Merge "adb doesn't actually use libzipfile."
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index 59a1734..e820f2a 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -19,6 +19,7 @@
*/
#include <memory>
+#include <vector>
#include <assert.h>
#include <errno.h>
@@ -983,9 +984,9 @@
static int32_t InflateToFile(int fd, const ZipEntry* entry,
uint8_t* begin, uint32_t length,
uint64_t* crc_out) {
- const uint32_t kBufSize = 32768;
- uint8_t read_buf[kBufSize];
- uint8_t write_buf[kBufSize];
+ const size_t kBufSize = 32768;
+ std::vector<uint8_t> read_buf(kBufSize);
+ std::vector<uint8_t> write_buf(kBufSize);
z_stream zstream;
int zerr;
@@ -998,7 +999,7 @@
zstream.opaque = Z_NULL;
zstream.next_in = NULL;
zstream.avail_in = 0;
- zstream.next_out = reinterpret_cast<Bytef*>(write_buf);
+ zstream.next_out = &write_buf[0];
zstream.avail_out = kBufSize;
zstream.data_type = Z_UNKNOWN;
@@ -1032,7 +1033,7 @@
/* read as much as we can */
if (zstream.avail_in == 0) {
const ZD_TYPE getSize = (compressed_length > kBufSize) ? kBufSize : compressed_length;
- const ZD_TYPE actual = TEMP_FAILURE_RETRY(read(fd, read_buf, getSize));
+ const ZD_TYPE actual = TEMP_FAILURE_RETRY(read(fd, &read_buf[0], getSize));
if (actual != getSize) {
ALOGW("Zip: inflate read failed (" ZD " vs " ZD ")", actual, getSize);
return kIoError;
@@ -1040,7 +1041,7 @@
compressed_length -= getSize;
- zstream.next_in = read_buf;
+ zstream.next_in = &read_buf[0];
zstream.avail_in = getSize;
}
@@ -1056,15 +1057,15 @@
/* write when we're full or when we're done */
if (zstream.avail_out == 0 ||
(zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
- const size_t write_size = zstream.next_out - write_buf;
+ const size_t write_size = zstream.next_out - &write_buf[0];
// The file might have declared a bogus length.
if (write_size + write_count > length) {
return -1;
}
- memcpy(begin + write_count, write_buf, write_size);
+ memcpy(begin + write_count, &write_buf[0], write_size);
write_count += write_size;
- zstream.next_out = write_buf;
+ zstream.next_out = &write_buf[0];
zstream.avail_out = kBufSize;
}
} while (zerr == Z_OK);
diff --git a/logcat/logcat.cpp b/logcat/logcat.cpp
index 7e4eadd..be96fc4 100644
--- a/logcat/logcat.cpp
+++ b/logcat/logcat.cpp
@@ -215,7 +215,7 @@
fprintf(stderr, "options include:\n"
" -s Set default filter to silent.\n"
- " Like specifying filterspec '*:s'\n"
+ " Like specifying filterspec '*:S'\n"
" -f <filename> Log to file. Default to stdout\n"
" -r [<kbytes>] Rotate log every kbytes. (16 if unspecified). Requires -f\n"
" -n <count> Sets max number of rotated logs to <count>, default 4\n"
@@ -250,21 +250,19 @@
fprintf(stderr,"\nfilterspecs are a series of \n"
" <tag>[:priority]\n\n"
"where <tag> is a log component tag (or * for all) and priority is:\n"
- " V Verbose\n"
- " D Debug\n"
+ " V Verbose (default for <tag>)\n"
+ " D Debug (default for '*')\n"
" I Info\n"
" W Warn\n"
" E Error\n"
" F Fatal\n"
- " S Silent (supress all output)\n"
- "\n'*' means '*:d' and <tag> by itself means <tag>:v\n"
- "\nIf not specified on the commandline, filterspec is set from ANDROID_LOG_TAGS.\n"
- "If no filterspec is found, filter defaults to '*:I'\n"
- "\nIf not specified with -v, format is set from ANDROID_PRINTF_LOG\n"
+ " S Silent (suppress all output)\n"
+ "\n'*' by itself means '*:D' and <tag> by itself means <tag>:V.\n"
+ "If no '*' filterspec or -s on command line, all filter defaults to '*:V'.\n"
+ "eg: '*:S <tag>' prints only <tag>, '<tag>:S' suppresses all <tag> log messages.\n"
+ "\nIf not specified on the command line, filterspec is set from ANDROID_LOG_TAGS.\n"
+ "\nIf not specified with -v on command line, format is set from ANDROID_PRINTF_LOG\n"
"or defaults to \"threadtime\"\n\n");
-
-
-
}
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index b358485..de2db67 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -505,12 +505,14 @@
while (fgets(buffer, sizeof(buffer), fp)) {
static const char match_1[] = "4 log.txt";
static const char match_2[] = "8 log.txt";
- static const char match_3[] = "16 log.txt";
+ static const char match_3[] = "12 log.txt";
+ static const char match_4[] = "16 log.txt";
static const char total[] = "total ";
if (!strncmp(buffer, match_1, sizeof(match_1) - 1)
|| !strncmp(buffer, match_2, sizeof(match_2) - 1)
- || !strncmp(buffer, match_3, sizeof(match_3) - 1)) {
+ || !strncmp(buffer, match_3, sizeof(match_3) - 1)
+ || !strncmp(buffer, match_4, sizeof(match_4) - 1)) {
++count;
} else if (strncmp(buffer, total, sizeof(total) - 1)) {
fprintf(stderr, "WARNING: Parse error: %s", buffer);
diff --git a/logd/CommandListener.cpp b/logd/CommandListener.cpp
index d7088b4..561ea3e 100644
--- a/logd/CommandListener.cpp
+++ b/logd/CommandListener.cpp
@@ -44,6 +44,7 @@
registerCmd(new GetStatisticsCmd(buf));
registerCmd(new SetPruneListCmd(buf));
registerCmd(new GetPruneListCmd(buf));
+ registerCmd(new ReinitCmd());
}
CommandListener::ShutdownCmd::ShutdownCmd(LogBuffer *buf, LogReader *reader,
@@ -296,6 +297,21 @@
return 0;
}
+CommandListener::ReinitCmd::ReinitCmd()
+ : LogCommand("reinit")
+{ }
+
+int CommandListener::ReinitCmd::runCommand(SocketClient *cli,
+ int /*argc*/, char ** /*argv*/) {
+ setname();
+
+ reinit_signal_handler(SIGHUP);
+
+ cli->sendMsg("success");
+
+ return 0;
+}
+
int CommandListener::getLogSocket() {
static const char socketName[] = "logd";
int sock = android_get_control_socket(socketName);
diff --git a/logd/CommandListener.h b/logd/CommandListener.h
index cd1c306..83e06b4 100644
--- a/logd/CommandListener.h
+++ b/logd/CommandListener.h
@@ -23,6 +23,9 @@
#include "LogReader.h"
#include "LogListener.h"
+// See main.cpp for implementation
+void reinit_signal_handler(int /*signal*/);
+
class CommandListener : public FrameworkListener {
LogBuffer &mBuf;
@@ -60,6 +63,14 @@
LogBufferCmd(GetStatistics)
LogBufferCmd(GetPruneList)
LogBufferCmd(SetPruneList)
+
+ class ReinitCmd : public LogCommand {
+ public:
+ ReinitCmd();
+ virtual ~ReinitCmd() {}
+ int runCommand(SocketClient *c, int argc, char ** argv);
+ };
+
};
#endif
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index edda6c4..2b495ab 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -92,10 +92,7 @@
return value;
}
-LogBuffer::LogBuffer(LastLogTimes *times)
- : mTimes(*times) {
- pthread_mutex_init(&mLogElementsLock, NULL);
-
+void LogBuffer::init() {
static const char global_tuneable[] = "persist.logd.size"; // Settings App
static const char global_default[] = "ro.logd.size"; // BoardConfig.mk
@@ -131,6 +128,13 @@
}
}
+LogBuffer::LogBuffer(LastLogTimes *times)
+ : mTimes(*times) {
+ pthread_mutex_init(&mLogElementsLock, NULL);
+
+ 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) {
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index b0003de..86a2a2a 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -46,6 +46,7 @@
LastLogTimes &mTimes;
LogBuffer(LastLogTimes *times);
+ void init();
void log(log_id_t log_id, log_time realtime,
uid_t uid, pid_t pid, pid_t tid,
diff --git a/logd/main.cpp b/logd/main.cpp
index 243bee4..2d799bf 100644
--- a/logd/main.cpp
+++ b/logd/main.cpp
@@ -17,7 +17,10 @@
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
+#include <poll.h>
#include <sched.h>
+#include <semaphore.h>
+#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -30,6 +33,7 @@
#include <cutils/properties.h>
#include <cutils/sched_policy.h>
+#include <cutils/sockets.h>
#include "private/android_filesystem_config.h"
#include "CommandListener.h"
@@ -127,17 +131,100 @@
return def;
}
-// Foreground waits for exit of the three main persistent threads that
-// are started here. The three threads are created to manage UNIX
-// domain client sockets for writing, reading and controlling the user
-// space logger. Additional transitory per-client threads are created
-// for each reader once they register.
-int main() {
- bool auditd = property_get_bool("logd.auditd", true);
+static sem_t reinit;
+static bool reinit_running = false;
+static LogBuffer *logBuf = NULL;
- int fdDmesg = -1;
- if (auditd && property_get_bool("logd.auditd.dmesg", true)) {
- fdDmesg = open("/dev/kmsg", O_WRONLY);
+static void *reinit_thread_start(void * /*obj*/) {
+ prctl(PR_SET_NAME, "logd.daemon");
+ set_sched_policy(0, SP_BACKGROUND);
+
+ setgid(AID_LOGD);
+ setuid(AID_LOGD);
+
+ while (reinit_running && !sem_wait(&reinit) && reinit_running) {
+ // Anything that reads persist.<property>
+ if (logBuf) {
+ logBuf->init();
+ }
+ }
+
+ return NULL;
+}
+
+// Serves as a global method to trigger reinitialization
+// and as a function that can be provided to signal().
+void reinit_signal_handler(int /*signal*/) {
+ sem_post(&reinit);
+}
+
+// Remove the static, and use this variable
+// globally for debugging if necessary. eg:
+// write(fdDmesg, "I am here\n", 10);
+static int fdDmesg = -1;
+
+// Foreground waits for exit of the main persistent threads
+// that are started here. The threads are created to manage
+// UNIX domain client sockets for writing, reading and
+// controlling the user space logger, and for any additional
+// logging plugins like auditd and restart control. Additional
+// transitory per-client threads are created for each reader.
+int main(int argc, char *argv[]) {
+ fdDmesg = open("/dev/kmsg", O_WRONLY);
+
+ // issue reinit command. KISS argument parsing.
+ if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {
+ int sock = TEMP_FAILURE_RETRY(
+ socket_local_client("logd",
+ ANDROID_SOCKET_NAMESPACE_RESERVED,
+ SOCK_STREAM));
+ if (sock < 0) {
+ return -errno;
+ }
+ static const char reinit[] = "reinit";
+ ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit)));
+ if (ret < 0) {
+ return -errno;
+ }
+ struct pollfd p;
+ memset(&p, 0, sizeof(p));
+ p.fd = sock;
+ p.events = POLLIN;
+ ret = TEMP_FAILURE_RETRY(poll(&p, 1, 100));
+ if (ret < 0) {
+ return -errno;
+ }
+ if ((ret == 0) || !(p.revents & POLLIN)) {
+ return -ETIME;
+ }
+ static const char success[] = "success";
+ char buffer[sizeof(success) - 1];
+ memset(buffer, 0, sizeof(buffer));
+ ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
+ if (ret < 0) {
+ return -errno;
+ }
+ return strncmp(buffer, success, sizeof(success) - 1) != 0;
+ }
+
+ // Reinit Thread
+ sem_init(&reinit, 0, 0);
+ pthread_attr_t attr;
+ if (!pthread_attr_init(&attr)) {
+ struct sched_param param;
+
+ memset(¶m, 0, sizeof(param));
+ pthread_attr_setschedparam(&attr, ¶m);
+ pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
+ if (!pthread_attr_setdetachstate(&attr,
+ PTHREAD_CREATE_DETACHED)) {
+ pthread_t thread;
+ reinit_running = true;
+ if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) {
+ reinit_running = false;
+ }
+ }
+ pthread_attr_destroy(&attr);
}
if (drop_privs() != 0) {
@@ -153,7 +240,9 @@
// LogBuffer is the object which is responsible for holding all
// log entries.
- LogBuffer *logBuf = new LogBuffer(times);
+ logBuf = new LogBuffer(times);
+
+ signal(SIGHUP, reinit_signal_handler);
{
char property[PROPERTY_VALUE_MAX];
@@ -195,9 +284,13 @@
// initiated log messages. New log entries are added to LogBuffer
// and LogReader is notified to send updates to connected clients.
+ bool auditd = property_get_bool("logd.auditd", true);
+
if (auditd) {
+ bool dmesg = property_get_bool("logd.auditd.dmesg", true);
+
// failure is an option ... messages are in dmesg (required by standard)
- LogAudit *al = new LogAudit(logBuf, reader, fdDmesg);
+ LogAudit *al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1);
int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
if (len > 0) {
@@ -217,11 +310,10 @@
if (al->startListener()) {
delete al;
- close(fdDmesg);
}
}
- pause();
+ TEMP_FAILURE_RETRY(pause());
+
exit(0);
}
-
diff --git a/rootdir/init.rc b/rootdir/init.rc
index e3b5db9..bc36c3e 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -164,6 +164,7 @@
# Load properties from /system/ + /factory after fs mount.
on load_all_props_action
load_all_props
+ start logd-reinit
# Indicate to fw loaders that the relevant mounts are up.
on firmware_mounts_complete
@@ -430,6 +431,7 @@
on property:vold.decrypt=trigger_load_persist_props
load_persist_props
+ start logd-reinit
on property:vold.decrypt=trigger_post_fs_data
trigger post-fs-data
@@ -472,6 +474,10 @@
socket logdr seqpacket 0666 logd logd
socket logdw dgram 0222 logd logd
+service logd-reinit /system/bin/logd --reinit
+ oneshot
+ disabled
+
service healthd /sbin/healthd
class core
critical