BitTube.cpp revision 3ad3807a5c4039618175c042a1121c926c2c62e9
1589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian/* 2589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Copyright (C) 2010 The Android Open Source Project 3589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 4589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 5589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * you may not use this file except in compliance with the License. 6589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * You may obtain a copy of the License at 7589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 8589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 9589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * 10589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * Unless required by applicable law or agreed to in writing, software 11589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 12589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * See the License for the specific language governing permissions and 14589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian * limitations under the License. 15589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian */ 16589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 17589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <stdint.h> 18589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <sys/types.h> 19589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 20589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <unistd.h> 21589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <fcntl.h> 22589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 23589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <utils/Errors.h> 24589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 25589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian#include <binder/Parcel.h> 26589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 275cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian#include <gui/BitTube.h> 28589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 29589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopiannamespace android { 30589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian// ---------------------------------------------------------------------------- 31589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 325cae0d0699a169e468fff3e21165f35db12f2cdeMathias AgopianBitTube::BitTube() 33589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian : mSendFd(-1), mReceiveFd(-1) 34589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 35589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian int fds[2]; 36589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (pipe(fds) == 0) { 37589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mReceiveFd = fds[0]; 38589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mSendFd = fds[1]; 39589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); 40589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian fcntl(mSendFd, F_SETFL, O_NONBLOCK); 415cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } else { 425cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian mReceiveFd = -errno; 435cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian LOGE("BitTube: pipe creation failed (%s)", strerror(-mReceiveFd)); 44589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian } 45589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 46589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 475cae0d0699a169e468fff3e21165f35db12f2cdeMathias AgopianBitTube::BitTube(const Parcel& data) 48589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian : mSendFd(-1), mReceiveFd(-1) 49589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 50589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mReceiveFd = dup(data.readFileDescriptor()); 515cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian if (mReceiveFd >= 0) { 525cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian fcntl(mReceiveFd, F_SETFL, O_NONBLOCK); 535cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } else { 545cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian mReceiveFd = -errno; 555cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian LOGE("BitTube(Parcel): can't dup filedescriptor (%s)", 565cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian strerror(-mReceiveFd)); 575cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } 58589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 59589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 605cae0d0699a169e468fff3e21165f35db12f2cdeMathias AgopianBitTube::~BitTube() 61589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 62589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (mSendFd >= 0) 63589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian close(mSendFd); 64589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 65589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (mReceiveFd >= 0) 66589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian close(mReceiveFd); 67589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 68589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 695cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopianstatus_t BitTube::initCheck() const 705cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian{ 715cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian if (mReceiveFd < 0) { 725cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian return status_t(mReceiveFd); 735cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } 745cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian return NO_ERROR; 755cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian} 765cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian 775cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopianint BitTube::getFd() const 78589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 79589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return mReceiveFd; 80589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 81589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 825cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopianssize_t BitTube::write(void const* vaddr, size_t size) 83589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 845cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian ssize_t err, len; 855cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian do { 865cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian len = ::write(mSendFd, vaddr, size); 875cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian err = len < 0 ? errno : 0; 885cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } while (err == EINTR); 895cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian return err == 0 ? len : -err; 905cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian 91589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 92589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 935cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopianssize_t BitTube::read(void* vaddr, size_t size) 94589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 955cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian ssize_t err, len; 965cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian do { 975cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian len = ::read(mReceiveFd, vaddr, size); 985cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian err = len < 0 ? errno : 0; 995cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian } while (err == EINTR); 1003ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian if (err == EAGAIN || err == EWOULDBLOCK) { 1013ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian // EAGAIN means that we have non-blocking I/O but there was 1023ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian // no data to be read. Nothing the client should care about. 1033ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian return 0; 1043ad3807a5c4039618175c042a1121c926c2c62e9Mathias Agopian } 1055cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian return err == 0 ? len : -err; 106589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 107589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 1085cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopianstatus_t BitTube::writeToParcel(Parcel* reply) const 109589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{ 110589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian if (mReceiveFd < 0) 111589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return -EINVAL; 112589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 113589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian status_t result = reply->writeDupFileDescriptor(mReceiveFd); 114589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian close(mReceiveFd); 115589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian mReceiveFd = -1; 116589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian return result; 117589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian} 118589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian 119589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian// ---------------------------------------------------------------------------- 120589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian}; // namespace android 121