aboutsummaryrefslogtreecommitdiffstats
path: root/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp')
-rw-r--r--emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp190
1 files changed, 190 insertions, 0 deletions
diff --git a/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
new file mode 100644
index 0000000..50c3d8b
--- /dev/null
+++ b/emulator/opengl/system/OpenglSystemCommon/QemuPipeStream.cpp
@@ -0,0 +1,190 @@
+/*
+* Copyright (C) 2011 The Android Open Source Project
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+#include "QemuPipeStream.h"
+#include <hardware/qemu_pipe.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+QemuPipeStream::QemuPipeStream(size_t bufSize) :
+ IOStream(bufSize),
+ m_sock(-1),
+ m_bufsize(bufSize),
+ m_buf(NULL)
+{
+}
+
+QemuPipeStream::QemuPipeStream(int sock, size_t bufSize) :
+ IOStream(bufSize),
+ m_sock(sock),
+ m_bufsize(bufSize),
+ m_buf(NULL)
+{
+}
+
+QemuPipeStream::~QemuPipeStream()
+{
+ if (m_sock >= 0) {
+ ::close(m_sock);
+ }
+ if (m_buf != NULL) {
+ free(m_buf);
+ }
+}
+
+
+int QemuPipeStream::connect(void)
+{
+ m_sock = qemu_pipe_open("opengles");
+ if (!valid()) return -1;
+ return 0;
+}
+
+void *QemuPipeStream::allocBuffer(size_t minSize)
+{
+ size_t allocSize = (m_bufsize < minSize ? minSize : m_bufsize);
+ if (!m_buf) {
+ m_buf = (unsigned char *)malloc(allocSize);
+ }
+ else if (m_bufsize < allocSize) {
+ unsigned char *p = (unsigned char *)realloc(m_buf, allocSize);
+ if (p != NULL) {
+ m_buf = p;
+ m_bufsize = allocSize;
+ } else {
+ ERR("realloc (%d) failed\n", allocSize);
+ free(m_buf);
+ m_buf = NULL;
+ m_bufsize = 0;
+ }
+ }
+
+ return m_buf;
+};
+
+int QemuPipeStream::commitBuffer(size_t size)
+{
+ return writeFully(m_buf, size);
+}
+
+int QemuPipeStream::writeFully(const void *buf, size_t len)
+{
+ //DBG(">> QemuPipeStream::writeFully %d\n", len);
+ if (!valid()) return -1;
+
+ size_t res = len;
+ int retval = 0;
+
+ while (res > 0) {
+ ssize_t stat = ::write(m_sock, (const char *)(buf) + (len - res), res);
+ if (stat > 0) {
+ res -= stat;
+ continue;
+ }
+ if (stat == 0) { /* EOF */
+ ERR("QemuPipeStream::writeFully failed: premature EOF\n");
+ retval = -1;
+ break;
+ }
+ if (errno == EINTR) {
+ continue;
+ }
+ retval = stat;
+ ERR("QemuPipeStream::writeFully failed: %s\n", strerror(errno));
+ break;
+ }
+ //DBG("<< QemuPipeStream::writeFully %d\n", len );
+ return retval;
+}
+
+const unsigned char *QemuPipeStream::readFully(void *buf, size_t len)
+{
+ //DBG(">> QemuPipeStream::readFully %d\n", len);
+ if (!valid()) return NULL;
+ if (!buf) {
+ if (len>0) ERR("QemuPipeStream::readFully failed, buf=NULL, len %d", len);
+ return NULL; // do not allow NULL buf in that implementation
+ }
+ size_t res = len;
+ while (res > 0) {
+ ssize_t stat = ::read(m_sock, (char *)(buf) + len - res, len);
+ if (stat == 0) {
+ // client shutdown;
+ return NULL;
+ } else if (stat < 0) {
+ if (errno == EINTR) {
+ continue;
+ } else {
+ ERR("QemuPipeStream::readFully failed (buf %p): %s\n",
+ buf, strerror(errno));
+ return NULL;
+ }
+ } else {
+ res -= stat;
+ }
+ }
+ //DBG("<< QemuPipeStream::readFully %d\n", len);
+ return (const unsigned char *)buf;
+}
+
+const unsigned char *QemuPipeStream::read( void *buf, size_t *inout_len)
+{
+ //DBG(">> QemuPipeStream::read %d\n", *inout_len);
+ if (!valid()) return NULL;
+ if (!buf) {
+ ERR("QemuPipeStream::read failed, buf=NULL");
+ return NULL; // do not allow NULL buf in that implementation
+ }
+
+ int n = recv(buf, *inout_len);
+
+ if (n > 0) {
+ *inout_len = n;
+ return (const unsigned char *)buf;
+ }
+
+ //DBG("<< QemuPipeStream::read %d\n", *inout_len);
+ return NULL;
+}
+
+int QemuPipeStream::recv(void *buf, size_t len)
+{
+ if (!valid()) return int(ERR_INVALID_SOCKET);
+ char* p = (char *)buf;
+ int ret = 0;
+ while(len > 0) {
+ int res = ::read(m_sock, p, len);
+ if (res > 0) {
+ p += res;
+ ret += res;
+ len -= res;
+ continue;
+ }
+ if (res == 0) { /* EOF */
+ break;
+ }
+ if (errno == EINTR)
+ continue;
+
+ /* A real error */
+ if (ret == 0)
+ ret = -1;
+ break;
+ }
+ return ret;
+}