| /* |
| * 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 <sys/socket.h> |
| #include <netinet/in.h> |
| #include <errno.h> |
| #include <string.h> |
| #include <unistd.h> |
| #include <stddef.h> |
| #include <stdio.h> |
| #include "test_util.h" |
| |
| #ifdef __linux__ |
| #include <time.h> |
| double now_secs(void) |
| { |
| struct timespec tm; |
| clock_gettime(CLOCK_MONOTONIC, &tm); |
| return (double)tm.tv_sec + (double)tm.tv_nsec/1e9; |
| } |
| #else |
| #include <sys/time.h> |
| double now_secs(void) |
| { |
| struct timeval tv; |
| gettimeofday(&tv, NULL); |
| return tv.sec + (double)tv.usec/1e6; |
| } |
| #endif |
| |
| int |
| pipe_openSocket( Pipe* pipe, int port ) |
| { |
| static int fd; |
| struct sockaddr_in addr; |
| |
| pipe->socket = -1; |
| |
| fd = socket( AF_INET, SOCK_STREAM, 0 ); |
| if (fd < 0) { |
| fprintf(stderr, "%s: Can't create socket!!\n", __FUNCTION__); |
| return -1; |
| } |
| |
| memset(&addr, 0, sizeof(addr)); |
| addr.sin_family = AF_INET; |
| addr.sin_port = htons(port); |
| addr.sin_addr.s_addr = htonl(0x0a000202); |
| |
| if ( connect(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0 ) { |
| fprintf(stderr, "%s: Can't connect to tcp:local:%d: %s\n", |
| __FUNCTION__, port, strerror(errno)); |
| close(fd); |
| return -1; |
| } |
| |
| pipe->socket = fd; |
| return 0; |
| } |
| |
| int |
| pipe_openQemuPipe( Pipe* pipe, const char* pipename ) |
| { |
| pipe->socket = qemu_pipe_open(pipename); |
| if (pipe->socket < 0) { |
| fprintf(stderr, "%s: Could not open '%s' pipe: %s\n", __FUNCTION__, pipename, strerror(errno)); |
| return -1; |
| } |
| return 0; |
| } |
| |
| int |
| pipe_send( Pipe* pipe, const void* buff, size_t bufflen ) |
| { |
| int ret; |
| const uint8_t* ptr = buff; |
| while (bufflen > 0) { |
| ret = write(pipe->socket, ptr, bufflen); |
| if (ret < 0) { |
| if (errno == EINTR) |
| continue; |
| fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno)); |
| return -1; |
| } |
| if (ret == 0) { |
| fprintf(stderr, "%s: disconnection!\n", __FUNCTION__); |
| return -1; |
| } |
| ptr += ret; |
| bufflen -= ret; |
| } |
| return 0; |
| } |
| |
| int |
| pipe_recv( Pipe* pipe, void* buff, size_t bufflen ) |
| { |
| int ret; |
| |
| for (;;) { |
| ret = read(pipe->socket, buff, bufflen); |
| if (ret < 0) { |
| if (errno == EINTR) |
| continue; |
| fprintf(stderr, "%s: error: %s\n", __FUNCTION__, strerror(errno)); |
| return -1; |
| } |
| if (ret == 0) { |
| fprintf(stderr, "%s: disconnection!\n", __FUNCTION__); |
| return -1; |
| } |
| break; |
| } |
| return ret; |
| } |
| |
| void |
| pipe_close( Pipe* pipe ) |
| { |
| if (pipe->socket >= 0) { |
| close(pipe->socket); |
| pipe->socket = -1; |
| } |
| } |