10175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn/*
20175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Copyright (C) 2012-2014 The Android Open Source Project
30175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn *
40175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License");
50175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * you may not use this file except in compliance with the License.
60175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * You may obtain a copy of the License at
70175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn *
80175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn *      http://www.apache.org/licenses/LICENSE-2.0
90175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn *
100175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * Unless required by applicable law or agreed to in writing, software
110175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS,
120175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * See the License for the specific language governing permissions and
140175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn * limitations under the License.
150175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn */
160175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
1721fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn#include <ctype.h>
18ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn#include <endian.h>
1921fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn#include <fcntl.h>
200175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <stdio.h>
210175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <string.h>
220175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <time.h>
230175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include <unistd.h>
240175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
25ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn#include <private/android_logger.h>
260175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
272ad0bd0a9b594bbe2560b405b0008b7bc742cfcaMark Salyzyn#include "LogBuffer.h"
280175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "LogBufferElement.h"
29ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn#include "LogCommand.h"
300175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn#include "LogReader.h"
312ad0bd0a9b594bbe2560b405b0008b7bc742cfcaMark Salyzyn#include "LogUtils.h"
320175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
335a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzynconst log_time LogBufferElement::FLUSH_ERROR((uint32_t)-1, (uint32_t)-1);
34ee49c6a670a54e0636f81f39ddc93c87c9a4d766Mark Salyzynatomic_int_fast64_t LogBufferElement::sequence(1);
350175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
367e2f83c0bcc3ad8a2840a48be14d302ed79d671cMark SalyzynLogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime,
37b992d0d7d34bed62fd16151a68d60d58cc8003efMark Salyzyn                                   uid_t uid, pid_t pid, pid_t tid,
38501c373916e292764400dbae735f44b33378400fMark Salyzyn                                   const char* msg, unsigned short len)
39501c373916e292764400dbae735f44b33378400fMark Salyzyn    : mUid(uid),
40501c373916e292764400dbae735f44b33378400fMark Salyzyn      mPid(pid),
41501c373916e292764400dbae735f44b33378400fMark Salyzyn      mTid(tid),
42501c373916e292764400dbae735f44b33378400fMark Salyzyn      mRealTime(realtime),
43501c373916e292764400dbae735f44b33378400fMark Salyzyn      mMsgLen(len),
44501c373916e292764400dbae735f44b33378400fMark Salyzyn      mLogId(log_id) {
450175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    mMsg = new char[len];
460175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    memcpy(mMsg, msg, len);
47501c373916e292764400dbae735f44b33378400fMark Salyzyn    mTag = (isBinary() && (mMsgLen >= sizeof(uint32_t)))
48501c373916e292764400dbae735f44b33378400fMark Salyzyn               ? le32toh(reinterpret_cast<android_event_header_t*>(mMsg)->tag)
49501c373916e292764400dbae735f44b33378400fMark Salyzyn               : 0;
500175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn}
510175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
52501c373916e292764400dbae735f44b33378400fMark SalyzynLogBufferElement::LogBufferElement(const LogBufferElement& elem)
53501c373916e292764400dbae735f44b33378400fMark Salyzyn    : mTag(elem.mTag),
54501c373916e292764400dbae735f44b33378400fMark Salyzyn      mUid(elem.mUid),
55501c373916e292764400dbae735f44b33378400fMark Salyzyn      mPid(elem.mPid),
56501c373916e292764400dbae735f44b33378400fMark Salyzyn      mTid(elem.mTid),
57501c373916e292764400dbae735f44b33378400fMark Salyzyn      mRealTime(elem.mRealTime),
58501c373916e292764400dbae735f44b33378400fMark Salyzyn      mMsgLen(elem.mMsgLen),
59501c373916e292764400dbae735f44b33378400fMark Salyzyn      mLogId(elem.mLogId) {
60a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn    mMsg = new char[mMsgLen];
61a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn    memcpy(mMsg, elem.mMsg, mMsgLen);
62a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn}
63a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn
640175b0747a1f55329109e84c9a1322dcb95e2848Mark SalyzynLogBufferElement::~LogBufferElement() {
65501c373916e292764400dbae735f44b33378400fMark Salyzyn    delete[] mMsg;
660175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn}
670175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
6821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn// caller must own and free character string
69501c373916e292764400dbae735f44b33378400fMark Salyzynchar* android::tidToName(pid_t tid) {
70501c373916e292764400dbae735f44b33378400fMark Salyzyn    char* retval = NULL;
7121fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    char buffer[256];
7221fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    snprintf(buffer, sizeof(buffer), "/proc/%u/comm", tid);
7321fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    int fd = open(buffer, O_RDONLY);
7421fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    if (fd >= 0) {
7521fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        ssize_t ret = read(fd, buffer, sizeof(buffer));
7621fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        if (ret >= (ssize_t)sizeof(buffer)) {
7721fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn            ret = sizeof(buffer) - 1;
7821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        }
7921fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        while ((ret > 0) && isspace(buffer[ret - 1])) {
8021fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn            --ret;
8121fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        }
8221fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        if (ret > 0) {
8321fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn            buffer[ret] = '\0';
8421fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn            retval = strdup(buffer);
8521fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        }
8621fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        close(fd);
8721fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    }
8821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn
8921fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    // if nothing for comm, check out cmdline
90501c373916e292764400dbae735f44b33378400fMark Salyzyn    char* name = android::pidToName(tid);
9121fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    if (!retval) {
9221fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        retval = name;
9321fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        name = NULL;
9421fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    }
9521fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn
9621fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    // check if comm is truncated, see if cmdline has full representation
9721fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    if (name) {
9821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        // impossible for retval to be NULL if name not NULL
9921fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        size_t retval_len = strlen(retval);
10021fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        size_t name_len = strlen(name);
10121fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        // KISS: ToDo: Only checks prefix truncated, not suffix, or both
102501c373916e292764400dbae735f44b33378400fMark Salyzyn        if ((retval_len < name_len) &&
103501c373916e292764400dbae735f44b33378400fMark Salyzyn            !fastcmp<strcmp>(retval, name + name_len - retval_len)) {
10421fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn            free(retval);
10521fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn            retval = name;
10621fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        } else {
10721fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn            free(name);
10821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        }
10921fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    }
11021fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    return retval;
11121fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn}
11221fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn
113ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn// assumption: mMsg == NULL
114501c373916e292764400dbae735f44b33378400fMark Salyzynsize_t LogBufferElement::populateDroppedMessage(char*& buffer, LogBuffer* parent,
115501c373916e292764400dbae735f44b33378400fMark Salyzyn                                                bool lastSame) {
116047cc0729fd837a03b99db901941c1421ef15f96Mark Salyzyn    static const char tag[] = "chatty";
117ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
118501c373916e292764400dbae735f44b33378400fMark Salyzyn    if (!__android_log_is_loggable_len(ANDROID_LOG_INFO, tag, strlen(tag),
119807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn                                       ANDROID_LOG_VERBOSE)) {
120e59c469fa89d438d2d7150b7d8cd6b401900709bMark Salyzyn        return 0;
121e59c469fa89d438d2d7150b7d8cd6b401900709bMark Salyzyn    }
122e59c469fa89d438d2d7150b7d8cd6b401900709bMark Salyzyn
123b5b879678522882e6dbb02511379518d2b7b545dMark Salyzyn    static const char format_uid[] = "uid=%u%s%s %s %u line%s";
124ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn    parent->lock();
125501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* name = parent->uidToName(mUid);
126ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn    parent->unlock();
127501c373916e292764400dbae735f44b33378400fMark Salyzyn    const char* commName = android::tidToName(mTid);
12821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    if (!commName && (mTid != mPid)) {
12917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        commName = android::tidToName(mPid);
13021fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    }
13121fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    if (!commName) {
132ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn        parent->lock();
13321fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        commName = parent->pidToName(mPid);
134ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn        parent->unlock();
13521fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    }
136ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn    if (name && name[0] && commName && (name[0] == commName[0])) {
137ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn        size_t len = strlen(name + 1);
138ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn        if (!strncmp(name + 1, commName + 1, len)) {
139ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn            if (commName[len + 1] == '\0') {
140501c373916e292764400dbae735f44b33378400fMark Salyzyn                free(const_cast<char*>(commName));
141ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn                commName = NULL;
142ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn            } else {
143501c373916e292764400dbae735f44b33378400fMark Salyzyn                free(const_cast<char*>(name));
144ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn                name = NULL;
145ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn            }
146047cc0729fd837a03b99db901941c1421ef15f96Mark Salyzyn        }
14721fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    }
14821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    if (name) {
149501c373916e292764400dbae735f44b33378400fMark Salyzyn        char* buf = NULL;
150758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        asprintf(&buf, "(%s)", name);
151758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (buf) {
152501c373916e292764400dbae735f44b33378400fMark Salyzyn            free(const_cast<char*>(name));
153758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = buf;
15421fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        }
15521fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    }
15621fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    if (commName) {
157501c373916e292764400dbae735f44b33378400fMark Salyzyn        char* buf = NULL;
158758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        asprintf(&buf, " %s", commName);
159758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (buf) {
160501c373916e292764400dbae735f44b33378400fMark Salyzyn            free(const_cast<char*>(commName));
161758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            commName = buf;
16221fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn        }
163ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
16421fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    // identical to below to calculate the buffer size required
165b5b879678522882e6dbb02511379518d2b7b545dMark Salyzyn    const char* type = lastSame ? "identical" : "expire";
166ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn    size_t len = snprintf(NULL, 0, format_uid, mUid, name ? name : "",
167501c373916e292764400dbae735f44b33378400fMark Salyzyn                          commName ? commName : "", type, mDropped,
168501c373916e292764400dbae735f44b33378400fMark Salyzyn                          (mDropped > 1) ? "s" : "");
169ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
170ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    size_t hdrLen;
17160636fa872382a8cde0440b72cdfc9032b5fa7d0Mark Salyzyn    if (isBinary()) {
172ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        hdrLen = sizeof(android_log_event_string_t);
173ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    } else {
174ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        hdrLen = 1 + sizeof(tag);
175ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
176ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
177501c373916e292764400dbae735f44b33378400fMark Salyzyn    buffer = static_cast<char*>(calloc(1, hdrLen + len + 1));
178ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (!buffer) {
179501c373916e292764400dbae735f44b33378400fMark Salyzyn        free(const_cast<char*>(name));
180501c373916e292764400dbae735f44b33378400fMark Salyzyn        free(const_cast<char*>(commName));
181ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        return 0;
182ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
183ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
184ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    size_t retval = hdrLen + len;
18560636fa872382a8cde0440b72cdfc9032b5fa7d0Mark Salyzyn    if (isBinary()) {
186501c373916e292764400dbae735f44b33378400fMark Salyzyn        android_log_event_string_t* event =
187501c373916e292764400dbae735f44b33378400fMark Salyzyn            reinterpret_cast<android_log_event_string_t*>(buffer);
188ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
18947684ca59147a3f5de71bf4f2fe6a647bdc6c60eMark Salyzyn        event->header.tag = htole32(CHATTY_LOG_TAG);
190758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        event->type = EVENT_TYPE_STRING;
191758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        event->length = htole32(len);
192ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    } else {
193ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        ++retval;
194ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        buffer[0] = ANDROID_LOG_INFO;
195ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        strcpy(buffer + 1, tag);
196ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
197ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
19821fb7e0b753b2251369bfaa1c6f6a09e58e64437Mark Salyzyn    snprintf(buffer + hdrLen, len + 1, format_uid, mUid, name ? name : "",
199501c373916e292764400dbae735f44b33378400fMark Salyzyn             commName ? commName : "", type, mDropped,
200501c373916e292764400dbae735f44b33378400fMark Salyzyn             (mDropped > 1) ? "s" : "");
201501c373916e292764400dbae735f44b33378400fMark Salyzyn    free(const_cast<char*>(name));
202501c373916e292764400dbae735f44b33378400fMark Salyzyn    free(const_cast<char*>(commName));
203ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
204ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    return retval;
205ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn}
206ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
2075a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzynlog_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent,
208b5b879678522882e6dbb02511379518d2b7b545dMark Salyzyn                                   bool privileged, bool lastSame) {
2097b87365ecf8c08307173537645b85708f59aab78Mark Salyzyn    struct logger_entry_v4 entry;
210ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
2117b87365ecf8c08307173537645b85708f59aab78Mark Salyzyn    memset(&entry, 0, sizeof(struct logger_entry_v4));
212ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
213501c373916e292764400dbae735f44b33378400fMark Salyzyn    entry.hdr_size = privileged ? sizeof(struct logger_entry_v4)
214501c373916e292764400dbae735f44b33378400fMark Salyzyn                                : sizeof(struct logger_entry_v3);
2150175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    entry.lid = mLogId;
2160175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    entry.pid = mPid;
217b992d0d7d34bed62fd16151a68d60d58cc8003efMark Salyzyn    entry.tid = mTid;
2187b87365ecf8c08307173537645b85708f59aab78Mark Salyzyn    entry.uid = mUid;
2190175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    entry.sec = mRealTime.tv_sec;
2200175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    entry.nsec = mRealTime.tv_nsec;
2210175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
2220175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    struct iovec iovec[2];
2230175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn    iovec[0].iov_base = &entry;
2247b87365ecf8c08307173537645b85708f59aab78Mark Salyzyn    iovec[0].iov_len = entry.hdr_size;
225ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
226501c373916e292764400dbae735f44b33378400fMark Salyzyn    char* buffer = NULL;
227ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
228ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    if (!mMsg) {
229b5b879678522882e6dbb02511379518d2b7b545dMark Salyzyn        entry.len = populateDroppedMessage(buffer, parent, lastSame);
2305a34d6ea43d28f3b5d27bf6dd5b9fa31ec033531Mark Salyzyn        if (!entry.len) return mRealTime;
231ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        iovec[1].iov_base = buffer;
232ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    } else {
233ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        entry.len = mMsgLen;
234ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn        iovec[1].iov_base = mMsg;
235ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    }
236ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    iovec[1].iov_len = entry.len;
237ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
238dd609d810b5d60adeb885d37f820fa2a526eef71Mark Salyzyn    log_time retval = reader->sendDatav(iovec, 1 + (entry.len != 0))
239dd609d810b5d60adeb885d37f820fa2a526eef71Mark Salyzyn                          ? FLUSH_ERROR
240dd609d810b5d60adeb885d37f820fa2a526eef71Mark Salyzyn                          : mRealTime;
241ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
242501c373916e292764400dbae735f44b33378400fMark Salyzyn    if (buffer) free(buffer);
2430175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn
244ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    return retval;
2450175b0747a1f55329109e84c9a1322dcb95e2848Mark Salyzyn}
246