BitTube.cpp revision 5cae0d0699a169e468fff3e21165f35db12f2cde
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);
1005cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopian    return err == 0 ? len : -err;
101589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian}
102589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian
1035cae0d0699a169e468fff3e21165f35db12f2cdeMathias Agopianstatus_t BitTube::writeToParcel(Parcel* reply) const
104589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian{
105589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian    if (mReceiveFd < 0)
106589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian        return -EINVAL;
107589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian
108589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian    status_t result = reply->writeDupFileDescriptor(mReceiveFd);
109589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian    close(mReceiveFd);
110589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian    mReceiveFd = -1;
111589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian    return result;
112589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian}
113589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian
114589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian// ----------------------------------------------------------------------------
115589ce85ee4174829cfedce91b6b2509d2a4002ebMathias Agopian}; // namespace android
116