11754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato/*
21754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Copyright (C) 2016 The Android Open Source Project
31754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
41754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Licensed under the Apache License, Version 2.0 (the "License");
51754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * you may not use this file except in compliance with the License.
61754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * You may obtain a copy of the License at
71754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
81754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *      http://www.apache.org/licenses/LICENSE-2.0
91754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato *
101754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * Unless required by applicable law or agreed to in writing, software
111754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * distributed under the License is distributed on an "AS IS" BASIS,
121754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
131754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * See the License for the specific language governing permissions and
141754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato * limitations under the License.
151754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato */
164e843106a6f510a7d77fedfbeaec8e95b57905b7Yi Jin#define DEBUG false
17b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "Log.h"
181754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
191754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include "FdBuffer.h"
201754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
211754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <cutils/log.h>
221754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <utils/SystemClock.h>
231754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
241754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <fcntl.h>
251754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <poll.h>
261754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato#include <unistd.h>
270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin#include <wait.h>
281754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
296cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace android {
306cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace os {
316cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace incidentd {
326cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
33b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinconst ssize_t BUFFER_SIZE = 16 * 1024;  // 16 KB
34b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinconst ssize_t MAX_BUFFER_COUNT = 256;   // 4 MB max
351754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
361754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe OnoratoFdBuffer::FdBuffer()
37b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    : mBuffer(BUFFER_SIZE), mStartTime(-1), mFinishTime(-1), mTimedOut(false), mTruncated(false) {}
381754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
39b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinFdBuffer::~FdBuffer() {}
401754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
41e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jinstatus_t FdBuffer::read(int fd, int64_t timeout) {
42e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    struct pollfd pfds = {.fd = fd, .events = POLLIN};
431754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mStartTime = uptimeMillis();
441754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
45e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
461754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
471754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    while (true) {
48c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
49c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            mTruncated = true;
50c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            break;
511754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
52c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        if (mBuffer.writeBuffer() == NULL) return NO_MEMORY;
531754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
541754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        int64_t remainingTime = (mStartTime + timeout) - uptimeMillis();
551754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (remainingTime <= 0) {
56b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            VLOG("timed out due to long read");
571754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mTimedOut = true;
581754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            break;
591754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
601754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
611754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        int count = poll(&pfds, 1, remainingTime);
621754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        if (count == 0) {
63b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            VLOG("timed out due to block calling poll");
641754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            mTimedOut = true;
651754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            break;
661754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        } else if (count < 0) {
67b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            VLOG("poll failed: %s", strerror(errno));
681754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            return -errno;
691754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        } else {
701754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            if ((pfds.revents & POLLERR) != 0) {
71b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                VLOG("return event has error %s", strerror(errno));
721754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                return errno != 0 ? -errno : UNKNOWN_ERROR;
731754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            } else {
74e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                ssize_t amt = ::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite());
751754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                if (amt < 0) {
761754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    if (errno == EAGAIN || errno == EWOULDBLOCK) {
771754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                        continue;
781754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    } else {
79e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                        VLOG("Fail to read %d: %s", fd, strerror(errno));
801754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                        return -errno;
811754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    }
821754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                } else if (amt == 0) {
83e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                    VLOG("Reached EOF of fd=%d", fd);
841754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                    break;
851754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato                }
86c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin                mBuffer.wp()->move(amt);
871754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato            }
881754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato        }
891754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    }
901754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    mFinishTime = uptimeMillis();
911754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato    return NO_ERROR;
921754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato}
931754d744a7a34731ffc07af1bc3dbfcb06864ab0Joe Onorato
94e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jinstatus_t FdBuffer::readFully(int fd) {
95eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    mStartTime = uptimeMillis();
96eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams
97eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    while (true) {
98eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams        if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
99eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            // Don't let it get too big.
100eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            mTruncated = true;
101eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            VLOG("Truncating data");
102eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            break;
103eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams        }
104eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams        if (mBuffer.writeBuffer() == NULL) return NO_MEMORY;
105eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams
106e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ssize_t amt =
107e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                TEMP_FAILURE_RETRY(::read(fd, mBuffer.writeBuffer(), mBuffer.currentToWrite()));
108eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams        if (amt < 0) {
109e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin            VLOG("Fail to read %d: %s", fd, strerror(errno));
110eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            return -errno;
111eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams        } else if (amt == 0) {
112eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            VLOG("Done reading %zu bytes", mBuffer.size());
113eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            // We're done.
114eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams            break;
115eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams        }
116eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams        mBuffer.wp()->move(amt);
117eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    }
118eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams
119eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    mFinishTime = uptimeMillis();
120eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    return NO_ERROR;
121eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams}
122eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams
123e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jinstatus_t FdBuffer::readProcessedDataInStream(int fd, unique_fd toFd, unique_fd fromFd,
1246355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin                                             int64_t timeoutMs, const bool isSysfs) {
1250a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    struct pollfd pfds[] = {
126e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin            {.fd = fd, .events = POLLIN},
127e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin            {.fd = toFd.get(), .events = POLLOUT},
128e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin            {.fd = fromFd.get(), .events = POLLIN},
1290a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    };
1300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    mStartTime = uptimeMillis();
1320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    // mark all fds non blocking
134e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
135e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    fcntl(toFd.get(), F_SETFL, fcntl(toFd.get(), F_GETFL, 0) | O_NONBLOCK);
136e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin    fcntl(fromFd.get(), F_SETFL, fcntl(fromFd.get(), F_GETFL, 0) | O_NONBLOCK);
1370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1380a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    // A circular buffer holds data read from fd and writes to parsing process
1390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    uint8_t cirBuf[BUFFER_SIZE];
1400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    size_t cirSize = 0;
1410a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    int rpos = 0, wpos = 0;
1420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1430a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    // This is the buffer used to store processed data
1440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    while (true) {
145c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        if (mBuffer.size() >= MAX_BUFFER_COUNT * BUFFER_SIZE) {
146c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            mTruncated = true;
147c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            break;
1480a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
149c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin        if (mBuffer.writeBuffer() == NULL) return NO_MEMORY;
1500a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1510a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        int64_t remainingTime = (mStartTime + timeoutMs) - uptimeMillis();
1520a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (remainingTime <= 0) {
153b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            VLOG("timed out due to long read");
1540a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            mTimedOut = true;
1550a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            break;
1560a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1570a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1580a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // wait for any pfds to be ready to perform IO
1590a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        int count = poll(pfds, 3, remainingTime);
1600a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (count == 0) {
161b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            VLOG("timed out due to block calling poll");
1620a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            mTimedOut = true;
1630a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            break;
1640a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        } else if (count < 0) {
165b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            VLOG("Fail to poll: %s", strerror(errno));
1660a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            return -errno;
1670a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1680a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1690a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // make sure no errors occur on any fds
1700a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        for (int i = 0; i < 3; ++i) {
1710a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if ((pfds[i].revents & POLLERR) != 0) {
1720eb223496c3dee6bd0a33ea4fa664fb92ef557ccYi Jin                if (i == 0 && isSysfs) {
173e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                    VLOG("fd %d is sysfs, ignore its POLLERR return value", fd);
1740eb223496c3dee6bd0a33ea4fa664fb92ef557ccYi Jin                    continue;
1750eb223496c3dee6bd0a33ea4fa664fb92ef557ccYi Jin                }
176e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                VLOG("fd[%d]=%d returns error events: %s", i, fd, strerror(errno));
1770a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                return errno != 0 ? -errno : UNKNOWN_ERROR;
1780a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
1790a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
1800a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
1810a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // read from fd
1820a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (cirSize != BUFFER_SIZE && pfds[0].fd != -1) {
1830a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            ssize_t amt;
1840a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (rpos >= wpos) {
185e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                amt = ::read(fd, cirBuf + rpos, BUFFER_SIZE - rpos);
1860a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
187e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                amt = ::read(fd, cirBuf + rpos, wpos - rpos);
1880a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
1890a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (amt < 0) {
1900a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
191e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                    VLOG("Fail to read fd %d: %s", fd, strerror(errno));
1920a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                    return -errno;
1931a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin                }  // otherwise just continue
1941a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin            } else if (amt == 0) {
195e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                VLOG("Reached EOF of input file %d", fd);
1961a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin                pfds[0].fd = -1;  // reach EOF so don't have to poll pfds[0].
1970a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
1980a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                rpos += amt;
1990a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                cirSize += amt;
2000a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
2010a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2020a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2030a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // write to parsing process
2040a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (cirSize > 0 && pfds[1].fd != -1) {
2050a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            ssize_t amt;
2060a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (rpos > wpos) {
207e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                amt = ::write(toFd.get(), cirBuf + wpos, rpos - wpos);
2080a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
209e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin                amt = ::write(toFd.get(), cirBuf + wpos, BUFFER_SIZE - wpos);
2100a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
2110a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (amt < 0) {
2120a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
2136cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin                    VLOG("Fail to write toFd %d: %s", toFd.get(), strerror(errno));
2140a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                    return -errno;
215b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin                }  // otherwise just continue
2160a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            } else {
2170a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                wpos += amt;
2180a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                cirSize -= amt;
2190a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            }
2200a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2210a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2220a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // if buffer is empty and fd is closed, close write fd.
2230a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (cirSize == 0 && pfds[0].fd == -1 && pfds[1].fd != -1) {
224e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin            VLOG("Close write pipe %d", toFd.get());
225e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin            toFd.reset();
2260a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            pfds[1].fd = -1;
2270a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2280a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2290a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // circular buffer, reset rpos and wpos
2300a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (rpos >= BUFFER_SIZE) {
2310a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            rpos = 0;
2320a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2330a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (wpos >= BUFFER_SIZE) {
2340a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            wpos = 0;
2350a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2360a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2370a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        // read from parsing process
238e3dab2d906ee45954e58826b11cce9219c005cc5Yi Jin        ssize_t amt = ::read(fromFd.get(), mBuffer.writeBuffer(), mBuffer.currentToWrite());
2390a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        if (amt < 0) {
2400a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            if (!(errno == EAGAIN || errno == EWOULDBLOCK)) {
241ea31cbea935a20d9d290453c2ba2f8b8670e45caYi Jin                VLOG("Fail to read fromFd %d: %s", fromFd.get(), strerror(errno));
2420a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin                return -errno;
243b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            }  // otherwise just continue
2440a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        } else if (amt == 0) {
245ea31cbea935a20d9d290453c2ba2f8b8670e45caYi Jin            VLOG("Reached EOF of fromFd %d", fromFd.get());
2460a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin            break;
2470a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        } else {
248c23fad2f9079f678eae15338f5e57e2a6bf7e391Yi Jin            mBuffer.wp()->move(amt);
2490a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin        }
2500a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    }
2510a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
2520a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    mFinishTime = uptimeMillis();
2530a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin    return NO_ERROR;
2540a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin}
2550a3406fc4f8e9a8c8a9155fc7886a0496f692496Yi Jin
256b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinsize_t FdBuffer::size() const { return mBuffer.size(); }
2570f0471623e91c202fb7381a050cc331572fb439fYi Jin
258b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinEncodedBuffer::iterator FdBuffer::data() const { return mBuffer.begin(); }
2596cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
2606cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace incidentd
2616cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace os
2626cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace android
263