blob: d93be80fddc3d0e6c92a78db4d5c218ac81ef8a8 [file] [log] [blame]
/*
* Copyright (C) 2019 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.
*/
#define LOG_TAG "vsock_logcat"
#include <sstream>
#include <cutils/properties.h>
#include <gflags/gflags.h>
#include <glog/logging.h>
#include "common/libs/fs/shared_fd.h"
#include "common/libs/utils/subprocess.h"
DEFINE_uint32(port, property_get_int32("ro.boot.vsock_logcat_port", 0),
"VSOCK port to send logcat output to");
DEFINE_uint32(cid, 2, "VSOCK CID to send logcat output to");
int main(int argc, char** argv) {
gflags::ParseCommandLineFlags(&argc, &argv, true);
CHECK(FLAGS_port != 0) << "Port flag is required";
auto log_fd = cvd::SharedFD::VsockClient(FLAGS_cid, FLAGS_port, SOCK_STREAM);
if (!log_fd->IsOpen()) {
LOG(ERROR) << "Unable to connect to vsock:" << FLAGS_cid << ":"
<< FLAGS_port << ": " << log_fd->StrError();
return 1;
}
cvd::Command logcat_cmd("/system/bin/logcat");
logcat_cmd.AddParameter("-b");
logcat_cmd.AddParameter("all");
logcat_cmd.AddParameter("-v");
logcat_cmd.AddParameter("threadtime");
logcat_cmd.AddParameter("*:V");
logcat_cmd.RedirectStdIO(cvd::Subprocess::StdIOChannel::kStdOut, log_fd);
while (true) {
int wstatus;
logcat_cmd.Start().Wait(&wstatus, 0);
std::ostringstream exit_msg_builder;
exit_msg_builder << std::endl
<< "Logcat process exited with wstatus " << wstatus
<< ", restarting ..." << std::endl
<< std::endl;
auto exit_msg = exit_msg_builder.str();
size_t written = log_fd->Write(exit_msg.c_str(), exit_msg.size());
if (written != exit_msg.size()) {
LOG(ERROR) << "Unable to write complete message on socket: "
<< log_fd->StrError();
return 2;
}
}
}