133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner/*
233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * Copyright (C) 2011 The Android Open Source Project
333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * Licensed under the Apache License, Version 2.0 (the "License");
533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * you may not use this file except in compliance with the License.
633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * You may obtain a copy of the License at
733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *      http://www.apache.org/licenses/LICENSE-2.0
933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
1033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * Unless required by applicable law or agreed to in writing, software
1133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * distributed under the License is distributed on an "AS IS" BASIS,
1233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * See the License for the specific language governing permissions and
1433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * limitations under the License.
1533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner */
1633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#ifndef ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
1733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#define ANDROID_INCLUDE_HARDWARE_QEMU_PIPE_H
1833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
1933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <sys/cdefs.h>
2033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <unistd.h>
2133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <fcntl.h>
2233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <sys/mman.h>
2333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <pthread.h>  /* for pthread_once() */
2433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <stdlib.h>
2533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <stdio.h>
26360956c4b0dd1067f93b3a4ec4feec0346eec92fElliott Hughes#include <string.h>
2733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#include <errno.h>
2833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
2933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#ifndef D
3033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#  define  D(...)   do{}while(0)
3133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#endif
3233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
3333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner/* Try to open a new Qemu fast-pipe. This function returns a file descriptor
3433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * that can be used to communicate with a named service managed by the
3533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * emulator.
3633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
3733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * This file descriptor can be used as a standard pipe/socket descriptor.
3833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
3933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * 'pipeName' is the name of the emulator service you want to connect to.
4033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * E.g. 'opengles' or 'camera'.
4133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
4233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * On success, return a valid file descriptor
4333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * Returns -1 on error, and errno gives the error code, e.g.:
4433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
4533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *    EINVAL  -> unknown/unsupported pipeName
4633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *    ENOSYS  -> fast pipes not available in this system.
4733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
4833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * ENOSYS should never happen, except if you're trying to run within a
4933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * misconfigured emulator.
5033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner *
5133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * You should be able to open several pipes to the same pipe service,
5233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * except for a few special cases (e.g. GSM modem), where EBUSY will be
5333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner * returned if more than one client tries to connect to it.
5433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner */
5533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turnerstatic __inline__ int
5633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turnerqemu_pipe_open(const char*  pipeName)
5733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner{
5833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    char  buff[256];
5933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    int   buffLen;
6033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    int   fd, ret;
6133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
6233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    if (pipeName == NULL || pipeName[0] == '\0') {
6333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        errno = EINVAL;
6433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        return -1;
6533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    }
6633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
6733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    snprintf(buff, sizeof buff, "pipe:%s", pipeName);
6833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
6933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    fd = open("/dev/qemu_pipe", O_RDWR);
70d3d041b7d1fdb9b0cbe031a1ca0f4600beeeb546Octavian Purdila    if (fd < 0 && errno == ENOENT)
71d3d041b7d1fdb9b0cbe031a1ca0f4600beeeb546Octavian Purdila        fd = open("/dev/goldfish_pipe", O_RDWR);
7233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    if (fd < 0) {
7333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        D("%s: Could not open /dev/qemu_pipe: %s", __FUNCTION__, strerror(errno));
7433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        //errno = ENOSYS;
7533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        return -1;
7633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    }
7733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
7833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    buffLen = strlen(buff);
7933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
8033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    ret = TEMP_FAILURE_RETRY(write(fd, buff, buffLen+1));
8133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    if (ret != buffLen+1) {
8233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        D("%s: Could not connect to %s pipe service: %s", __FUNCTION__, pipeName, strerror(errno));
8333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        if (ret == 0) {
8433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner            errno = ECONNRESET;
8533fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        } else if (ret > 0) {
8633fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner            errno = EINVAL;
8733fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        }
8833fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner        return -1;
8933fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    }
9033fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
9133fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner    return fd;
9233fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner}
9333fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner
9433fddf0ca9801080472116654264be63a21b6e80David 'Digit' Turner#endif /* ANDROID_INCLUDE_HARDWARE_QEMUD_PIPE_H */
95