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