1e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner/* 2e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * Copyright (C) 2011 The Android Open Source Project 3e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * 4e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * Licensed under the Apache License, Version 2.0 (the "License"); 5e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * you may not use this file except in compliance with the License. 6e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * You may obtain a copy of the License at 7e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * 8e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * http://www.apache.org/licenses/LICENSE-2.0 9e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * 10e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * Unless required by applicable law or agreed to in writing, software 11e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * distributed under the License is distributed on an "AS IS" BASIS, 12e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * See the License for the specific language governing permissions and 14e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner * limitations under the License. 15e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner */ 16e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 17e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <sys/socket.h> 18e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <netinet/in.h> 19e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <errno.h> 20e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <string.h> 21e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <unistd.h> 22e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <stddef.h> 23e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <stdio.h> 24e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include "test_util.h" 25e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 26e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#ifdef __linux__ 27e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <time.h> 28e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerdouble now_secs(void) 29e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner{ 30e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner struct timespec tm; 31e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner clock_gettime(CLOCK_MONOTONIC, &tm); 32e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return (double)tm.tv_sec + (double)tm.tv_nsec/1e9; 33e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner} 34e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#else 35e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#include <sys/time.h> 36e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerdouble now_secs(void) 37e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner{ 38e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner struct timeval tv; 39e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner gettimeofday(&tv, NULL); 40e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return tv.sec + (double)tv.usec/1e6; 41e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner} 42e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner#endif 43e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 44e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerint 45e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerpipe_openSocket( Pipe* pipe, int port ) 46e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner{ 47e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner static int fd; 48e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner struct sockaddr_in addr; 49e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 50e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner pipe->socket = -1; 51e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 52e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fd = socket( AF_INET, SOCK_STREAM, 0 ); 53e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (fd < 0) { 54e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fprintf(stderr, "%s: Can't create socket!!\n", __FUNCTION__); 55e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return -1; 56e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 57e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 58e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner memset(&addr, 0, sizeof(addr)); 59e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner addr.sin_family = AF_INET; 60e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner addr.sin_port = htons(port); 61e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner addr.sin_addr.s_addr = htonl(0x0a000202); 62e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 63e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if ( connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0 ) { 64e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fprintf(stderr, "%s: Can't connect to tcp:local:%d: %s\n", 65e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner __FUNCTION__, port, strerror(errno)); 66e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner close(fd); 67e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return -1; 68e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 69e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 70e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner pipe->socket = fd; 71e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return 0; 72e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner} 73e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 74e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerint 75e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerpipe_openQemuPipe( Pipe* pipe, const char* pipename ) 76e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner{ 77e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner pipe->socket = qemu_pipe_open(pipename); 78e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (pipe->socket < 0) { 79e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fprintf(stderr, "%s: Could not open '%s' pipe: %s\n", __FUNCTION__, pipename, strerror(errno)); 80e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return -1; 81e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 82e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return 0; 83e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner} 84e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 85e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerint 86e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerpipe_send( Pipe* pipe, const void* buff, size_t bufflen ) 87e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner{ 88e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner int ret; 89e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner const uint8_t* ptr = buff; 90e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner while (bufflen > 0) { 91e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner ret = write(pipe->socket, ptr, bufflen); 92e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (ret < 0) { 93e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (errno == EINTR) 94e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner continue; 95e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno)); 96e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return -1; 97e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 98e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (ret == 0) { 99e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fprintf(stderr, "%s: disconnection!\n", __FUNCTION__); 100e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return -1; 101e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 102e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner ptr += ret; 103e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner bufflen -= ret; 104e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 105e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return 0; 106e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner} 107e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 108e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerint 109e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerpipe_recv( Pipe* pipe, void* buff, size_t bufflen ) 110e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner{ 111e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner int ret; 112e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 113e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner for (;;) { 114e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner ret = read(pipe->socket, buff, bufflen); 115e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (ret < 0) { 116e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (errno == EINTR) 117e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner continue; 118e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno)); 119e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return -1; 120e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 121e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (ret == 0) { 122e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner fprintf(stderr, "%s: disconnection!\n", __FUNCTION__); 123e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return -1; 124e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 125e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner break; 126e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 127e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner return ret; 128e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner} 129e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner 130e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnervoid 131e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turnerpipe_close( Pipe* pipe ) 132e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner{ 133e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner if (pipe->socket >= 0) { 134e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner close(pipe->socket); 135e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner pipe->socket = -1; 136e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner } 137e1eea50214580061e18e71e9b1ed56c7e721b751David 'Digit' Turner} 138