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