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> 28 double 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> 36 double now_secs(void) 37 { 38 struct timeval tv; 39 gettimeofday(&tv, NULL); 40 return tv.sec + (double)tv.usec/1e6; 41 } 42 #endif 43 44 int 45 pipe_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 74 int 75 pipe_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 85 int 86 pipe_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 108 int 109 pipe_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 130 void 131 pipe_close( Pipe* pipe ) 132 { 133 if (pipe->socket >= 0) { 134 close(pipe->socket); 135 pipe->socket = -1; 136 } 137 } 138