1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License. 6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at 7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and 14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License. 15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Thread that reads from stdout/stderr and converts them to log messages. 18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * (Sort of a hack.) 19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h" 21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h> 23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <unistd.h> 24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <fcntl.h> 25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <errno.h> 26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFilenoStdout 1 28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFilenoStderr 2 29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kMaxLine 512 31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Hold some data. 34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 35d862faa2ceae186da5518607505eb942d634ced9Carl Shapirostruct BufferedData { 36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char buf[kMaxLine+1]; 37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int count; 38d862faa2ceae186da5518607505eb942d634ced9Carl Shapiro}; 39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project// fwd 41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* stdioConverterThreadStart(void* arg); 42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool readAndLog(int fd, BufferedData* data, const char* tag); 43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Crank up the stdout/stderr converter thread. 47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns immediately. 49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 501e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmStdioConverterStartup() 51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.haltStdioConverter = false; 53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmInitMutex(&gDvm.stdioConverterLock); 55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pthread_cond_init(&gDvm.stdioConverterCond, NULL); 56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 570c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro if (pipe(gDvm.stdoutPipe) != 0) { 58e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("pipe failed: %s", strerror(errno)); 59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 610c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro if (pipe(gDvm.stderrPipe) != 0) { 62e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("pipe failed: %s", strerror(errno)); 63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 660c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro if (dup2(gDvm.stdoutPipe[1], kFilenoStdout) != kFilenoStdout) { 67e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("dup2(1) failed: %s", strerror(errno)); 68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 700c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro close(gDvm.stdoutPipe[1]); 710c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro gDvm.stdoutPipe[1] = -1; 72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#ifdef HAVE_ANDROID_OS 73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* don't redirect stderr on sim -- logs get written there! */ 74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* (don't need this on the sim anyway) */ 750c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro if (dup2(gDvm.stderrPipe[1], kFilenoStderr) != kFilenoStderr) { 76e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("dup2(2) failed: %d %s", errno, strerror(errno)); 77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 790c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro close(gDvm.stderrPipe[1]); 800c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro gDvm.stderrPipe[1] = -1; 81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#endif 82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create the thread. 86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockMutex(&gDvm.stdioConverterLock); 88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (!dvmCreateInternalThread(&gDvm.stdioConverterHandle, 900c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro "Stdio Converter", 910c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro stdioConverterThreadStart, 920c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro NULL)) { 93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (!gDvm.stdioConverterReady) { 97b31b30131bbf58280a515c40027aa958b81b5cd6Carl Shapiro dvmWaitCond(&gDvm.stdioConverterCond, &gDvm.stdioConverterLock); 98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockMutex(&gDvm.stdioConverterLock); 100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Shut down the stdio converter thread if it was started. 106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since we know the thread is just sitting around waiting for something 108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to arrive on stdout, print something. 109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1101e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmStdioConverterShutdown() 111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.haltStdioConverter = true; 113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (gDvm.stdioConverterHandle == 0) // not started, or still starting 114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return; 115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* print something to wake it up */ 117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project printf("Shutting down\n"); 118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fflush(stdout); 119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 120062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("Joining stdio converter..."); 121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project pthread_join(gDvm.stdioConverterHandle, NULL); 122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Select on stdout/stderr pipes, waiting for activity. 126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * DO NOT use printf from here. 128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* stdioConverterThreadStart(void* arg) 130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int cc; 132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* tell the main thread that we're ready */ 134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmLockMutex(&gDvm.stdioConverterLock); 135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project gDvm.stdioConverterReady = true; 136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project cc = pthread_cond_signal(&gDvm.stdioConverterCond); 137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(cc == 0); 138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmUnlockMutex(&gDvm.stdioConverterLock); 139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* we never do anything that affects the rest of the VM */ 141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmChangeStatus(NULL, THREAD_VMWAIT); 142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocate read buffers. 145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 1460c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro BufferedData* stdoutData = new BufferedData; 1470c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro BufferedData* stderrData = new BufferedData; 148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project stdoutData->count = stderrData->count = 0; 149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Read until shutdown time. 152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project while (!gDvm.haltStdioConverter) { 154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fd_set readfds; 155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int maxFd, fdCount; 156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project FD_ZERO(&readfds); 1580c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro FD_SET(gDvm.stdoutPipe[0], &readfds); 1590c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro FD_SET(gDvm.stderrPipe[0], &readfds); 1600c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro maxFd = MAX(gDvm.stdoutPipe[0], gDvm.stderrPipe[0]); 161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project fdCount = select(maxFd+1, &readfds, NULL, NULL, NULL); 163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (fdCount < 0) { 165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (errno != EINTR) { 166c1a4ab9c313d8a3d12007f2dbef7b5a6fa4ac2efSteve Block ALOGE("select on stdout/stderr failed"); 167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 169062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("Got EINTR, ignoring"); 170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else if (fdCount == 0) { 171062bf509a77fce9dfcb7e7b2e401cf2a124d83d5Steve Block ALOGD("WEIRD: select returned zero"); 172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project bool err = false; 1740c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro if (FD_ISSET(gDvm.stdoutPipe[0], &readfds)) { 1750c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro err |= !readAndLog(gDvm.stdoutPipe[0], stdoutData, 176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "stdout"); 177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 1780c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro if (FD_ISSET(gDvm.stderrPipe[0], &readfds)) { 1790c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro err |= !readAndLog(gDvm.stderrPipe[0], stderrData, 180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project "stderr"); 181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* probably EOF; give up */ 184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (err) { 185e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("stdio converter got read error; shutting it down"); 186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project break; 187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1910c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro close(gDvm.stdoutPipe[0]); 1920c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro close(gDvm.stderrPipe[0]); 193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 1940c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro delete stdoutData; 1950c32ebc544b8dd1528dc007090abda0be5f31174Carl Shapiro delete stderrData; 196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* change back for shutdown sequence */ 198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project dvmChangeStatus(NULL, THREAD_RUNNING); 199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return NULL; 200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* 203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Data is pending on "fd". Read as much as will fit in "data", then 204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * write out any full lines and compact "data". 205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool readAndLog(int fd, BufferedData* data, const char* tag) 207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{ 208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project ssize_t actual; 209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project size_t want; 210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project assert(data->count < kMaxLine); 212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project want = kMaxLine - data->count; 214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project actual = read(fd, data->buf + data->count, want); 215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (actual <= 0) { 216e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block ALOGW("read %s: (%d,%d) failed (%d): %s", 217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project tag, fd, want, (int)actual, strerror(errno)); 218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return false; 219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 2204308417beec548c2b2c06ecec4f7f4a965b09fb2Steve Block //ALOGI("read %s: %d at %d", tag, actual, data->count); 221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data->count += actual; 223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Got more data, look for an EOL. We expect LF or CRLF, but will 226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * try to handle a standalone CR. 227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project char* cp = data->buf; 229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project const char* start = data->buf; 230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int i = data->count; 231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project for (i = data->count; i > 0; i--, cp++) { 232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (*cp == '\n' || (*cp == '\r' && i != 0 && *(cp+1) != '\n')) { 233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *cp = '\0'; 234e8e1ddccd616e8226b7cc1e4e9fdb327429249e8Steve Block //ALOGW("GOT %d at %d '%s'", cp - start, start - data->buf, start); 2351663a6c12fdf4732d7ea0a0406af6085b3c408e4Steve Block ALOG(LOG_INFO, tag, "%s", start); 236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = cp+1; 237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See if we overflowed. If so, cut it off. 242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (start == data->buf && data->count == kMaxLine) { 244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data->buf[kMaxLine] = '\0'; 2451663a6c12fdf4732d7ea0a0406af6085b3c408e4Steve Block ALOG(LOG_INFO, tag, "%s!", start); 246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project start = cp + kMaxLine; 247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* 250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Update "data" if we consumed some output. If there's anything left 251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * in the buffer, it's because we didn't see an EOL and need to keep 252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * reading until we see one. 253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */ 254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (start != data->buf) { 255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project if (start >= data->buf + data->count) { 256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* consumed all available */ 257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data->count = 0; 258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } else { 259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project /* some left over */ 260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project int remaining = data->count - (start - data->buf); 261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project memmove(data->buf, start, remaining); 262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project data->count = remaining; 263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project } 265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project 266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project return true; 267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} 268