1cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert/* 2cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Copyright (C) 2015 The Android Open Source Project 3cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * 4cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Licensed under the Apache License, Version 2.0 (the "License"); 5cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * you may not use this file except in compliance with the License. 6cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * You may obtain a copy of the License at 7cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * 8cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * http://www.apache.org/licenses/LICENSE-2.0 9cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * 10cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * Unless required by applicable law or agreed to in writing, software 11cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * distributed under the License is distributed on an "AS IS" BASIS, 12cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * See the License for the specific language governing permissions and 14cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert * limitations under the License. 15cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert */ 16cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 173313426fad9eaaf53017cdbde889ebcec91358ecDan Albert#define TRACE_TAG TRACE_RWX 18cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 19cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_io.h" 20cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 21cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include <unistd.h> 22cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 23e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes#include <base/stringprintf.h> 24e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes 25cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert#include "adb_trace.h" 2692af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes#include "adb_utils.h" 27e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes#include "sysdeps.h" 2892af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes 2992af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool SendProtocolString(int fd, const std::string& s) { 3092af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes int length = s.size(); 3192af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes if (length > 0xffff) { 3292af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes length = 0xffff; 3392af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes } 3492af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes 35e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes return WriteFdFmt(fd, "%04x", length) && WriteFdExactly(fd, s); 3692af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes} 3792af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes 3892af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool SendOkay(int fd) { 3992af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes return WriteFdExactly(fd, "OKAY", 4); 4092af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes} 4192af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes 4292af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool SendFail(int fd, const std::string& reason) { 4392af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes return WriteFdExactly(fd, "FAIL", 4) && SendProtocolString(fd, reason); 4492af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes} 45cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 46cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albertbool ReadFdExactly(int fd, void* buf, size_t len) { 47cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert char* p = reinterpret_cast<char*>(buf); 48cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 49cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert size_t len0 = len; 50cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 51cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert D("readx: fd=%d wanted=%zu\n", fd, len); 52cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert while (len > 0) { 53bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert int r = adb_read(fd, p, len); 54cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert if (r > 0) { 55cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert len -= r; 56cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert p += r; 57cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } else if (r == -1) { 58cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert D("readx: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 59cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert return false; 60cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } else { 61cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert D("readx: fd=%d disconnected\n", fd); 62cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert errno = 0; 63cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert return false; 64cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } 65cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } 66cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 67cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert D("readx: fd=%d wanted=%zu got=%zu\n", fd, len0, len0 - len); 68cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert if (ADB_TRACING) { 69cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert dump_hex(reinterpret_cast<const unsigned char*>(buf), len0); 70cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } 71cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 72cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert return true; 73cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert} 74cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 75cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albertbool WriteFdExactly(int fd, const void* buf, size_t len) { 76cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert const char* p = reinterpret_cast<const char*>(buf); 77cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert int r; 78cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 79cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert D("writex: fd=%d len=%d: ", fd, (int)len); 80cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert if (ADB_TRACING) { 81cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert dump_hex(reinterpret_cast<const unsigned char*>(buf), len); 82cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } 83cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 84cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert while (len > 0) { 85bac3474a8256cb32a29e8d46f78cad95a5502692Dan Albert r = adb_write(fd, p, len); 86cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert if (r == -1) { 87cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert D("writex: fd=%d error %d: %s\n", fd, errno, strerror(errno)); 88cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert if (errno == EAGAIN) { 89cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert adb_sleep_ms(1); // just yield some cpu time 90cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert continue; 91cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } else if (errno == EPIPE) { 92cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert D("writex: fd=%d disconnected\n", fd); 93cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert errno = 0; 94cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert return false; 9508f66bc771ac798d89451a9b68a1c6722352d683Dan Albert } else { 9608f66bc771ac798d89451a9b68a1c6722352d683Dan Albert return false; 97cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } 98cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } else { 99cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert len -= r; 100cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert p += r; 101cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } 102cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert } 103cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert return true; 104cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert} 105cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert 10692af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool WriteFdExactly(int fd, const char* str) { 10792af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes return WriteFdExactly(fd, str, strlen(str)); 10892af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes} 10992af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes 11092af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughesbool WriteFdExactly(int fd, const std::string& str) { 11192af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes return WriteFdExactly(fd, str.c_str(), str.size()); 11292af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes} 11392af733ee202caa3b5475fe27fcc81582f11e7c8Elliott Hughes 114e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughesbool WriteFdFmt(int fd, const char* fmt, ...) { 115e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes std::string str; 116e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes 117e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes va_list ap; 118e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes va_start(ap, fmt); 119e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes android::base::StringAppendV(&str, fmt, ap); 120e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes va_end(ap); 121e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes 122e1a55004e9fa46055c59f86e952e9e457c36c3f2Elliott Hughes return WriteFdExactly(fd, str); 123cc731cc76786b6bdc58764aad9924c0d0c8d645fDan Albert} 124