diff options
Diffstat (limited to 'emulator/opengl/tests/event_injector')
-rw-r--r-- | emulator/opengl/tests/event_injector/Android.mk | 13 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/EventInjector.cpp | 76 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/EventInjector.h | 59 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/emulator-console.c | 345 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/emulator-console.h | 55 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/iolooper-select.c | 274 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/iolooper.h | 91 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/sockets.c | 1550 | ||||
-rw-r--r-- | emulator/opengl/tests/event_injector/sockets.h | 432 |
9 files changed, 0 insertions, 2895 deletions
diff --git a/emulator/opengl/tests/event_injector/Android.mk b/emulator/opengl/tests/event_injector/Android.mk deleted file mode 100644 index 26eb476..0000000 --- a/emulator/opengl/tests/event_injector/Android.mk +++ /dev/null @@ -1,13 +0,0 @@ -LOCAL_PATH := $(call my-dir) - -$(call emugl-begin-host-static-library,event_injector) - -LOCAL_SRC_FILES := \ - EventInjector.cpp \ - sockets.c \ - emulator-console.c \ - iolooper-select.c - -$(call emugl-export,C_INCLUDES,$(LOCAL_PATH)) - -$(call emugl-end-module) diff --git a/emulator/opengl/tests/event_injector/EventInjector.cpp b/emulator/opengl/tests/event_injector/EventInjector.cpp deleted file mode 100644 index 6dade6e..0000000 --- a/emulator/opengl/tests/event_injector/EventInjector.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -* 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 "EventInjector.h" -#include "emulator-console.h" - -#define PRIVATE EventInjectorPrivate - -class PRIVATE -{ -public: - IoLooper* mLooper; - EmulatorConsole* mConsole; - - EventInjectorPrivate(int port) { - mLooper = iolooper_new(); - mConsole = emulatorConsole_new(port, mLooper); - } -}; - -EventInjector::EventInjector(int consolePort) -{ - mPrivate = new PRIVATE(consolePort); -} - -EventInjector::~EventInjector() -{ - delete mPrivate; -} - -void EventInjector::wait(int timeout_ms) -{ - iolooper_wait(mPrivate->mLooper, timeout_ms); -} - -void EventInjector::poll(void) -{ - emulatorConsole_poll(mPrivate->mConsole); -} - -void EventInjector::sendMouseDown( int x, int y ) -{ - emulatorConsole_sendMouseDown(mPrivate->mConsole, x, y); -} - -void EventInjector::sendMouseUp( int x, int y ) -{ - emulatorConsole_sendMouseUp(mPrivate->mConsole, x, y); -} - -void EventInjector::sendMouseMotion( int x, int y ) -{ - emulatorConsole_sendMouseMotion(mPrivate->mConsole, x, y); -} - -void EventInjector::sendKeyDown( int keycode ) -{ - emulatorConsole_sendKey(mPrivate->mConsole, keycode, 1); -} - -void EventInjector::sendKeyUp( int keycode ) -{ - emulatorConsole_sendKey(mPrivate->mConsole, keycode, 0); -} diff --git a/emulator/opengl/tests/event_injector/EventInjector.h b/emulator/opengl/tests/event_injector/EventInjector.h deleted file mode 100644 index a8fded7..0000000 --- a/emulator/opengl/tests/event_injector/EventInjector.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* 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. -*/ -/* Event redirector is used to inject user events from a GL window - * into the emulated program. - */ -#ifndef EVENT_INJECTOR_H -#define EVENT_INJECTOR_H - -class EventInjectorPrivate; - -class EventInjector -{ -public: - EventInjector(int consolePort); - virtual ~EventInjector(); - - void wait( int timeout_ms ); - void poll( void ); - - void sendMouseDown( int x, int y ); - void sendMouseUp( int x, int y ); - void sendMouseMotion( int x, int y ); - void sendKeyDown( int keycode ); - void sendKeyUp( int keycode ); - - /* Keycode values expected by the Linux kernel, and the emulator */ - enum { - KEY_BACK = 158, - KEY_HOME = 102, - KEY_SOFT1 = 229, - KEY_LEFT = 105, - KEY_UP = 103, - KEY_DOWN = 108, - KEY_RIGHT = 106, - KEY_VOLUMEUP = 115, - KEY_VOLUMEDOWN = 114, - KEY_SEND = 231, - KEY_END = 107, - KEY_ENTER = 28, - }; - -private: - EventInjectorPrivate* mPrivate; -}; - -#endif /* EVENT_INJECTOR_H */ diff --git a/emulator/opengl/tests/event_injector/emulator-console.c b/emulator/opengl/tests/event_injector/emulator-console.c deleted file mode 100644 index a8c49b2..0000000 --- a/emulator/opengl/tests/event_injector/emulator-console.c +++ /dev/null @@ -1,345 +0,0 @@ -/* -* 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 "emulator-console.h" -#include "sockets.h" -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#define DEBUG 0 -#if DEBUG >= 1 -# define D(...) printf(__VA_ARGS__), printf("\n") -#else -# define D(...) ((void)0) -#endif -#if DEBUG >= 2 -# define DD(...) printf(__VA_ARGS__), printf("\n") -#else -# define DD(...) ((void)0) -#endif - -#define ANEW0(p) (p) = calloc(sizeof(*(p)), 1) - -enum { - STATE_CONNECTING = 0, - STATE_CONNECTED, - STATE_WAITING, - STATE_ERROR = 2 -}; - -typedef struct Msg { - const char* data; // pointer to data - int size; // size of data - int sent; // already sent (so sent..size remain in buffer). - struct Msg* next; // next message in queue. -} Msg; - -static Msg* -msg_alloc( const char* data, int datalen ) -{ - Msg* msg; - - msg = malloc(sizeof(*msg) + datalen); - msg->data = (const char*)(msg + 1); - msg->size = datalen; - msg->sent = 0; - memcpy((char*)msg->data, data, datalen); - msg->next = NULL; - - return msg; -} - -static void -msg_free( Msg* msg ) -{ - free(msg); -} - -struct EmulatorConsole { - int fd; - IoLooper* looper; - int state; - Msg* out_msg; - SockAddress address; - int64_t waitUntil; -}; - -/* Read as much from the input as possible, ignoring it. - */ -static int -emulatorConsole_eatInput( EmulatorConsole* con ) -{ - for (;;) { - char temp[64]; - int ret = socket_recv(con->fd, temp, sizeof temp); - if (ret < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return 0; - } - return -1; - } - if (ret == 0) { - return -1; - } - DD("Console received: '%.*s'", ret, temp); - } -} - -static int -emulatorConsole_sendOutput( EmulatorConsole* con ) -{ - if (con->state != STATE_CONNECTED) { - errno = EINVAL; - return -1; - } - - while (con->out_msg != NULL) { - Msg* msg = con->out_msg; - int ret; - - ret = socket_send(con->fd, - msg->data + msg->sent, - msg->size - msg->sent); - if (ret > 0) { - DD("Console sent: '%.*s'", ret, msg->data + msg->sent); - - msg->sent += ret; - if (msg->sent == msg->size) { - con->out_msg = msg->next; - msg_free(msg); - } - continue; - } - if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK)) { - return 0; - } - con->state = STATE_ERROR; - D("Console error when sending: %s", strerror(errno)); - return -1; - } - iolooper_del_write(con->looper, con->fd); - return 0; -} - -static void -emulatorConsole_completeConnect(EmulatorConsole* con) -{ - D("Console connected!"); - iolooper_add_read(con->looper, con->fd); - iolooper_del_write(con->looper, con->fd); - con->state = STATE_CONNECTED; - if (con->out_msg != NULL) { - iolooper_add_write(con->looper, con->fd); - emulatorConsole_sendOutput(con); - } -} - -static void -emulatorConsole_retry(EmulatorConsole* con) -{ - /* Not possible yet, wait one second */ - D("Could not connect to emulator, waiting 1 second: %s", errno_str); - con->state = STATE_WAITING; - con->waitUntil = iolooper_now() + 5000; -} - -static void -emulatorConsole_connect(EmulatorConsole* con) -{ - D("Trying to connect!"); - if (con->fd < 0) { - con->fd = socket_create_inet( SOCKET_STREAM ); - if (con->fd < 0) { - D("ERROR: Could not create socket: %s", errno_str); - con->state = STATE_ERROR; - return; - } - socket_set_nonblock(con->fd); - } - con->state = STATE_CONNECTING; - if (socket_connect(con->fd, &con->address) < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EINPROGRESS) { - iolooper_add_write(con->looper, con->fd); - } else { - emulatorConsole_retry(con); - } - return; - } - - emulatorConsole_completeConnect(con); -} - -static void -emulatorConsole_reset( EmulatorConsole* con ) -{ - D("Resetting console connection"); - while (con->out_msg) { - Msg* msg = con->out_msg; - con->out_msg = msg->next; - msg_free(msg); - } - iolooper_del_read(con->looper, con->fd); - iolooper_del_write(con->looper, con->fd); - socket_close(con->fd); - con->fd = -1; - emulatorConsole_connect(con); -} - -/* Create a new EmulatorConsole object to connect asynchronously to - * a given emulator port. Note that this should always succeeds since - * the connection is asynchronous. - */ -EmulatorConsole* -emulatorConsole_new(int port, IoLooper* looper) -{ - EmulatorConsole* con; - SockAddress addr; - - ANEW0(con); - con->looper = looper; - con->fd = -1; - sock_address_init_inet(&con->address, SOCK_ADDRESS_INET_LOOPBACK, port); - - emulatorConsole_connect(con); - return con; -} - -int -emulatorConsole_poll( EmulatorConsole* con ) -{ - int ret; - - if (con->state == STATE_WAITING) { - if (iolooper_now() >= con->waitUntil) - emulatorConsole_connect(con); - return 0; - } - - if (!iolooper_is_read(con->looper, con->fd) && - !iolooper_is_write(con->looper, con->fd)) - { - return 0; - } - -LOOP: - switch (con->state) { - case STATE_ERROR: - return -1; - - case STATE_CONNECTING: - // read socket error to determine success / error. - if (socket_get_error(con->fd) != 0) { - emulatorConsole_retry(con); - } else { - emulatorConsole_completeConnect(con); - } - return 0; - - case STATE_CONNECTED: - /* ignore input, if any */ - if (iolooper_is_read(con->looper, con->fd)) { - if (emulatorConsole_eatInput(con) < 0) { - goto SET_ERROR; - } - } - /* send outgoing data, if any */ - if (iolooper_is_write(con->looper, con->fd)) { - if (emulatorConsole_sendOutput(con) < 0) { - goto SET_ERROR; - } - } - return 0; - - default: - D("UNSUPPORTED STATE!"); - break; - } - -SET_ERROR: - D("Console ERROR!: %s\n", errno_str); - con->state = STATE_ERROR; - emulatorConsole_reset(con); - return -1; -} - -/* Send a message to the console asynchronously. Any answer will be - * ignored. */ -void -emulatorConsole_send( EmulatorConsole* con, const char* command ) -{ - int cmdlen = strlen(command); - Msg* msg; - Msg** plast; - - if (cmdlen == 0) - return; - - /* Append new message at end of outgoing list */ - msg = msg_alloc(command, cmdlen); - plast = &con->out_msg; - while (*plast) { - plast = &(*plast)->next; - } - *plast = msg; - if (con->out_msg == msg) { - iolooper_add_write(con->looper, con->fd); - } - emulatorConsole_sendOutput(con); -} - - -void -emulatorConsole_sendMouseDown( EmulatorConsole* con, int x, int y ) -{ - char temp[128]; - - D("sendMouseDown(%d,%d)", x, y); - snprintf(temp, sizeof temp, - "event send 3:0:%d 3:1:%d 1:330:1 0:0:0\r\n", - x, y); - emulatorConsole_send(con, temp); -} - -void -emulatorConsole_sendMouseMotion( EmulatorConsole* con, int x, int y ) -{ - /* Same as mouse down */ - emulatorConsole_sendMouseDown(con, x, y); -} - -void -emulatorConsole_sendMouseUp( EmulatorConsole* con, int x, int y ) -{ - char temp[128]; - - D("sendMouseUp(%d,%d)", x, y); - snprintf(temp, sizeof temp, - "event send 3:0:%d 3:1:%d 1:330:0 0:0:0\r\n", - x, y); - emulatorConsole_send(con, temp); -} - -#define EE(x,y) if (keycode == x) return y; - -void -emulatorConsole_sendKey( EmulatorConsole* con, int keycode, int down ) -{ - char temp[128]; - - snprintf(temp, sizeof temp, - "event send EV_KEY:%d:%d 0:0:0\r\n", keycode, down); - emulatorConsole_send(con, temp); -} diff --git a/emulator/opengl/tests/event_injector/emulator-console.h b/emulator/opengl/tests/event_injector/emulator-console.h deleted file mode 100644 index 19e9687..0000000 --- a/emulator/opengl/tests/event_injector/emulator-console.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -* 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. -*/ -#ifndef ANDROID_EMULATOR_CONSOLE_H -#define ANDROID_EMULATOR_CONSOLE_H - -#include "iolooper.h" -#include "sockets.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct EmulatorConsole EmulatorConsole; - -/* Create a new EmulatorConsole object to connect asynchronously to - * a given emulator port. Note that this always succeeds since the - * connection is asynchronous. - */ -EmulatorConsole* emulatorConsole_new(int port, IoLooper* looper); - -/* Call this after an iolooper_poll() or iolooper_wait() to check - * the status of the console's socket and act upon it. - * - * Returns 0 on success, or -1 on error (which indicates disconnection!) - */ -int emulatorConsole_poll( EmulatorConsole* console ); - -/* Send a message to the console asynchronously. Any answer will be - * ignored. */ -void emulatorConsole_send( EmulatorConsole* console, const char* command ); - -void emulatorConsole_sendMouseDown( EmulatorConsole* con, int x, int y ); -void emulatorConsole_sendMouseMotion( EmulatorConsole* con, int x, int y ); -void emulatorConsole_sendMouseUp( EmulatorConsole* con, int x, int y ); - -void emulatorConsole_sendKey( EmulatorConsole* con, int keycode, int down ); - -#ifdef __cplusplus -} -#endif - -#endif /* ANDROID_EMULATOR_CONSOLE_H */ diff --git a/emulator/opengl/tests/event_injector/iolooper-select.c b/emulator/opengl/tests/event_injector/iolooper-select.c deleted file mode 100644 index c5fc7c2..0000000 --- a/emulator/opengl/tests/event_injector/iolooper-select.c +++ /dev/null @@ -1,274 +0,0 @@ -/* -* 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 <errno.h> -#include <stdlib.h> -#include "iolooper.h" -#include "sockets.h" - -/* An implementation of iolooper.h based on Unix select() */ -#ifdef _WIN32 -# include <winsock2.h> -# include <time.h> -#else -# include <sys/types.h> -# include <sys/select.h> -# include <sys/time.h> -#endif - -struct IoLooper { - fd_set reads[1]; - fd_set writes[1]; - fd_set reads_result[1]; - fd_set writes_result[1]; - int max_fd; - int max_fd_valid; -}; - -IoLooper* -iolooper_new(void) -{ - IoLooper* iol = malloc(sizeof(*iol)); - iolooper_reset(iol); - return iol; -} - -void -iolooper_free( IoLooper* iol ) -{ - free(iol); -} - -void -iolooper_reset( IoLooper* iol ) -{ - FD_ZERO(iol->reads); - FD_ZERO(iol->writes); - iol->max_fd = -1; - iol->max_fd_valid = 1; -} - -static void -iolooper_add_fd( IoLooper* iol, int fd ) -{ - if (iol->max_fd_valid && fd > iol->max_fd) { - iol->max_fd = fd; - } -} - -static void -iolooper_del_fd( IoLooper* iol, int fd ) -{ - if (iol->max_fd_valid && fd == iol->max_fd) - iol->max_fd_valid = 0; -} - -void -iolooper_modify( IoLooper* iol, int fd, int oldflags, int newflags ) -{ - if (fd < 0) - return; - - int changed = oldflags ^ newflags; - - if ((changed & IOLOOPER_READ) != 0) { - if ((newflags & IOLOOPER_READ) != 0) - iolooper_add_read(iol, fd); - else - iolooper_del_read(iol, fd); - } - if ((changed & IOLOOPER_WRITE) != 0) { - if ((newflags & IOLOOPER_WRITE) != 0) - iolooper_add_write(iol, fd); - else - iolooper_del_write(iol, fd); - } -} - - -static int -iolooper_fd_count( IoLooper* iol ) -{ - int max_fd = iol->max_fd; - int fd; - - if (iol->max_fd_valid) - return max_fd + 1; - - /* recompute max fd */ - for (fd = 0; fd < FD_SETSIZE; fd++) { - if (!FD_ISSET(fd, iol->reads) && !FD_ISSET(fd, iol->writes)) - continue; - - max_fd = fd; - } - iol->max_fd = max_fd; - iol->max_fd_valid = 1; - - return max_fd + 1; -} - -void -iolooper_add_read( IoLooper* iol, int fd ) -{ - if (fd >= 0) { - iolooper_add_fd(iol, fd); - FD_SET(fd, iol->reads); - } -} - -void -iolooper_add_write( IoLooper* iol, int fd ) -{ - if (fd >= 0) { - iolooper_add_fd(iol, fd); - FD_SET(fd, iol->writes); - } -} - -void -iolooper_del_read( IoLooper* iol, int fd ) -{ - if (fd >= 0) { - iolooper_del_fd(iol, fd); - FD_CLR(fd, iol->reads); - } -} - -void -iolooper_del_write( IoLooper* iol, int fd ) -{ - if (fd >= 0) { - iolooper_del_fd(iol, fd); - FD_CLR(fd, iol->writes); - } -} - -int -iolooper_poll( IoLooper* iol ) -{ - int count = iolooper_fd_count(iol); - int ret; - fd_set errs; - - if (count == 0) - return 0; - - FD_ZERO(&errs); - - do { - struct timeval tv; - - tv.tv_sec = tv.tv_usec = 0; - - iol->reads_result[0] = iol->reads[0]; - iol->writes_result[0] = iol->writes[0]; - - ret = select( count, iol->reads_result, iol->writes_result, &errs, &tv); - } while (ret < 0 && errno == EINTR); - - return ret; -} - -int -iolooper_wait( IoLooper* iol, int64_t duration ) -{ - int count = iolooper_fd_count(iol); - int ret; - fd_set errs; - struct timeval tm0, *tm = NULL; - - if (count == 0) - return 0; - - if (duration < 0) - tm = NULL; - else { - tm = &tm0; - tm->tv_sec = duration / 1000; - tm->tv_usec = (duration - 1000*tm->tv_sec) * 1000; - } - - FD_ZERO(&errs); - - do { - iol->reads_result[0] = iol->reads[0]; - iol->writes_result[0] = iol->writes[0]; - - ret = select( count, iol->reads_result, iol->writes_result, &errs, tm); - if (ret == 0) { - // Indicates timeout - errno = ETIMEDOUT; - } - } while (ret < 0 && errno == EINTR); - - return ret; -} - - -int -iolooper_is_read( IoLooper* iol, int fd ) -{ - return FD_ISSET(fd, iol->reads_result); -} - -int -iolooper_is_write( IoLooper* iol, int fd ) -{ - return FD_ISSET(fd, iol->writes_result); -} - -int -iolooper_has_operations( IoLooper* iol ) -{ - return iolooper_fd_count(iol) > 0; -} - -int64_t -iolooper_now(void) -{ -#ifdef _WIN32 - FILETIME now; - int64_t now_100ns; - - GetSystemTimeAsFileTime(&now); - - /* Get the time as hundreds of nanosecond intervals since - 12:00 AM January 1t 1601 UTC. We don't really need - to compute the value relative to the Posix epoch */ - now_100ns = ((int64_t)now.dwHighDateTime << 32) | now.dwLowDateTime; - - /* 100 ns == 0.1 us == 0.0001 ms */ - return now_100ns / 10000LL; - -#else /* !_WIN32 */ - struct timeval time_now; - return gettimeofday(&time_now, NULL) ? -1 : (int64_t)time_now.tv_sec * 1000LL + - time_now.tv_usec / 1000; -#endif /* !_WIN32 */ -} - -int -iolooper_wait_absolute(IoLooper* iol, int64_t deadline) -{ - int64_t timeout = deadline - iolooper_now(); - - /* If the deadline has passed, set the timeout to 0, this allows us - * to poll the file descriptor nonetheless */ - if (timeout < 0) - timeout = 0; - - return iolooper_wait(iol, timeout); -} diff --git a/emulator/opengl/tests/event_injector/iolooper.h b/emulator/opengl/tests/event_injector/iolooper.h deleted file mode 100644 index 4aa3db7..0000000 --- a/emulator/opengl/tests/event_injector/iolooper.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -* 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. -*/ -#ifndef IOLOOPER_H -#define IOLOOPER_H - -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* An IOLooper is an abstraction for select() */ - -typedef struct IoLooper IoLooper; - -IoLooper* iolooper_new(void); -void iolooper_free( IoLooper* iol ); -void iolooper_reset( IoLooper* iol ); - -void iolooper_add_read( IoLooper* iol, int fd ); -void iolooper_add_write( IoLooper* iol, int fd ); -void iolooper_del_read( IoLooper* iol, int fd ); -void iolooper_del_write( IoLooper* iol, int fd ); - -enum { - IOLOOPER_READ = (1<<0), - IOLOOPER_WRITE = (1<<1), -}; -void iolooper_modify( IoLooper* iol, int fd, int oldflags, int newflags); - -int iolooper_poll( IoLooper* iol ); -/* Wrapper around select() - * Return: - * > 0 in case an I/O has occurred, or < 0 on error, or 0 on timeout with - * errno set to ETIMEDOUT. - */ -int iolooper_wait( IoLooper* iol, int64_t duration ); - -int iolooper_is_read( IoLooper* iol, int fd ); -int iolooper_is_write( IoLooper* iol, int fd ); -/* Returns 1 if this IoLooper has one or more file descriptor to interact with */ -int iolooper_has_operations( IoLooper* iol ); -/* Gets current time in milliseconds. - * Return: - * Number of milliseconds corresponded to the current time on success, or -1 - * on failure. - */ -int64_t iolooper_now(void); -/* Waits for an I/O to occur before specific absolute time. - * This routine should be used (instead of iolooper_wait) in cases when multiple - * sequential I/O should be completed within given time interval. For instance, - * consider the scenario, when "server" does two sequential writes, and "client" - * now has to read data transferred with these two distinct writes. It might be - * wasteful to do two reads, each with the same (large) timeout. Instead, it - * would be better to assign a deadline for both reads before the first read, - * and call iolooper_wait_absoulte with the same deadline value: - * int64_t deadline = iolooper_now() + TIMEOUT; - * if (iolooper_wait_absoulte(iol, deadline)) { - * // Process first buffer. - * (iolooper_wait_absoulte(iol, deadline)) { - * // Process second read - * } - * } - * Param: - * iol IoLooper instance for an I/O. - * deadline Deadline (absoulte time in milliseconds) before which an I/O should - * occur. - * Return: - * Number of I/O descriptors set in iol, if an I/O has occurred, 0 if no I/O - * occurred before the deadline, or -1 on error. - */ -int iolooper_wait_absolute(IoLooper* iol, int64_t deadline); - -#ifdef __cplusplus -} -#endif - -#endif /* IOLOOPER_H */ diff --git a/emulator/opengl/tests/event_injector/sockets.c b/emulator/opengl/tests/event_injector/sockets.c deleted file mode 100644 index 33df32b..0000000 --- a/emulator/opengl/tests/event_injector/sockets.c +++ /dev/null @@ -1,1550 +0,0 @@ -/* -* 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. -*/ -#ifdef __linux__ /* Recent versions of glibc only define EAI_NODATA, which is an - extension to the POSIX standard, if _GNU_SOURCE is defined. */ -# define _GNU_SOURCE 1 -#endif - -#include "sockets.h" -#include <fcntl.h> -#include <stddef.h> -#include <stdlib.h> -#include <string.h> -#include <limits.h> - -#define D(...) ((void)0) - -#ifdef _WIN32 -# define xxWIN32_LEAN_AND_MEAN -# define _WIN32_WINNT 0x501 -# include <windows.h> -# include <winsock2.h> -# include <ws2tcpip.h> -#else /* !_WIN32 */ -# include <sys/ioctl.h> -# include <sys/socket.h> -# include <netinet/in.h> -# include <netinet/tcp.h> -# include <netdb.h> -# if HAVE_UNIX_SOCKETS -# include <sys/un.h> -# ifndef UNIX_PATH_MAX -# define UNIX_PATH_MAX (sizeof(((struct sockaddr_un*)0)->sun_path)-1) -# endif -# endif -#endif /* !_WIN32 */ - -#define MIN(x,y) ({ typeof(x) _x = (x); typeof(y) _y = (y); _x <= _y ? _x : _y; }) -#define AFREE(p) free(p) -#define AARRAY_NEW(p,count) (p) = malloc(sizeof(*(p))*(count)) -#define AARRAY_NEW0(p,count) (p) = calloc(sizeof(*(p)),(count)) - -/* QSOCKET_CALL is used to deal with the fact that EINTR happens pretty - * easily in QEMU since we use SIGALRM to implement periodic timers - */ -#ifdef _WIN32 -# define QSOCKET_CALL(_ret,_cmd) \ - do { _ret = (_cmd); } while ( _ret < 0 && WSAGetLastError() == WSAEINTR ) -#else -# define QSOCKET_CALL(_ret,_cmd) \ - do { \ - errno = 0; \ - do { _ret = (_cmd); } while ( _ret < 0 && errno == EINTR ); \ - } while (0); -#endif - -#ifdef _WIN32 - -#include <errno.h> - -static int winsock_error; - -#define WINSOCK_ERRORS_LIST \ - EE(WSA_INVALID_HANDLE,EINVAL,"invalid handle") \ - EE(WSA_NOT_ENOUGH_MEMORY,ENOMEM,"not enough memory") \ - EE(WSA_INVALID_PARAMETER,EINVAL,"invalid parameter") \ - EE(WSAEINTR,EINTR,"interrupted function call") \ - EE(WSAEALREADY,EALREADY,"operation already in progress") \ - EE(WSAEBADF,EBADF,"bad file descriptor") \ - EE(WSAEACCES,EACCES,"permission denied") \ - EE(WSAEFAULT,EFAULT,"bad address") \ - EE(WSAEINVAL,EINVAL,"invalid argument") \ - EE(WSAEMFILE,EMFILE,"too many opened files") \ - EE(WSAEWOULDBLOCK,EWOULDBLOCK,"resource temporarily unavailable") \ - EE(WSAEINPROGRESS,EINPROGRESS,"operation now in progress") \ - EE(WSAEALREADY,EAGAIN,"operation already in progress") \ - EE(WSAENOTSOCK,EBADF,"socket operation not on socket") \ - EE(WSAEDESTADDRREQ,EDESTADDRREQ,"destination address required") \ - EE(WSAEMSGSIZE,EMSGSIZE,"message too long") \ - EE(WSAEPROTOTYPE,EPROTOTYPE,"wrong protocol type for socket") \ - EE(WSAENOPROTOOPT,ENOPROTOOPT,"bad protocol option") \ - EE(WSAEADDRINUSE,EADDRINUSE,"address already in use") \ - EE(WSAEADDRNOTAVAIL,EADDRNOTAVAIL,"cannot assign requested address") \ - EE(WSAENETDOWN,ENETDOWN,"network is down") \ - EE(WSAENETUNREACH,ENETUNREACH,"network unreachable") \ - EE(WSAENETRESET,ENETRESET,"network dropped connection on reset") \ - EE(WSAECONNABORTED,ECONNABORTED,"software caused connection abort") \ - EE(WSAECONNRESET,ECONNRESET,"connection reset by peer") \ - EE(WSAENOBUFS,ENOBUFS,"no buffer space available") \ - EE(WSAEISCONN,EISCONN,"socket is already connected") \ - EE(WSAENOTCONN,ENOTCONN,"socket is not connected") \ - EE(WSAESHUTDOWN,ESHUTDOWN,"cannot send after socket shutdown") \ - EE(WSAETOOMANYREFS,ETOOMANYREFS,"too many references") \ - EE(WSAETIMEDOUT,ETIMEDOUT,"connection timed out") \ - EE(WSAECONNREFUSED,ECONNREFUSED,"connection refused") \ - EE(WSAELOOP,ELOOP,"cannot translate name") \ - EE(WSAENAMETOOLONG,ENAMETOOLONG,"name too long") \ - EE(WSAEHOSTDOWN,EHOSTDOWN,"host is down") \ - EE(WSAEHOSTUNREACH,EHOSTUNREACH,"no route to host") \ - -typedef struct { - int winsock; - int unix; - const char* string; -} WinsockError; - -static const WinsockError _winsock_errors[] = { -#define EE(w,u,s) { w, u, s }, - WINSOCK_ERRORS_LIST -#undef EE - { -1, -1, NULL } -}; - -/* this function reads the latest winsock error code and updates - * errno to a matching value. It also returns the new value of - * errno. - */ -static int -_fix_errno( void ) -{ - const WinsockError* werr = _winsock_errors; - int unix = EINVAL; /* generic error code */ - - winsock_error = WSAGetLastError(); - - for ( ; werr->string != NULL; werr++ ) { - if (werr->winsock == winsock_error) { - unix = werr->unix; - break; - } - } - errno = unix; - return -1; -} - -static int -_set_errno( int code ) -{ - winsock_error = -1; - errno = code; - return -1; -} - -/* this function returns a string describing the latest Winsock error */ -const char* -_errno_str(void) -{ - const WinsockError* werr = _winsock_errors; - const char* result = NULL; - - for ( ; werr->string; werr++ ) { - if (werr->winsock == winsock_error) { - result = werr->string; - break; - } - } - - if (result == NULL) { - result = "Unknown socket error"; - } - return result; -} -#else -static int -_fix_errno( void ) -{ - return -1; -} - -static int -_set_errno( int code ) -{ - errno = code; - return -1; -} -#endif - -/* socket types */ - -static int -socket_family_to_bsd( SocketFamily family ) -{ - switch (family) { - case SOCKET_INET: return AF_INET; - case SOCKET_IN6: return AF_INET6; -#if HAVE_UNIX_SOCKETS - case SOCKET_UNIX: return AF_LOCAL; -#endif - default: return -1; - } -} - -static int -socket_type_to_bsd( SocketType type ) -{ - switch (type) { - case SOCKET_DGRAM: return SOCK_DGRAM; - case SOCKET_STREAM: return SOCK_STREAM; - default: return 0; - } -} - -static SocketType -socket_type_from_bsd( int type ) -{ - switch (type) { - case SOCK_DGRAM: return SOCKET_DGRAM; - case SOCK_STREAM: return SOCKET_STREAM; - default: return (SocketType) SOCKET_UNSPEC; - } -} - -#if 0 -static int -socket_type_check( SocketType type ) -{ - return (type == SOCKET_DGRAM || type == SOCKET_STREAM); -} -#endif - -typedef union { - struct sockaddr sa[1]; - struct sockaddr_in in[1]; -#if HAVE_IN6_SOCKETS - struct sockaddr_in6 in6[1]; -#endif -#if HAVE_UNIX_SOCKETS - struct sockaddr_un un[1]; -#endif -} sockaddr_storage; - -/* socket addresses */ - -void -sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port ) -{ - a->family = SOCKET_INET; - a->u.inet.port = port; - a->u.inet.address = ip; -} - -void -sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port ) -{ - a->family = SOCKET_IN6; - a->u.in6.port = port; - memcpy( a->u.in6.address, ip6, sizeof(a->u.in6.address) ); -} - -void -sock_address_init_unix( SockAddress* a, const char* path ) -{ - a->family = SOCKET_UNIX; - a->u._unix.path = strdup(path ? path : ""); - a->u._unix.owner = 1; -} - -void sock_address_done( SockAddress* a ) -{ - if (a->family == SOCKET_UNIX && a->u._unix.owner) { - a->u._unix.owner = 0; - free((char*)a->u._unix.path); - } -} - -static char* -format_char( char* buf, char* end, int c ) -{ - if (buf < end) { - if (buf+1 == end) { - *buf++ = 0; - } else { - *buf++ = (char) c; - *buf = 0; - } - } - return buf; -} - -static char* -format_str( char* buf, char* end, const char* str ) -{ - int len = strlen(str); - int avail = end - buf; - - if (len > avail) - len = avail; - - memcpy( buf, str, len ); - buf += len; - - if (buf == end) - buf[-1] = 0; - else - buf[0] = 0; - - return buf; -} - -static char* -format_unsigned( char* buf, char* end, unsigned val ) -{ - char temp[16]; - int nn; - - for ( nn = 0; val != 0; nn++ ) { - int rem = val % 10; - temp[nn] = '0'+rem; - val /= 10; - } - - if (nn == 0) - temp[nn++] = '0'; - - while (nn > 0) - buf = format_char(buf, end, temp[--nn]); - - return buf; -} - -static char* -format_hex( char* buf, char* end, unsigned val, int ndigits ) -{ - int shift = 4*ndigits; - static const char hex[16] = "0123456789abcdef"; - - while (shift >= 0) { - buf = format_char(buf, end, hex[(val >> shift) & 15]); - shift -= 4; - } - return buf; -} - -static char* -format_ip4( char* buf, char* end, uint32_t ip ) -{ - buf = format_unsigned( buf, end, (unsigned)(ip >> 24) ); - buf = format_char( buf, end, '.'); - buf = format_unsigned( buf, end, (unsigned)((ip >> 16) & 255)); - buf = format_char( buf, end, '.'); - buf = format_unsigned( buf, end, (unsigned)((ip >> 8) & 255)); - buf = format_char( buf, end, '.'); - buf = format_unsigned( buf, end, (unsigned)(ip & 255)); - return buf; -} - -static char* -format_ip6( char* buf, char* end, const uint8_t* ip6 ) -{ - int nn; - for (nn = 0; nn < 8; nn++) { - int val = (ip6[0] << 16) | ip6[1]; - ip6 += 2; - if (nn > 0) - buf = format_char(buf, end, ':'); - if (val == 0) - continue; - buf = format_hex(buf, end, val, 4); - } - return buf; -} - -const char* -sock_address_to_string( const SockAddress* a ) -{ - static char buf0[PATH_MAX]; - char *buf = buf0, *end = buf + sizeof(buf0); - - switch (a->family) { - case SOCKET_INET: - buf = format_ip4( buf, end, a->u.inet.address ); - buf = format_char( buf, end, ':' ); - buf = format_unsigned( buf, end, (unsigned) a->u.inet.port ); - break; - - case SOCKET_IN6: - buf = format_ip6( buf, end, a->u.in6.address ); - buf = format_char( buf, end, ':' ); - buf = format_unsigned( buf, end, (unsigned) a->u.in6.port ); - break; - - case SOCKET_UNIX: - buf = format_str( buf, end, a->u._unix.path ); - break; - - default: - return NULL; - } - - return buf0; -} - -int -sock_address_equal( const SockAddress* a, const SockAddress* b ) -{ - if (a->family != b->family) - return 0; - - switch (a->family) { - case SOCKET_INET: - return (a->u.inet.address == b->u.inet.address && - a->u.inet.port == b->u.inet.port); - - case SOCKET_IN6: - return (!memcmp(a->u.in6.address, b->u.in6.address, 16) && - a->u.in6.port == b->u.in6.port); - - case SOCKET_UNIX: - return (!strcmp(a->u._unix.path, b->u._unix.path)); - - default: - return 0; - } -} - -int -sock_address_get_port( const SockAddress* a ) -{ - switch (a->family) { - case SOCKET_INET: - return a->u.inet.port; - case SOCKET_IN6: - return a->u.in6.port; - default: - return -1; - } -} - -void -sock_address_set_port( SockAddress* a, uint16_t port ) -{ - switch (a->family) { - case SOCKET_INET: - a->u.inet.port = port; - break; - case SOCKET_IN6: - a->u.in6.port = port; - break; - default: - ; - } -} - -const char* -sock_address_get_path( const SockAddress* a ) -{ - if (a->family == SOCKET_UNIX) - return a->u._unix.path; - else - return NULL; -} - -int -sock_address_get_ip( const SockAddress* a ) -{ - if (a->family == SOCKET_INET) - return a->u.inet.address; - - return -1; -} - -#if 0 -char* -bufprint_sock_address( char* p, char* end, const SockAddress* a ) -{ - switch (a->family) { - case SOCKET_INET: - { - uint32_t ip = a->u.inet.address; - - return bufprint( p, end, "%d.%d.%d.%d:%d", - (ip >> 24) & 255, (ip >> 16) & 255, - (ip >> 8) & 255, ip & 255, - a->u.inet.port ); - } - case SOCKET_IN6: - { - int nn = 0; - const char* column = ""; - const uint8_t* tab = a->u.in6.address; - for (nn = 0; nn < 16; nn += 2) { - p = bufprint(p, end, "%s%04x", column, (tab[n] << 8) | tab[n+1]); - column = ":"; - } - return bufprint(p, end, ":%d", a->u.in6.port); - } - case SOCKET_UNIX: - { - return bufprint(p, end, "%s", a->u._unix.path); - } - default: - return p; - } -} -#endif - -static int -sock_address_to_bsd( const SockAddress* a, sockaddr_storage* paddress, socklen_t *psize ) -{ - switch (a->family) { - case SOCKET_INET: - { - struct sockaddr_in* dst = paddress->in; - - *psize = sizeof(*dst); - - memset( paddress, 0, *psize ); - - dst->sin_family = AF_INET; - dst->sin_port = htons(a->u.inet.port); - dst->sin_addr.s_addr = htonl(a->u.inet.address); - } - break; - -#if HAVE_IN6_SOCKETS - case SOCKET_IN6: - { - struct sockaddr_in6* dst = paddress->in6; - - *psize = sizeof(*dst); - - memset( paddress, 0, *psize ); - - dst->sin6_family = AF_INET6; - dst->sin6_port = htons(a->u.in6.port); - memcpy( dst->sin6_addr.s6_addr, a->u.in6.address, 16 ); - } - break; -#endif /* HAVE_IN6_SOCKETS */ - -#if HAVE_UNIX_SOCKETS - case SOCKET_UNIX: - { - int slen = strlen(a->u._unix.path); - struct sockaddr_un* dst = paddress->un; - - if (slen >= (int)UNIX_PATH_MAX) - return -1; - - memset( dst, 0, sizeof(*dst) ); - - dst->sun_family = AF_LOCAL; - memcpy( dst->sun_path, a->u._unix.path, slen ); - dst->sun_path[slen] = 0; - - *psize = (char*)&dst->sun_path[slen+1] - (char*)dst; - } - break; -#endif /* HAVE_UNIX_SOCKETS */ - - default: - return _set_errno(EINVAL); - } - - return 0; -} - -static int -sock_address_from_bsd( SockAddress* a, const void* from, size_t fromlen ) -{ - switch (((struct sockaddr *)from)->sa_family) { - case AF_INET: - { - const struct sockaddr_in* src = from; - - if (fromlen < sizeof(*src)) - return _set_errno(EINVAL); - - a->family = SOCKET_INET; - a->u.inet.port = ntohs(src->sin_port); - a->u.inet.address = ntohl(src->sin_addr.s_addr); - } - break; - -#ifdef HAVE_IN6_SOCKETS - case AF_INET6: - { - const struct sockaddr_in6* src = from; - - if (fromlen < sizeof(*src)) - return _set_errno(EINVAL); - - a->family = SOCKET_IN6; - a->u.in6.port = ntohs(src->sin6_port); - memcpy(a->u.in6.address, src->sin6_addr.s6_addr, 16); - } - break; -#endif - -#ifdef HAVE_UNIX_SOCKETS - case AF_LOCAL: - { - const struct sockaddr_un* src = from; - char* end; - - if (fromlen < sizeof(*src)) - return _set_errno(EINVAL); - - /* check that the path is zero-terminated */ - end = memchr(src->sun_path, 0, UNIX_PATH_MAX); - if (end == NULL) - return _set_errno(EINVAL); - - a->family = SOCKET_UNIX; - a->u._unix.owner = 1; - a->u._unix.path = strdup(src->sun_path); - } - break; -#endif - - default: - return _set_errno(EINVAL); - } - return 0; -} - - -int -sock_address_init_resolve( SockAddress* a, const char* hostname, uint16_t port, int preferIn6 ) -{ - struct addrinfo hints[1]; - struct addrinfo* res; - int ret; - - memset(hints, 0, sizeof(hints)); - hints->ai_family = preferIn6 ? AF_INET6 : AF_UNSPEC; - - ret = getaddrinfo(hostname, NULL, hints, &res); - if (ret != 0) { - int err; - - switch (ret) { - case EAI_AGAIN: /* server is down */ - case EAI_FAIL: /* server is sick */ - err = EHOSTDOWN; - break; - -#ifdef EAI_NODATA - case EAI_NODATA: -#endif - case EAI_NONAME: - err = ENOENT; - break; - - case EAI_MEMORY: - err = ENOMEM; - break; - - default: - err = EINVAL; - } - return _set_errno(err); - } - - /* Parse the returned list of addresses. */ - { - struct addrinfo* res_ipv4 = NULL; - struct addrinfo* res_ipv6 = NULL; - struct addrinfo* r; - - /* If preferIn6 is false, we stop on the first IPv4 address, - * otherwise, we stop on the first IPv6 one - */ - for (r = res; r != NULL; r = r->ai_next) { - if (r->ai_family == AF_INET && res_ipv4 == NULL) { - res_ipv4 = r; - if (!preferIn6) - break; - } - else if (r->ai_family == AF_INET6 && res_ipv6 == NULL) { - res_ipv6 = r; - if (preferIn6) - break; - } - } - - /* Select the best address in 'r', which will be NULL - * if there is no corresponding address. - */ - if (preferIn6) { - r = res_ipv6; - if (r == NULL) - r = res_ipv4; - } else { - r = res_ipv4; - if (r == NULL) - r = res_ipv6; - } - - if (r == NULL) { - ret = _set_errno(ENOENT); - goto Exit; - } - - /* Convert to a SockAddress */ - ret = sock_address_from_bsd( a, r->ai_addr, r->ai_addrlen ); - if (ret < 0) - goto Exit; - } - - /* need to set the port */ - switch (a->family) { - case SOCKET_INET: a->u.inet.port = port; break; - case SOCKET_IN6: a->u.in6.port = port; break; - default: ; - } - -Exit: - freeaddrinfo(res); - return ret; -} - -/* The Winsock headers for mingw lack some definitions */ -#ifndef AI_ADDRCONFIG -# define AI_ADDRCONFIG 0 -#endif - -SockAddress** -sock_address_list_create( const char* hostname, - const char* port, - unsigned flags ) -{ - SockAddress** list = NULL; - SockAddress* addr; - int nn, count, ret; - struct addrinfo ai, *res, *e; - - memset(&ai, 0, sizeof(ai)); - ai.ai_flags |= AI_ADDRCONFIG; - ai.ai_family = PF_UNSPEC; - - if (flags & SOCKET_LIST_FORCE_INET) - ai.ai_family = PF_INET; - else if (flags & SOCKET_LIST_FORCE_IN6) - ai.ai_family = PF_INET6; - - if (flags & SOCKET_LIST_PASSIVE) - ai.ai_flags |= AI_PASSIVE; - else - ai.ai_flags |= AI_CANONNAME; - - if (flags & SOCKET_LIST_DGRAM) - ai.ai_socktype = SOCK_DGRAM; - - while (1) { - struct addrinfo hints = ai; - - ret = getaddrinfo(hostname, port, &hints, &res); - if (ret == 0) - break; - - switch (ret) { -#ifdef EAI_ADDRFAMILY - case EAI_ADDRFAMILY: -#endif - case EAI_NODATA: - _set_errno(ENOENT); - break; - case EAI_FAMILY: - _set_errno(EAFNOSUPPORT); - break; - case EAI_AGAIN: - _set_errno(EAGAIN); - break; -#ifdef EAI_SYSTEM - case EAI_SYSTEM: - if (errno == EINTR) - continue; - break; -#endif - default: - _set_errno(EINVAL); - } - return NULL; - } - - /* allocate result list */ - for (count = 0, e = res; e != NULL; e = e->ai_next) - count += 1; - - AARRAY_NEW(list, count+1); - AARRAY_NEW(addr, count); - - for (nn = 0, e = res; e != NULL; e = e->ai_next) { - - ret = sock_address_from_bsd(addr, e->ai_addr, e->ai_addrlen); - if (ret < 0) - continue; - - list[nn++] = addr++; - } - list[nn] = NULL; - freeaddrinfo(res); - return list; -} - -SockAddress** -sock_address_list_create2(const char* host_and_port, unsigned flags ) -{ - char host_name[512]; - const char* actual_host_name = "localhost"; - // Parse host and port name. - const char* port_name = strchr(host_and_port, ':'); - if (port_name != NULL) { - int to_copy = MIN((int)sizeof(host_name)-1, port_name - host_and_port); - if (to_copy != 0) { - memcpy(host_name, host_and_port, to_copy); - host_name[to_copy] = '\0'; - actual_host_name = host_name; - port_name++; - } else { - return NULL; - } - } else { - port_name = host_and_port; - } - // Make sure that port_name is not empty. - if (port_name[0] == '\0') { - return NULL; - } - return sock_address_list_create(actual_host_name, port_name, flags); -} - -void -sock_address_list_free( SockAddress** list ) -{ - int nn; - SockAddress* addr; - - if (list == NULL) - return; - - addr = list[0]; - for (nn = 0; list[nn] != NULL; nn++) { - sock_address_done(list[nn]); - list[nn] = NULL; - } - AFREE(addr); - AFREE(list); -} - -int -sock_address_get_numeric_info( SockAddress* a, - char* host, - size_t hostlen, - char* serv, - size_t servlen ) -{ - struct sockaddr* saddr; - socklen_t slen; - int ret; - - switch (a->family) { - case SOCKET_INET: - saddr = (struct sockaddr*) &a->u.inet.address; - slen = sizeof(a->u.inet.address); - break; - -#if HAVE_IN6_SOCKET - case SOCKET_IN6: - saddr = (struct sockaddr*) &a->u.in6.address; - slen = sizeof(a->u.in6.address); - break; -#endif - default: - return _set_errno(EINVAL); - } - - ret = getnameinfo( saddr, slen, host, hostlen, serv, servlen, - NI_NUMERICHOST | NI_NUMERICSERV ); - - switch (ret) { - case 0: - break; - case EAI_AGAIN: - ret = EAGAIN; - break; - default: - ret = EINVAL; - } - return ret; -} - -int -socket_create( SocketFamily family, SocketType type ) -{ - int ret; - int sfamily = socket_family_to_bsd(family); - int stype = socket_type_to_bsd(type); - - if (sfamily < 0 || stype < 0) { - return _set_errno(EINVAL); - } - - QSOCKET_CALL(ret, socket(sfamily, stype, 0)); - if (ret < 0) - return _fix_errno(); - - return ret; -} - - -int -socket_create_inet( SocketType type ) -{ - return socket_create( SOCKET_INET, type ); -} - -#if HAVE_IN6_SOCKETS -int -socket_create_in6 ( SocketType type ) -{ - return socket_create( SOCKET_IN6, type ); -} -#endif - -#if HAVE_UNIX_SOCKETS -int -socket_create_unix( SocketType type ) -{ - return socket_create( SOCKET_UNIX, type ); -} -#endif - -int socket_can_read(int fd) -{ -#ifdef _WIN32 - unsigned long opt; - - if (ioctlsocket(fd, FIONREAD, &opt) < 0) - return 0; - - return opt; -#else - int opt; - - if (ioctl(fd, FIONREAD, &opt) < 0) - return 0; - - return opt; -#endif -} - -#define SOCKET_CALL(cmd) \ - int ret; \ - QSOCKET_CALL(ret, (cmd)); \ - if (ret < 0) \ - return _fix_errno(); \ - return ret; \ - -int -socket_send(int fd, const void* buf, int buflen) -{ - SOCKET_CALL(send(fd, buf, buflen, 0)) -} - -int -socket_send_oob( int fd, const void* buf, int buflen ) -{ - SOCKET_CALL(send(fd, buf, buflen, MSG_OOB)); -} - -int -socket_sendto(int fd, const void* buf, int buflen, const SockAddress* to) -{ - sockaddr_storage sa; - socklen_t salen; - - if (sock_address_to_bsd(to, &sa, &salen) < 0) - return -1; - - SOCKET_CALL(sendto(fd, buf, buflen, 0, sa.sa, salen)); -} - -int -socket_recv(int fd, void* buf, int len) -{ - SOCKET_CALL(recv(fd, buf, len, 0)); -} - -int -socket_recvfrom(int fd, void* buf, int len, SockAddress* from) -{ - sockaddr_storage sa; - socklen_t salen = sizeof(sa); - int ret; - - QSOCKET_CALL(ret,recvfrom(fd,buf,len,0,sa.sa,&salen)); - if (ret < 0) - return _fix_errno(); - - if (sock_address_from_bsd(from, &sa, salen) < 0) - return -1; - - return ret; -} - -int -socket_connect( int fd, const SockAddress* address ) -{ - sockaddr_storage addr; - socklen_t addrlen; - - if (sock_address_to_bsd(address, &addr, &addrlen) < 0) - return -1; - - SOCKET_CALL(connect(fd,addr.sa,addrlen)); -} - -int -socket_bind( int fd, const SockAddress* address ) -{ - sockaddr_storage addr; - socklen_t addrlen; - - if (sock_address_to_bsd(address, &addr, &addrlen) < 0) - return -1; - - SOCKET_CALL(bind(fd, addr.sa, addrlen)); -} - -int -socket_get_address( int fd, SockAddress* address ) -{ - sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - int ret; - - QSOCKET_CALL(ret, getsockname(fd, addr.sa, &addrlen)); - if (ret < 0) - return _fix_errno(); - - return sock_address_from_bsd(address, &addr, addrlen); -} - -int -socket_get_peer_address( int fd, SockAddress* address ) -{ - sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - int ret; - - QSOCKET_CALL(ret, getpeername(fd, addr.sa, &addrlen)); - if (ret < 0) - return _fix_errno(); - - return sock_address_from_bsd(address, &addr, addrlen); -} - -int -socket_listen( int fd, int backlog ) -{ - SOCKET_CALL(listen(fd, backlog)); -} - -int -socket_accept( int fd, SockAddress* address ) -{ - sockaddr_storage addr; - socklen_t addrlen = sizeof(addr); - int ret; - - QSOCKET_CALL(ret, accept(fd, addr.sa, &addrlen)); - if (ret < 0) - return _fix_errno(); - - if (address) { - if (sock_address_from_bsd(address, &addr, addrlen) < 0) { - socket_close(ret); - return -1; - } - } - return ret; -} - -static int -socket_getoption(int fd, int domain, int option, int defaut) -{ - int ret; - while (1) { -#ifdef _WIN32 - DWORD opt = (DWORD)-1; -#else - int opt = -1; -#endif - socklen_t optlen = sizeof(opt); - ret = getsockopt(fd, domain, option, (char*)&opt, &optlen); - if (ret == 0) - return (int)opt; - if (errno != EINTR) - return defaut; - } -#undef OPT_CAST -} - - -SocketType socket_get_type(int fd) -{ - int so_type = socket_getoption(fd, SOL_SOCKET, SO_TYPE, -1); - return socket_type_from_bsd(so_type); -} - -int socket_set_nonblock(int fd) -{ -#ifdef _WIN32 - unsigned long opt = 1; - return ioctlsocket(fd, FIONBIO, &opt); -#else - int flags = fcntl(fd, F_GETFL); - return fcntl(fd, F_SETFL, flags | O_NONBLOCK); -#endif -} - -int socket_set_blocking(int fd) -{ -#ifdef _WIN32 - unsigned long opt = 0; - return ioctlsocket(fd, FIONBIO, &opt); -#else - int flags = fcntl(fd, F_GETFL); - return fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); -#endif -} - -static int -socket_setoption(int fd, int domain, int option, int _flag) -{ -#ifdef _WIN32 - DWORD flag = (DWORD) _flag; -#else - int flag = _flag; -#endif - return setsockopt( fd, domain, option, (const char*)&flag, sizeof(flag) ); -} - -int socket_set_xreuseaddr(int fd) -{ -#ifdef _WIN32 - /* on Windows, SO_REUSEADDR is used to indicate that several programs can - * bind to the same port. this is completely different from the Unix - * semantics. instead of SO_EXCLUSIVEADDR to ensure that explicitely prevent - * this. - */ - return socket_setoption(fd, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, 1); -#else - return socket_setoption(fd, SOL_SOCKET, SO_REUSEADDR, 1); -#endif -} - - -int socket_set_oobinline(int fd) -{ - return socket_setoption(fd, SOL_SOCKET, SO_OOBINLINE, 1); -} - - -int socket_set_nodelay(int fd) -{ - return socket_setoption(fd, IPPROTO_TCP, TCP_NODELAY, 1); -} - -int socket_set_ipv6only(int fd) -{ -/* IPV6_ONLY is only supported since Vista on Windows, - * and the Mingw headers lack its definition anyway. - */ -#if defined(_WIN32) && !defined(IPV6_V6ONLY) - return 0; -#else - return socket_setoption(fd, IPPROTO_IPV6, IPV6_V6ONLY, 1); -#endif -} - - -int socket_get_error(int fd) -{ - return socket_getoption(fd, SOL_SOCKET, SO_ERROR, -1); -} - -#ifdef _WIN32 -#include <stdlib.h> - -static void socket_cleanup(void) -{ - WSACleanup(); -} - -int socket_init(void) -{ - WSADATA Data; - int ret, err; - - ret = WSAStartup(MAKEWORD(2,2), &Data); - if (ret != 0) { - err = WSAGetLastError(); - return -1; - } - atexit(socket_cleanup); - return 0; -} - -#else /* !_WIN32 */ - -int socket_init(void) -{ - return 0; /* nothing to do on Unix */ -} - -#endif /* !_WIN32 */ - -#ifdef _WIN32 - -void -socket_close( int fd ) -{ - int old_errno = errno; - - shutdown( fd, SD_BOTH ); - /* we want to drain the socket before closing it */ - //qemu_set_fd_handler( fd, socket_close_handler, NULL, (void*)fd ); - closesocket(fd); - - errno = old_errno; -} - -#else /* !_WIN32 */ - -#include <unistd.h> - -void -socket_close( int fd ) -{ - int old_errno = errno; - - shutdown( fd, SHUT_RDWR ); - close( fd ); - - errno = old_errno; -} - -#endif /* !_WIN32 */ - - -static int -socket_bind_server( int s, const SockAddress* to, SocketType type ) -{ - socket_set_xreuseaddr(s); - - if (socket_bind(s, to) < 0) { - D("could not bind server socket address %s: %s", - sock_address_to_string(to), errno_str); - goto FAIL; - } - - if (type == SOCKET_STREAM) { - if (socket_listen(s, 4) < 0) { - D("could not listen server socket %s: %s", - sock_address_to_string(to), errno_str); - goto FAIL; - } - } - return s; - -FAIL: - socket_close(s); - return -1; -} - - -static int -socket_connect_client( int s, const SockAddress* to ) -{ - if (socket_connect(s, to) < 0) { - D( "could not connect client socket to %s: %s\n", - sock_address_to_string(to), errno_str ); - socket_close(s); - return -1; - } - - socket_set_nonblock( s ); - return s; -} - - -static int -socket_in_server( int address, int port, SocketType type ) -{ - SockAddress addr; - int s; - - sock_address_init_inet( &addr, address, port ); - s = socket_create_inet( type ); - if (s < 0) - return -1; - - return socket_bind_server( s, &addr, type ); -} - - -static int -socket_in_client( SockAddress* to, SocketType type ) -{ - int s; - - s = socket_create_inet( type ); - if (s < 0) return -1; - - return socket_connect_client( s, to ); -} - - -int -socket_loopback_server( int port, SocketType type ) -{ - return socket_in_server( SOCK_ADDRESS_INET_LOOPBACK, port, type ); -} - -int -socket_loopback_client( int port, SocketType type ) -{ - SockAddress addr; - - sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, port ); - return socket_in_client( &addr, type ); -} - - -int -socket_network_client( const char* host, int port, SocketType type ) -{ - SockAddress addr; - - if (sock_address_init_resolve( &addr, host, port, 0) < 0) - return -1; - - return socket_in_client( &addr, type ); -} - - -int -socket_anyaddr_server( int port, SocketType type ) -{ - return socket_in_server( SOCK_ADDRESS_INET_ANY, port, type ); -} - -int -socket_accept_any( int server_fd ) -{ - int fd; - - QSOCKET_CALL(fd, accept( server_fd, NULL, 0 )); - if (fd < 0) { - D( "could not accept client connection from fd %d: %s", - server_fd, errno_str ); - return -1; - } - - /* set to non-blocking */ - socket_set_nonblock( fd ); - return fd; -} - - -#if HAVE_UNIX_SOCKETS - -int -socket_unix_server( const char* name, SocketType type ) -{ - SockAddress addr; - int s, ret; - - s = socket_create_unix( type ); - if (s < 0) - return -1; - - sock_address_init_unix( &addr, name ); - - do { - ret = unlink( name ); - } while (ret < 0 && errno == EINTR); - - ret = socket_bind_server( s, &addr, type ); - - sock_address_done( &addr ); - return ret; -} - -int -socket_unix_client( const char* name, SocketType type ) -{ - SockAddress addr; - int s, ret; - - s = socket_create_unix(type); - if (s < 0) - return -1; - - sock_address_init_unix( &addr, name ); - - ret = socket_connect_client( s, &addr ); - - sock_address_done( &addr ); - return ret; -} - -#endif /* HAVE_UNIX_SOCKETS */ - - - -int -socket_pair(int *fd1, int *fd2) -{ -#ifndef _WIN32 - int fds[2]; - int ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds); - - if (!ret) { - socket_set_nonblock(fds[0]); - socket_set_nonblock(fds[1]); - *fd1 = fds[0]; - *fd2 = fds[1]; - } - return ret; -#else /* _WIN32 */ - /* on Windows, select() only works with network sockets, which - * means we absolutely cannot use Win32 PIPEs to implement - * socket pairs with the current event loop implementation. - * We're going to do like Cygwin: create a random pair - * of localhost TCP sockets and connect them together - */ - int s0, s1, s2, port; - struct sockaddr_in sockin; - socklen_t len; - - /* first, create the 'server' socket. - * a port number of 0 means 'any port between 1024 and 5000. - * see Winsock bind() documentation for details */ - s0 = socket_loopback_server( 0, SOCK_STREAM ); - if (s0 < 0) - return -1; - - /* now connect a client socket to it, we first need to - * extract the server socket's port number */ - len = sizeof sockin; - if (getsockname(s0, (struct sockaddr*) &sockin, &len) < 0) { - closesocket (s0); - return -1; - } - - port = ntohs(sockin.sin_port); - s2 = socket_loopback_client( port, SOCK_STREAM ); - if (s2 < 0) { - closesocket(s0); - return -1; - } - - /* we need to accept the connection on the server socket - * this will create the second socket for the pair - */ - len = sizeof sockin; - s1 = accept(s0, (struct sockaddr*) &sockin, &len); - if (s1 == INVALID_SOCKET) { - closesocket (s0); - closesocket (s2); - return -1; - } - socket_set_nonblock(s1); - - /* close server socket */ - closesocket(s0); - *fd1 = s1; - *fd2 = s2; - return 0; -#endif /* _WIN32 */ -} - - - -int -socket_mcast_inet_add_membership( int s, uint32_t ip ) -{ - struct ip_mreq imr; - - imr.imr_multiaddr.s_addr = htonl(ip); - imr.imr_interface.s_addr = htonl(INADDR_ANY); - - if ( setsockopt( s, IPPROTO_IP, IP_ADD_MEMBERSHIP, - (const char *)&imr, - sizeof(struct ip_mreq)) < 0 ) - { - return _fix_errno(); - } - return 0; -} - -int -socket_mcast_inet_drop_membership( int s, uint32_t ip ) -{ - struct ip_mreq imr; - - imr.imr_multiaddr.s_addr = htonl(ip); - imr.imr_interface.s_addr = htonl(INADDR_ANY); - - if ( setsockopt( s, IPPROTO_IP, IP_DROP_MEMBERSHIP, - (const char *)&imr, - sizeof(struct ip_mreq)) < 0 ) - { - return _fix_errno(); - } - return 0; -} - -int -socket_mcast_inet_set_loop( int s, int enabled ) -{ - return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_LOOP, !!enabled ); -} - -int -socket_mcast_inet_set_ttl( int s, int ttl ) -{ - return socket_setoption( s, IPPROTO_IP, IP_MULTICAST_TTL, ttl ); -} - - -char* -host_name( void ) -{ - static char buf[256]; /* 255 is the max host name length supported by DNS */ - int ret; - - QSOCKET_CALL(ret, gethostname(buf, sizeof(buf))); - - if (ret < 0) - return "localhost"; - else - return buf; -} diff --git a/emulator/opengl/tests/event_injector/sockets.h b/emulator/opengl/tests/event_injector/sockets.h deleted file mode 100644 index ea48c5f..0000000 --- a/emulator/opengl/tests/event_injector/sockets.h +++ /dev/null @@ -1,432 +0,0 @@ -/* -* 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. -*/ -/* headers to use the BSD sockets */ -#ifndef ANDROID_SOCKET_H -#define ANDROID_SOCKET_H - -#include <stddef.h> -#include <stdint.h> -#include <errno.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* we're going to hide the implementation details of sockets behind - * a simple wrapper interface declared here. - * - * all socket operations set the global 'errno' variable on error. - * this is unlike Winsock which instead modifies another internal - * variable accessed through WSAGetLastError() and WSASetLastError() - */ - -/* the wrapper will convert any Winsock error message into an errno - * code for you. There are however a few standard Unix error codes - * that are not defined by the MS C library headers, so we add them - * here. We use the official Winsock error codes, which are documented - * even though we don't want to include the Winsock headers - */ -#ifdef _WIN32 -# ifndef EINTR -# define EINTR 10004 -# endif -# ifndef EAGAIN -# define EAGAIN 10035 -# endif -# ifndef EWOULDBLOCK -# define EWOULDBLOCK EAGAIN -# endif -# ifndef EINPROGRESS -# define EINPROGRESS 10036 -# endif -# ifndef EALREADY -# define EALREADY 10037 -# endif -# ifndef EDESTADDRREQ -# define EDESTADDRREQ 10039 -# endif -# ifndef EMSGSIZE -# define EMSGSIZE 10040 -# endif -# ifndef EPROTOTYPE -# define EPROTOTYPE 10041 -# endif -# ifndef ENOPROTOOPT -# define ENOPROTOOPT 10042 -# endif -# ifndef EAFNOSUPPORT -# define EAFNOSUPPORT 10047 -# endif -# ifndef EADDRINUSE -# define EADDRINUSE 10048 -# endif -# ifndef EADDRNOTAVAIL -# define EADDRNOTAVAIL 10049 -# endif -# ifndef ENETDOWN -# define ENETDOWN 10050 -# endif -# ifndef ENETUNREACH -# define ENETUNREACH 10051 -# endif -# ifndef ENETRESET -# define ENETRESET 10052 -# endif -# ifndef ECONNABORTED -# define ECONNABORTED 10053 -# endif -# ifndef ECONNRESET -# define ECONNRESET 10054 -# endif -# ifndef ENOBUFS -# define ENOBUFS 10055 -# endif -# ifndef EISCONN -# define EISCONN 10056 -# endif -# ifndef ENOTCONN -# define ENOTCONN 10057 -# endif -# ifndef ESHUTDOWN -# define ESHUTDOWN 10058 -# endif -# ifndef ETOOMANYREFS -# define ETOOMANYREFS 10059 -# endif -# ifndef ETIMEDOUT -# define ETIMEDOUT 10060 -# endif -# ifndef ECONNREFUSED -# define ECONNREFUSED 10061 -# endif -# ifndef ELOOP -# define ELOOP 10062 -# endif -# ifndef EHOSTDOWN -# define EHOSTDOWN 10064 -# endif -# ifndef EHOSTUNREACH -# define EHOSTUNREACH 10065 -# endif -#endif /* _WIN32 */ - -/* Define 'errno_str' as a handy macro to return the string - * corresponding to a given errno code. On Unix, this is - * equivalent to strerror(errno), but on Windows, this will - * take care of Winsock-originated errors as well. - */ -#ifdef _WIN32 - extern const char* _errno_str(void); -# define errno_str _errno_str() -#else -# define errno_str strerror(errno) -#endif - -/* always enable IPv6 sockets for now. - * the QEMU internal router is not capable of - * supporting them, but we plan to replace it - * with something better in the future. - */ -#define HAVE_IN6_SOCKETS 1 - -/* Unix sockets are not available on Win32 */ -#ifndef _WIN32 -# define HAVE_UNIX_SOCKETS 1 -#endif - -/* initialize the socket sub-system. this must be called before - * using any of the declarations below. - */ -int socket_init( void ); - -/* return the name of the current host */ -char* host_name( void ); - -/* supported socket types */ -typedef enum { - SOCKET_DGRAM = 0, - SOCKET_STREAM -} SocketType; - -/* supported socket families */ -typedef enum { - SOCKET_UNSPEC, - SOCKET_INET, - SOCKET_IN6, - SOCKET_UNIX -} SocketFamily; - -/* Generic socket address structure. Note that for Unix - * sockets, the path is stored in a heap-allocated block, - * unless the 'owner' field is cleared. If this is the case, - */ -typedef struct { - SocketFamily family; - union { - struct { - uint16_t port; - uint32_t address; - } inet; - struct { - uint16_t port; - uint8_t address[16]; - } in6; - struct { - int owner; - const char* path; - } _unix; - } u; -} SockAddress; - -#define SOCK_ADDRESS_INET_ANY 0x00000000 -#define SOCK_ADDRESS_INET_LOOPBACK 0x7f000001 - -/* initialize a new IPv4 socket address, the IP address and port are - * in host endianess. - */ -void sock_address_init_inet( SockAddress* a, uint32_t ip, uint16_t port ); - -/* Initialize an IPv6 socket address, the address is in network order - * and the port in host endianess. - */ -#if HAVE_IN6_SOCKETS -void sock_address_init_in6 ( SockAddress* a, const uint8_t* ip6[16], uint16_t port ); -#endif - -/* Intialize a Unix socket address, this will copy the 'path' string into the - * heap. You need to call sock_address_done() to release the copy - */ -#if HAVE_UNIX_SOCKETS -void sock_address_init_unix( SockAddress* a, const char* path ); -#endif - -/* Finalize a socket address, only needed for now for Unix addresses */ -void sock_address_done( SockAddress* a ); - -int sock_address_equal( const SockAddress* a, const SockAddress* b ); - -/* return a static string describing the address */ -const char* sock_address_to_string( const SockAddress* a ); - -static __inline__ -SocketFamily sock_address_get_family( const SockAddress* a ) -{ - return a->family; -} - -/* return the port number of a given socket address, or -1 if it's a Unix one */ -int sock_address_get_port( const SockAddress* a ); - -/* set the port number of a given socket address, don't do anything for Unix ones */ -void sock_address_set_port( SockAddress* a, uint16_t port ); - -/* return the path of a given Unix socket, returns NULL for non-Unix ones */ -const char* sock_address_get_path( const SockAddress* a ); - -/* return the inet address, or -1 if it's not SOCKET_INET */ -int sock_address_get_ip( const SockAddress* a ); - -/* bufprint a socket address into a human-readable string */ -char* bufprint_sock_address( char* p, char* end, const SockAddress* a ); - -/* resolve a hostname or decimal IPv4/IPv6 address into a socket address. - * returns 0 on success, or -1 on failure. Note that the values or errno - * set by this function are the following: - * - * EINVAL : invalid argument - * EHOSTDOWN : could not reach DNS server - * ENOENT : no host with this name, or host doesn't have any IP address - * ENOMEM : not enough memory to perform request - */ -int sock_address_init_resolve( SockAddress* a, - const char* hostname, - uint16_t port, - int preferIn6 ); - -int sock_address_get_numeric_info( SockAddress* a, - char* host, - size_t hostlen, - char* serv, - size_t servlen ); - -/* Support for listing all socket addresses of a given host */ -enum { - SOCKET_LIST_PASSIVE = (1 << 0), - SOCKET_LIST_FORCE_INET = (1 << 1), - SOCKET_LIST_FORCE_IN6 = (1 << 2), - SOCKET_LIST_DGRAM = (1 << 3), -}; - -/* resolve a host and service/port name into a list of SockAddress objects. - * returns a NULL-terminated array of SockAddress pointers on success, - * or NULL in case of failure, with the value of errno set to one of the - * following: - * - * EINVAL : invalid argument - * EHOSTDOWN : could not reach DNS server - * ENOENT : no host with this name, or host doesn't have IP address - * ENOMEM : not enough memory to perform request - * - * other system-level errors can also be set depending on the host sockets - * implementation. - * - * This function loops on EINTR so the caller shouldn't have to check for it. - */ -SockAddress** sock_address_list_create( const char* hostname, - const char* port, - unsigned flags ); - -/* resolve a string containing host and port name into a list of SockAddress - * objects. Parameter host_and_port should be in format [host:]port, where - * 'host' addresses the machine and must be resolvable into an IP address, and - * 'port' is a decimal numeric value for the port. 'host' is optional, and if - * ommited, localhost will be used. - * returns a NULL-terminated array of SockAddress pointers on success, - * or NULL in case of failure, with the value of errno set to one of the - * following: - * - * EINVAL : invalid argument - * EHOSTDOWN : could not reach DNS server - * ENOENT : no host with this name, or host doesn't have IP address - * ENOMEM : not enough memory to perform request - * - * other system-level errors can also be set depending on the host sockets - * implementation. - * - * This function loops on EINTR so the caller shouldn't have to check for it. - */ -SockAddress** sock_address_list_create2(const char* host_and_port, - unsigned flags ); - -void sock_address_list_free( SockAddress** list ); - -/* create a new socket, return the socket number of -1 on failure */ -int socket_create( SocketFamily family, SocketType type ); - -/* create a new socket intended for IPv4 communication. returns the socket number, - * or -1 on failure. - */ -int socket_create_inet( SocketType type ); - -/* create a new socket intended for IPv6 communication. returns the socket number, - * or -1 on failure. - */ -#if HAVE_IN6_SOCKETS -int socket_create_in6 ( SocketType type ); -#endif - -/* create a unix/local domain socket. returns the socket number, - * or -1 on failure. - */ -#if HAVE_UNIX_SOCKETS -int socket_create_unix( SocketType type ); -#endif - -/* return the type of a given socket */ -SocketType socket_get_type(int fd); - -/* set SO_REUSEADDR on Unix, SO_EXCLUSIVEADDR on Windows */ -int socket_set_xreuseaddr(int fd); - -/* set socket in non-blocking mode */ -int socket_set_nonblock(int fd); - -/* set socket in blocking mode */ -int socket_set_blocking(int fd); - -/* disable the TCP Nagle algorithm for lower latency */ -int socket_set_nodelay(int fd); - -/* send OOB data inline for this socket */ -int socket_set_oobinline(int fd); - -/* force listening to IPv6 interfaces only */ -int socket_set_ipv6only(int fd); - -/* retrieve last socket error code */ -int socket_get_error(int fd); - -/* close an opened socket. Note that this is unlike the Unix 'close' because: - * - it will properly shutdown the socket in the background - * - it does not modify errno - */ -void socket_close( int fd ); - -/* the following functions are equivalent to the BSD sockets ones - */ -int socket_recv ( int fd, void* buf, int buflen ); -int socket_recvfrom( int fd, void* buf, int buflen, SockAddress* from ); - -int socket_send ( int fd, const void* buf, int buflen ); -int socket_send_oob( int fd, const void* buf, int buflen ); -int socket_sendto( int fd, const void* buf, int buflen, const SockAddress* to ); - -int socket_connect( int fd, const SockAddress* address ); -int socket_bind( int fd, const SockAddress* address ); -int socket_get_address( int fd, SockAddress* address ); -int socket_get_peer_address( int fd, SockAddress* address ); -int socket_listen( int fd, int backlog ); -int socket_accept( int fd, SockAddress* address ); - -/* returns the number of bytes that can be read from a socket */ -int socket_can_read( int fd ); - -/* this call creates a pair of non-blocking sockets connected - * to each other. this is equivalent to calling the Unix function: - * socketpair(AF_LOCAL,SOCK_STREAM,0,&fds) - * - * on Windows, this will use a pair of TCP loopback sockets instead - * returns 0 on success, -1 on error. - */ -int socket_pair(int *fd1, int *fd2); - -/* create a server socket listening on the host's loopback interface */ -int socket_loopback_server( int port, SocketType type ); - -/* connect to a port on the host's loopback interface */ -int socket_loopback_client( int port, SocketType type ); - -/* create a server socket listening to a Unix domain path */ -#if HAVE_UNIX_SOCKETS -int socket_unix_server( const char* name, SocketType type ); -#endif - -/* create a Unix sockets and connects it to a Unix server */ -#if HAVE_UNIX_SOCKETS -int socket_unix_client( const char* name, SocketType type ); -#endif - -/* create an IPv4 client socket and connect it to a given host */ -int socket_network_client( const char* host, int port, SocketType type ); - -/* create an IPv4 socket and binds it to a given port of the host's interface */ -int socket_anyaddr_server( int port, SocketType type ); - -/* accept a connection from the host's any interface, return the new socket - * descriptor or -1 */ -int socket_accept_any( int server_fd ); - - -int socket_mcast_inet_add_membership( int s, uint32_t ip ); -int socket_mcast_inet_drop_membership( int s, uint32_t ip ); -int socket_mcast_inet_set_loop( int s, int enabled ); -int socket_mcast_inet_set_ttl( int s, int ttl ); - -#ifdef __cplusplus -} -#endif - -#endif /* ANDROID_SOCKET_H */ |