sysdeps_win32.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "sysdeps.h"
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <windows.h>
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <winsock2.h>
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  TRACE_TAG  TRACE_SYSDEPS
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "adb.h"
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern void fatal(const char *fmt, ...);
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define assert(cond)  do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0)
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****      replaces libs/cutils/load_file.c                          *****/
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid *load_file(const char *fn, unsigned *_sz)
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE    file;
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char     *data;
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DWORD     file_size;
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    file = CreateFile( fn,
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       GENERIC_READ,
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       FILE_SHARE_READ,
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       NULL,
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       OPEN_EXISTING,
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       0,
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                       NULL );
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (file == INVALID_HANDLE_VALUE)
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    file_size = GetFileSize( file, NULL );
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    data      = NULL;
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (file_size > 0) {
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        data = (char*) malloc( file_size + 1 );
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (data == NULL) {
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D("load_file: could not allocate %ld bytes\n", file_size );
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            file_size = 0;
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        } else {
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DWORD  out_bytes;
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) ||
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                 out_bytes != file_size )
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            {
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D("load_file: could not read %ld bytes from '%s'\n", file_size, fn);
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                free(data);
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                data      = NULL;
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                file_size = 0;
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( file );
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    *_sz = (unsigned) file_size;
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  data;
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    common file descriptor handling                             *****/
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef const struct FHClassRec_*   FHClass;
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct FHRec_*          FH;
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct EventHookRec_*  EventHook;
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct FHClassRec_
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void (*_fh_init) ( FH  f );
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  (*_fh_close)( FH  f );
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  (*_fh_lseek)( FH  f, int  pos, int  origin );
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  (*_fh_read) ( FH  f, void*  buf, int  len );
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  (*_fh_write)( FH  f, const void*  buf, int  len );
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void (*_fh_hook) ( FH  f, int  events, EventHook  hook );
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} FHClassRec;
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* used to emulate unix-domain socket pairs */
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct SocketPairRec_*  SocketPair;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct FHRec_
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FHClass    clazz;
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int        used;
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int        eof;
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    union {
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        HANDLE      handle;
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SOCKET      socket;
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SocketPair  pair;
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } u;
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE    event;
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int       mask;
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char  name[32];
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} FHRec;
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  fh_handle  u.handle
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  fh_socket  u.socket
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  fh_pair    u.pair
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  WIN32_FH_BASE    100
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  WIN32_MAX_FHS    128
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic adb_mutex_t   _win32_lock;
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic  FHRec        _win32_fhs[ WIN32_MAX_FHS ];
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic  int          _win32_fh_count;
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic FH
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_from_int( int   fd )
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f;
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd -= WIN32_FH_BASE;
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fd < 0 || fd >= _win32_fh_count) {
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE );
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EBADF;
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f = &_win32_fhs[fd];
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (f->used == 0) {
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "_fh_from_int: invalid fd %d\n", fd + WIN32_FH_BASE );
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EBADF;
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return NULL;
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return f;
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_to_int( FH  f )
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return (int)(f - _win32_fhs) + WIN32_FH_BASE;
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic FH
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_alloc( FHClass  clazz )
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  nn;
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   f = NULL;
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_mutex_lock( &_win32_lock );
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (_win32_fh_count < WIN32_MAX_FHS) {
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f = &_win32_fhs[ _win32_fh_count++ ];
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Exit;
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (nn = 0; nn < WIN32_MAX_FHS; nn++) {
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( _win32_fhs[nn].clazz == NULL) {
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            f = &_win32_fhs[nn];
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto Exit;
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "_fh_alloc: no more free file descriptors\n" );
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectExit:
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (f) {
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->clazz = clazz;
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->used  = 1;
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->eof   = 0;
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        clazz->_fh_init(f);
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    adb_mutex_unlock( &_win32_lock );
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return f;
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_close( FH   f )
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f->used ) {
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->clazz->_fh_close( f );
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->used = 0;
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->eof  = 0;
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->clazz = NULL;
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* forward definitions */
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const FHClassRec   _fh_file_class;
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const FHClassRec   _fh_socket_class;
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    file-based descriptor handling                              *****/
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_file_init( FH  f )
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_handle = INVALID_HANDLE_VALUE;
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_file_close( FH  f )
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( f->fh_handle );
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_handle = INVALID_HANDLE_VALUE;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_file_read( FH  f,  void*  buf, int   len )
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DWORD  read_bytes;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) {
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_read: could not read %d bytes from %s\n", len, f->name );
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EIO;
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (read_bytes < (DWORD)len) {
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->eof = 1;
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (int)read_bytes;
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_file_write( FH  f,  const void*  buf, int   len )
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DWORD  wrote_bytes;
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) {
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_file_write: could not write %d bytes from %s\n", len, f->name );
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EIO;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else if (wrote_bytes < (DWORD)len) {
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->eof = 1;
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  (int)wrote_bytes;
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_file_lseek( FH  f, int  pos, int  origin )
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DWORD  method;
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DWORD  result;
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (origin)
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case SEEK_SET:  method = FILE_BEGIN; break;
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case SEEK_CUR:  method = FILE_CURRENT; break;
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case SEEK_END:  method = FILE_END; break;
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EINVAL;
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    result = SetFilePointer( f->fh_handle, pos, NULL, method );
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (result == INVALID_SET_FILE_POINTER) {
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EIO;
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->eof = 0;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (int)result;
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_file_hook( FH  f, int  event, EventHook  eventhook );  /* forward */
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const FHClassRec  _fh_file_class =
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_file_init,
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_file_close,
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_file_lseek,
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_file_read,
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_file_write,
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_file_hook
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    file-based descriptor handling                              *****/
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_open(const char*  path, int  options)
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f;
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DWORD  desiredAccess       = 0;
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DWORD  shareMode           = FILE_SHARE_READ | FILE_SHARE_WRITE;
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (options) {
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case O_RDONLY:
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            desiredAccess = GENERIC_READ;
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case O_WRONLY:
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            desiredAccess = GENERIC_WRITE;
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        case O_RDWR:
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            desiredAccess = GENERIC_READ | GENERIC_WRITE;
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        default:
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D("adb_open: invalid options (0x%0x)\n", options);
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EINVAL;
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f = _fh_alloc( &_fh_file_class );
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !f ) {
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = ENOMEM;
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_handle = CreateFile( path, desiredAccess, shareMode, NULL, OPEN_EXISTING,
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                               0, NULL );
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_open: could not open '%s':", path );
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (GetLastError()) {
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case ERROR_FILE_NOT_FOUND:
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "file not found\n" );
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                errno = ENOENT;
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case ERROR_PATH_NOT_FOUND:
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "path not found\n" );
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                errno = ENOTDIR;
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            default:
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "unknown error\n" );
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                errno = ENOENT;
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_open: '%s' => fd %d\n", path, _fh_to_int(f) );
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* ignore mode on Win32 */
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_creat(const char*  path, int  mode)
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f;
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f = _fh_alloc( &_fh_file_class );
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !f ) {
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = ENOMEM;
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_handle = CreateFile( path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                               NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                               NULL );
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_creat: could not open '%s':", path );
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        switch (GetLastError()) {
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case ERROR_FILE_NOT_FOUND:
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "file not found\n" );
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                errno = ENOENT;
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            case ERROR_PATH_NOT_FOUND:
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "path not found\n" );
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                errno = ENOTDIR;
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            default:
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "unknown error\n" );
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                errno = ENOENT;
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return -1;
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_creat: '%s' => fd %d\n", path, _fh_to_int(f) );
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_read(int  fd, void* buf, int len)
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH     f = _fh_from_int(fd);
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (f == NULL) {
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return f->clazz->_fh_read( f, buf, len );
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_write(int  fd, const void*  buf, int  len)
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH     f = _fh_from_int(fd);
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (f == NULL) {
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return f->clazz->_fh_write(f, buf, len);
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_lseek(int  fd, int  pos, int  where)
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH     f = _fh_from_int(fd);
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f) {
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return f->clazz->_fh_lseek(f, pos, where);
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_close(int  fd)
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   f = _fh_from_int(fd);
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f) {
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_close: %s\n", f->name);
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_close(f);
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    socket-based file descriptors                               *****/
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_socket_set_errno( void )
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (WSAGetLastError()) {
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0:              errno = 0; break;
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case WSAEWOULDBLOCK: errno = EAGAIN; break;
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case WSAEINTR:       errno = EINTR; break;
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default:
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "_socket_set_errno: unhandled value %d\n", WSAGetLastError() );
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EINVAL;
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_init( FH  f )
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = INVALID_SOCKET;
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->event     = WSACreateEvent();
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->mask      = 0;
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_close( FH  f )
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* gently tell any peer that we're closing the socket */
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    shutdown( f->fh_socket, SD_BOTH );
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    closesocket( f->fh_socket );
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = INVALID_SOCKET;
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( f->event );
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->mask = 0;
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_lseek( FH  f, int pos, int origin )
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    errno = EPIPE;
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_read( FH  f, void*  buf, int  len )
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  result = recv( f->fh_socket, buf, len, 0 );
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (result == SOCKET_ERROR) {
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _socket_set_errno();
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        result = -1;
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  result;
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_write( FH  f, const void*  buf, int  len )
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  result = send( f->fh_socket, buf, len, 0 );
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (result == SOCKET_ERROR) {
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _socket_set_errno();
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        result = -1;
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return result;
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_socket_hook( FH  f, int  event, EventHook  hook );  /* forward */
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const FHClassRec  _fh_socket_class =
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_init,
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_close,
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_lseek,
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_read,
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_write,
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_hook
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    replacement for libs/cutils/socket_xxxx.c                   *****/
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <winsock2.h>
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int  _winsock_init;
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_cleanup_winsock( void )
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    WSACleanup();
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_init_winsock( void )
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init) {
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        WSADATA  wsaData;
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int      rc = WSAStartup( MAKEWORD(2,2), &wsaData);
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (rc != 0) {
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fatal( "adb: could not initialize Winsock\n" );
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        atexit( _cleanup_winsock );
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _winsock_init = 1;
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_loopback_client(int port, int type)
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f = _fh_alloc( &_fh_socket_class );
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET  s;
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f)
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = AF_INET;
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(AF_INET, type, 0);
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) {
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("socket_loopback_client: could not create socket\n" );
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("socket_loopback_client: could not connect to %s:%d\n", type != SOCK_STREAM ? "udp" : "tcp", port );
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "socket_loopback_client: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LISTEN_BACKLOG 4
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_loopback_server(int port, int type)
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   f = _fh_alloc( &_fh_socket_class );
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET  s;
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  n;
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f) {
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = AF_INET;
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(AF_INET, type, 0);
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) return -1;
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    n = 1;
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (type == SOCK_STREAM) {
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret;
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = listen(s, LISTEN_BACKLOG);
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret < 0) {
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            _fh_close(f);
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(lo-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "socket_loopback_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_network_client(const char *host, int port, int type)
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f = _fh_alloc( &_fh_socket_class );
651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct hostent *hp;
652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET s;
654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f)
656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hp = gethostbyname(host);
662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(hp == 0) {
663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = hp->h_addrtype;
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(hp->h_addrtype, type, 0);
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) {
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "socket_network_client: host '%s' port %d type %s => fd %d\n", host, port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_inaddr_any_server(int port, int type)
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f = _fh_alloc( &_fh_socket_class );
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET  s;
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int n;
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f)
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = AF_INET;
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_addr.s_addr = htonl(INADDR_ANY);
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(AF_INET, type, 0);
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) {
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    n = 1;
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (type == SOCK_STREAM) {
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret;
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = listen(s, LISTEN_BACKLOG);
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret < 0) {
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            _fh_close(f);
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(any-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "socket_inaddr_server: port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp", _fh_to_int(f) );
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef accept
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen)
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   serverfh = _fh_from_int(serverfd);
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   fh;
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_socket_accept: invalid fd %d\n", serverfd );
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fh = _fh_alloc( &_fh_socket_class );
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!fh) {
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" );
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen );
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fh->fh_socket == INVALID_SOCKET) {
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close( fh );
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() );
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name );
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) );
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  _fh_to_int(fh);
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid  disable_tcp_nagle(int fd)
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   fh = _fh_from_int(fd);
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  on;
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !fh || fh->clazz != &_fh_socket_class )
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    setsockopt( fh->fh_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on) );
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    emulated socketpairs                                       *****/
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* we implement socketpairs directly in use space for the following reasons:
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   - it avoids copying data from/to the Nt kernel
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   - it allows us to implement fdevent hooks easily and cheaply, something
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *     that is not possible with standard Win32 pipes !!
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * basically, we use two circular buffers, each one corresponding to a given
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * direction.
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * each buffer is implemented as two regions:
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   region A which is (a_start,a_end)
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   region B which is (0, b_end)  with b_end <= a_start
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * an empty buffer has:  a_start = a_end = b_end = 0
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a_start is the pointer where we start reading data
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE,
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * then you start writing at b_end
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the buffer is full when  b_end == a_start && a_end == BUFFER_SIZE
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * there is room when b_end < a_start || a_end < BUFER_SIZE
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * when reading, a_start is incremented, it a_start meets a_end, then
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * we do:  a_start = 0, a_end = b_end, b_end = 0, and keep going on..
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  BIP_BUFFER_SIZE   4096
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPD(x)      D x
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPDUMP   bip_dump_hex
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  bip_dump_hex( const unsigned char*  ptr, size_t  len )
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  nn, len2 = len;
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len2 > 8) len2 = 8;
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (nn = 0; nn < len2; nn++)
827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("%02x", ptr[nn]);
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("  ");
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (nn = 0; nn < len2; nn++) {
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  c = ptr[nn];
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (c < 32 || c > 127)
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            c = '.';
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("%c", c);
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("\n");
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fflush(stdout);
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPD(x)        do {} while (0)
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPDUMP(p,l)   BIPD(p)
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct BipBufferRec_
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                a_start;
848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                a_end;
849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                b_end;
850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                fdin;
851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                fdout;
852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                closed;
853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                can_write;  /* boolean */
854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE             evt_write;  /* event signaled when one can write to a buffer  */
855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                can_read;   /* boolean */
856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE             evt_read;   /* event signaled when one can read from a buffer */
857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CRITICAL_SECTION  lock;
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char      buff[ BIP_BUFFER_SIZE ];
859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} BipBufferRec, *BipBuffer;
861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_init( BipBuffer  buffer )
864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "bit_buffer_init %p\n", buffer );
866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->a_start   = 0;
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->a_end     = 0;
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->b_end     = 0;
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->can_write = 1;
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->can_read  = 0;
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->fdin      = 0;
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->fdout     = 0;
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->closed    = 0;
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL );
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->evt_read  = CreateEvent( NULL, TRUE, FALSE, NULL );
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    InitializeCriticalSection( &buffer->lock );
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_close( BipBuffer  bip )
881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->closed = 1;
883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!bip->can_read) {
885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_read );
886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!bip->can_write) {
888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_write );
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_done( BipBuffer  bip )
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout ));
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( bip->evt_read );
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( bip->evt_write );
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DeleteCriticalSection( &bip->lock );
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_write( BipBuffer  bip, const void* src, int  len )
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  avail, count = 0;
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len <= 0)
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPDUMP( src, len );
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EnterCriticalSection( &bip->lock );
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (!bip->can_write) {
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  ret;
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LeaveCriticalSection( &bip->lock );
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* spinlocking here is probably unfair, but let's live with it */
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = WaitForSingleObject( bip->evt_write, INFINITE );
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != WAIT_OBJECT_0) {  /* buffer probably closed */
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() );
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        EnterCriticalSection( &bip->lock );
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = BIP_BUFFER_SIZE - bip->a_end;
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > 0)
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* we can append to region A */
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (avail > len)
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            avail = len;
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy( bip->buff + bip->a_end, src, avail );
945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        src   += avail;
946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count += avail;
947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len   -= avail;
948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->a_end += avail;
950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) {
951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip->can_write = 0;
952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ResetEvent( bip->evt_write );
953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto Exit;
954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len == 0)
958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Exit;
959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = bip->a_start - bip->b_end;
961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( avail > 0 );  /* since can_write is TRUE */
962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > len)
964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        avail = len;
965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy( bip->buff + bip->b_end, src, avail );
967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    count += avail;
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->b_end += avail;
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (bip->b_end == bip->a_start) {
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->can_write = 0;
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ResetEvent( bip->evt_write );
973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectExit:
976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( count > 0 );
977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !bip->can_read ) {
979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->can_read = 1;
980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_read );
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LeaveCriticalSection( &bip->lock );
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return count;
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project }
989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_read( BipBuffer  bip, void*  dst, int  len )
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  avail, count = 0;
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len <= 0)
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EnterCriticalSection( &bip->lock );
1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while ( !bip->can_read )
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LeaveCriticalSection( &bip->lock );
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EAGAIN;
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  ret;
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LeaveCriticalSection( &bip->lock );
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = WaitForSingleObject( bip->evt_read, INFINITE );
1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != WAIT_OBJECT_0) { /* probably closed buffer */
1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError());
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        EnterCriticalSection( &bip->lock );
1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = bip->a_end - bip->a_start;
1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( avail > 0 );  /* since can_read is TRUE */
1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > len)
1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        avail = len;
1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy( dst, bip->buff + bip->a_start, avail );
1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst   += avail;
1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    count += avail;
1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len   -= avail;
1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->a_start += avail;
1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (bip->a_start < bip->a_end)
1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Exit;
1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->a_start = 0;
1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->a_end   = bip->b_end;
1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->b_end   = 0;
1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = bip->a_end;
1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > 0) {
1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (avail > len)
1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            avail = len;
1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy( dst, bip->buff, avail );
1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count += avail;
1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->a_start += avail;
1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( bip->a_start < bip->a_end )
1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto Exit;
1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->a_start = bip->a_end = 0;
1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->can_read = 0;
1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ResetEvent( bip->evt_read );
1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectExit:
1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( count > 0 );
1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!bip->can_write ) {
1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->can_write = 1;
1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_write );
1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPDUMP( (const unsigned char*)dst - count, count );
1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LeaveCriticalSection( &bip->lock );
1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1080dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return count;
1081dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1083dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct SocketPairRec_
1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBufferRec  a2b_bip;
1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBufferRec  b2a_bip;
1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH            a_fd;
1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int           used;
1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} SocketPairRec;
1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid _fh_socketpair_init( FH  f )
1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_pair = NULL;
1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_close( FH  f )
1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f->fh_pair ) {
1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SocketPair  pair = f->fh_pair;
1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( f == pair->a_fd ) {
1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pair->a_fd = NULL;
1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip_buffer_close( &pair->b2a_bip );
1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip_buffer_close( &pair->a2b_bip );
1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( --pair->used == 0 ) {
1111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip_buffer_done( &pair->b2a_bip );
1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip_buffer_done( &pair->a2b_bip );
1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free( pair );
1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->fh_pair = NULL;
1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_lseek( FH  f, int pos, int  origin )
1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    errno = ESPIPE;
1124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
1125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_read( FH  f, void* buf, int  len )
1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair = f->fh_pair;
1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   bip;
1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pair)
1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f == pair->a_fd )
1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->b2a_bip;
1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->a2b_bip;
1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return bip_buffer_read( bip, buf, len );
1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_write( FH  f, const void*  buf, int  len )
1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair = f->fh_pair;
1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   bip;
1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pair)
1151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
1152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f == pair->a_fd )
1154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->a2b_bip;
1155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
1156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->b2a_bip;
1157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return bip_buffer_write( bip, buf, len );
1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_socketpair_hook( FH  f, int  event, EventHook  hook );  /* forward */
1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const FHClassRec  _fh_socketpair_class =
1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_init,
1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_close,
1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_lseek,
1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_read,
1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_write,
1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_hook
1172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
1173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_socketpair( int  sv[2] )
1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH          fa, fb;
1178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair;
1179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fa = _fh_alloc( &_fh_socketpair_class );
1181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fb = _fh_alloc( &_fh_socketpair_class );
1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!fa || !fb)
1184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Fail;
1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair = malloc( sizeof(*pair) );
1187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (pair == NULL) {
1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("adb_socketpair: not enough memory to allocate pipes\n" );
1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Fail;
1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip_buffer_init( &pair->a2b_bip );
1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip_buffer_init( &pair->b2a_bip );
1194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fa->fh_pair = pair;
1196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fb->fh_pair = pair;
1197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->used  = 2;
1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->a_fd  = fa;
1199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sv[0] = _fh_to_int(fa);
1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sv[1] = _fh_to_int(fb);
1202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->a2b_bip.fdin  = sv[0];
1204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->a2b_bip.fdout = sv[1];
1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->b2a_bip.fdin  = sv[1];
1206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->b2a_bip.fdout = sv[0];
1207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );
1209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );
1210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] );
1211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
1212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectFail:
1214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_close(fb);
1215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_close(fa);
1216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
1222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    fdevents emulation                                          *****/
1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****   this is a very simple implementation, we rely on the fact    *****/
1225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****   that ADB doesn't use FDE_ERROR.                              *****/
1226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
1227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FATAL(x...) fatal(__FUNCTION__, x)
1231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if DEBUG
1233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dump_fde(fdevent *fde, const char *info)
1234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
1236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state & FDE_READ ? 'R' : ' ',
1237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state & FDE_WRITE ? 'W' : ' ',
1238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state & FDE_ERROR ? 'E' : ' ',
1239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            info);
1240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
1242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define dump_fde(fde, info) do { } while(0)
1243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_EVENTMASK  0x00ff
1246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_STATEMASK  0xff00
1247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_ACTIVE     0x0100
1249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_PENDING    0x0200
1250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_CREATED    0x0400
1251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_enqueue(fdevent *node);
1253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_remove(fdevent *node);
1254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent *fdevent_plist_dequeue(void);
1255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent list_pending = {
1257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    .next = &list_pending,
1258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    .prev = &list_pending,
1259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
1260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent **fd_table = 0;
1262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int       fd_table_max = 0;
1263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct EventLooperRec_*  EventLooper;
1265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct EventHookRec_
1267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook    next;
1269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH           fh;
1270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE       h;
1271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          wanted;   /* wanted event flags */
1272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          ready;    /* ready event flags  */
1273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void*        aux;
1274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void        (*prepare)( EventHook  hook );
1275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int         (*start)  ( EventHook  hook );
1276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void        (*stop)   ( EventHook  hook );
1277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int         (*check)  ( EventHook  hook );
1278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int         (*peek)   ( EventHook  hook );
1279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} EventHookRec;
1280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventHook  _free_hooks;
1282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventHook
1284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectevent_hook_alloc( FH  fh )
1285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook  hook = _free_hooks;
1287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hook != NULL)
1288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _free_hooks = hook->next;
1289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else {
1290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook = malloc( sizeof(*hook) );
1291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook == NULL)
1292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fatal( "could not allocate event hook\n" );
1293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->next   = NULL;
1295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->fh     = fh;
1296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->wanted = 0;
1297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->ready  = 0;
1298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->h      = INVALID_HANDLE_VALUE;
1299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->aux    = NULL;
1300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->prepare = NULL;
1302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->start   = NULL;
1303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->stop    = NULL;
1304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->check   = NULL;
1305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->peek    = NULL;
1306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return hook;
1308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectevent_hook_free( EventHook  hook )
1312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->fh     = NULL;
1314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->wanted = 0;
1315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->ready  = 0;
1316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->next   = _free_hooks;
1317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _free_hooks  = hook;
1318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectevent_hook_signal( EventHook  hook )
1323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH        f   = hook->fh;
1325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int       fd  = _fh_to_int(f);
1326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent*  fde = fd_table[ fd - WIN32_FH_BASE ];
1327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fde != NULL && fde->fd == fd) {
1329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((fde->state & FDE_PENDING) == 0) {
1330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state |= FDE_PENDING;
1331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fdevent_plist_enqueue( fde );
1332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fde->events |= hook->wanted;
1334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  MAX_LOOPER_HANDLES  WIN32_MAX_FHS
1339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct EventLooperRec_
1341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook    hooks;
1343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE       htab[ MAX_LOOPER_HANDLES ];
1344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          htab_count;
1345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} EventLooperRec;
1347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventHook*
1349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectevent_looper_find_p( EventLooper  looper, FH  fh )
1350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook  *pnode = &looper->hooks;
1352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook   node  = *pnode;
1353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (;;) {
1354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( node == NULL || node->fh == fh )
1355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            break;
1356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        pnode = &node->next;
1357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node  = *pnode;
1358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  pnode;
1360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectevent_looper_hook( EventLooper  looper, int  fd, int  events )
1364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH          f = _fh_from_int(fd);
1366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook  *pnode;
1367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook   node;
1368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (f == NULL)  /* invalid arg */ {
1370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("event_looper_hook: invalid fd=%d\n", fd);
1371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
1372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pnode = event_looper_find_p( looper, f );
1375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node  = *pnode;
1376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( node == NULL ) {
1377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node       = event_hook_alloc( f );
1378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node->next = *pnode;
1379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *pnode     = node;
1380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( (node->wanted & events) != events ) {
1383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* this should update start/stop/check/peek */
1384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("event_looper_hook: call hook for %d (new=%x, old=%x)\n",
1385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project           fd, node->wanted, events);
1386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->clazz->_fh_hook( f, events & ~node->wanted, node );
1387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node->wanted |= events;
1388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
1389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("event_looper_hook: ignoring events %x for %d wanted=%x)\n",
1390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project           events, fd, node->wanted);
1391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectevent_looper_unhook( EventLooper  looper, int  fd, int  events )
1396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH          fh    = _fh_from_int(fd);
1398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook  *pnode = event_looper_find_p( looper, fh );
1399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook   node  = *pnode;
1400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (node != NULL) {
1402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  events2 = events & node->wanted;
1403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( events2 == 0 ) {
1404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd );
1405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return;
1406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        node->wanted &= ~events2;
1408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (!node->wanted) {
1409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            *pnode = node->next;
1410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            event_hook_free( node );
1411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventLooperRec  win32_looper;
1416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_init(void)
1418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    win32_looper.htab_count = 0;
1420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    win32_looper.hooks      = NULL;
1421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_connect(fdevent *fde)
1424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventLooper  looper = &win32_looper;
1426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          events = fde->state & FDE_EVENTMASK;
1427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (events != 0)
1429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        event_looper_hook( looper, fde->fd, events );
1430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_disconnect(fdevent *fde)
1433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventLooper  looper = &win32_looper;
1435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          events = fde->state & FDE_EVENTMASK;
1436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (events != 0)
1438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        event_looper_unhook( looper, fde->fd, events );
1439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_update(fdevent *fde, unsigned events)
1442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventLooper  looper  = &win32_looper;
1444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned     events0 = fde->state & FDE_EVENTMASK;
1445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (events != events0) {
1447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  removes = events0 & ~events;
1448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  adds    = events  & ~events0;
1449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (removes) {
1450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D("fdevent_update: remove %x from %d\n", removes, fde->fd);
1451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            event_looper_unhook( looper, fde->fd, removes );
1452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (adds) {
1454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D("fdevent_update: add %x to %d\n", adds, fde->fd);
1455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            event_looper_hook  ( looper, fde->fd, adds );
1456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_process()
1461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventLooper  looper = &win32_looper;
1463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook    hook;
1464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          gotone = 0;
1465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* if we have at least one ready hook, execute it/them */
1467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (hook = looper->hooks; hook; hook = hook->next) {
1468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook->ready = 0;
1469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook->prepare) {
1470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hook->prepare(hook);
1471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (hook->ready != 0) {
1472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                event_hook_signal( hook );
1473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                gotone = 1;
1474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* nothing's ready yet, so wait for something to happen */
1479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!gotone)
1480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
1481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        looper->htab_count = 0;
1482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (hook = looper->hooks; hook; hook = hook->next)
1484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        {
1485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (hook->start && !hook->start(hook)) {
1486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "fdevent_process: error when starting a hook\n" );
1487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return;
1488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (hook->h != INVALID_HANDLE_VALUE) {
1490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                int  nn;
1491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                for (nn = 0; nn < looper->htab_count; nn++)
1493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                {
1494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    if ( looper->htab[nn] == hook->h )
1495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        goto DontAdd;
1496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
1497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                looper->htab[ looper->htab_count++ ] = hook->h;
1498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DontAdd:
1499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                ;
1500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (looper->htab_count == 0) {
1504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "fdevent_process: nothing to wait for !!\n" );
1505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return;
1506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        do
1509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        {
1510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            int   wait_ret;
1511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "adb_win32: waiting for %d events\n", looper->htab_count );
1513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) {
1514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS, aborting!\n", looper->htab_count);
1515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                abort();
1516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE );
1518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (wait_ret == (int)WAIT_FAILED) {
1519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "adb_win32: wait failed, error %ld\n", GetLastError() );
1520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            } else {
1521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                D( "adb_win32: got one (index %d)\n", wait_ret );
1522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                /* according to Cygwin, some objects like consoles wake up on "inappropriate" events
1524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                 * like mouse movements. we need to filter these with the "check" function
1525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                 */
1526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                if ((unsigned)wait_ret < (unsigned)looper->htab_count)
1527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                {
1528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    for (hook = looper->hooks; hook; hook = hook->next)
1529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    {
1530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        if ( looper->htab[wait_ret] == hook->h       &&
1531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                         (!hook->check || hook->check(hook)) )
1532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        {
1533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready );
1534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            event_hook_signal( hook );
1535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            gotone = 1;
1536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                            break;
1537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                        }
1538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    }
1539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                }
1540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
1541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while (!gotone);
1543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        for (hook = looper->hooks; hook; hook = hook->next) {
1545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (hook->stop)
1546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                hook->stop( hook );
1547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (hook = looper->hooks; hook; hook = hook->next) {
1551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook->peek && hook->peek(hook))
1552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                event_hook_signal( hook );
1553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_register(fdevent *fde)
1558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  fd = fde->fd - WIN32_FH_BASE;
1560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd < 0) {
1562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        FATAL("bogus negative fd (%d)\n", fde->fd);
1563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd >= fd_table_max) {
1566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int oldmax = fd_table_max;
1567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(fde->fd > 32000) {
1568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            FATAL("bogus huuuuge fd (%d)\n", fde->fd);
1569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(fd_table_max == 0) {
1571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fdevent_init();
1572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fd_table_max = 256;
1573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while(fd_table_max <= fd) {
1575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fd_table_max *= 2;
1576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fd_table = realloc(fd_table, sizeof(fdevent*) * fd_table_max);
1578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(fd_table == 0) {
1579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            FATAL("could not expand fd_table to %d entries\n", fd_table_max);
1580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
1582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd_table[fd] = fde;
1585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_unregister(fdevent *fde)
1588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  fd = fde->fd - WIN32_FH_BASE;
1590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((fd < 0) || (fd >= fd_table_max)) {
1592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        FATAL("fd out of range (%d)\n", fde->fd);
1593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fd_table[fd] != fde) {
1596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        FATAL("fd_table out of sync");
1597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fd_table[fd] = 0;
1600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!(fde->state & FDE_DONT_CLOSE)) {
1602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dump_fde(fde, "close");
1603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        adb_close(fde->fd);
1604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_enqueue(fdevent *node)
1608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent *list = &list_pending;
1610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->next = list;
1612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->prev = list->prev;
1613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->prev->next = node;
1614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list->prev = node;
1615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_remove(fdevent *node)
1618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->prev->next = node->next;
1620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->next->prev = node->prev;
1621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->next = 0;
1622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->prev = 0;
1623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent *fdevent_plist_dequeue(void)
1626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent *list = &list_pending;
1628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent *node = list->next;
1629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(node == list) return 0;
1631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list->next = node->next;
1633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    list->next->prev = list;
1634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->next = 0;
1635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    node->prev = 0;
1636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return node;
1638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectfdevent *fdevent_create(int fd, fd_func func, void *arg)
1641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
1643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fde == 0) return 0;
1644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent_install(fde, fd, func, arg);
1645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->state |= FDE_CREATED;
1646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return fde;
1647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_destroy(fdevent *fde)
1650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fde == 0) return;
1652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(!(fde->state & FDE_CREATED)) {
1653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        FATAL("fde %p not created by fdevent_create()\n", fde);
1654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent_remove(fde);
1656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
1659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(fde, 0, sizeof(fdevent));
1661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->state = FDE_ACTIVE;
1662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->fd = fd;
1663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->func = func;
1664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->arg = arg;
1665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent_register(fde);
1667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dump_fde(fde, "connect");
1668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent_connect(fde);
1669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->state |= FDE_ACTIVE;
1670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_remove(fdevent *fde)
1673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fde->state & FDE_PENDING) {
1675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fdevent_plist_remove(fde);
1676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fde->state & FDE_ACTIVE) {
1679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fdevent_disconnect(fde);
1680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dump_fde(fde, "disconnect");
1681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fdevent_unregister(fde);
1682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->state = 0;
1685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->events = 0;
1686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_set(fdevent *fde, unsigned events)
1690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    events &= FDE_EVENTMASK;
1692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if((fde->state & FDE_EVENTMASK) == (int)events) return;
1694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fde->state & FDE_ACTIVE) {
1696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fdevent_update(fde, events);
1697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        dump_fde(fde, "update");
1698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fde->state = (fde->state & FDE_STATEMASK) | events;
1701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(fde->state & FDE_PENDING) {
1703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            /* if we're pending, make sure
1704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ** we don't signal an event that
1705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ** is no longer wanted.
1706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            */
1707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fde->events &= (~events);
1708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if(fde->events == 0) {
1709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fdevent_plist_remove(fde);
1710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state &= (~FDE_PENDING);
1711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_add(fdevent *fde, unsigned events)
1716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent_set(
1718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
1719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_del(fdevent *fde, unsigned events)
1722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent_set(
1724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
1725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid fdevent_loop()
1728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fdevent *fde;
1730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for(;;) {
1732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if DEBUG
1733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fprintf(stderr,"--- ---- waiting for events\n");
1734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fdevent_process();
1736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        while((fde = fdevent_plist_dequeue())) {
1738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            unsigned events = fde->events;
1739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->events = 0;
1740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state &= (~FDE_PENDING);
1741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            dump_fde(fde, "callback");
1742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->func(fde->fd, events, fde->arg);
1743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**  FILE EVENT HOOKS
1748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project **/
1749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _event_file_prepare( EventHook  hook )
1751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hook->wanted & (FDE_READ|FDE_WRITE)) {
1753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* we can always read/write */
1754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE);
1755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int  _event_file_peek( EventHook  hook )
1759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return (hook->wanted & (FDE_READ|FDE_WRITE));
1761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_file_hook( FH  f, int  events, EventHook  hook )
1764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->h       = f->fh_handle;
1766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->prepare = _event_file_prepare;
1767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->peek    = _event_file_peek;
1768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** SOCKET EVENT HOOKS
1771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project **/
1772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _event_socket_verify( EventHook  hook, WSANETWORKEVENTS*  evts )
1774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) {
1776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook->wanted & FDE_READ)
1777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hook->ready |= FDE_READ;
1778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR)
1779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hook->ready |= FDE_ERROR;
1780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) {
1782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook->wanted & FDE_WRITE)
1783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hook->ready |= FDE_WRITE;
1784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR)
1785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hook->ready |= FDE_ERROR;
1786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( evts->lNetworkEvents & FD_OOB ) {
1788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook->wanted & FDE_ERROR)
1789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hook->ready |= FDE_ERROR;
1790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _event_socket_prepare( EventHook  hook )
1794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    WSANETWORKEVENTS  evts;
1796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* look if some of the events we want already happened ? */
1798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts ))
1799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _event_socket_verify( hook, &evts );
1800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int  _socket_wanted_to_flags( int  wanted )
1803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  flags = 0;
1805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (wanted & FDE_READ)
1806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        flags |= FD_READ | FD_ACCEPT | FD_CLOSE;
1807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (wanted & FDE_WRITE)
1809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        flags |= FD_WRITE | FD_CONNECT | FD_CLOSE;
1810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (wanted & FDE_ERROR)
1812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        flags |= FD_OOB;
1813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return flags;
1815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int _event_socket_start( EventHook  hook )
1818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* create an event which we're going to wait for */
1820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH    fh    = hook->fh;
1821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    long  flags = _socket_wanted_to_flags( hook->wanted );
1822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->h = fh->event;
1824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hook->h == INVALID_HANDLE_VALUE) {
1825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "_event_socket_start: no event for %s\n", fh->name );
1826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( flags != fh->mask ) {
1830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags );
1831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) {
1832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() );
1833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            CloseHandle( hook->h );
1834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            hook->h = INVALID_HANDLE_VALUE;
1835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            exit(1);
1836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
1837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        fh->mask = flags;
1839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 1;
1841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void _event_socket_stop( EventHook  hook )
1844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->h = INVALID_HANDLE_VALUE;
1846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int  _event_socket_check( EventHook  hook )
1849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int               result = 0;
1851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH                fh = hook->fh;
1852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    WSANETWORKEVENTS  evts;
1853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) {
1855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _event_socket_verify( hook, &evts );
1856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        result = (hook->ready != 0);
1857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (result) {
1858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ResetEvent( hook->h );
1859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "_event_socket_check %s returns %d\n", fh->name, result );
1862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  result;
1863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int  _event_socket_peek( EventHook  hook )
1866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    WSANETWORKEVENTS  evts;
1868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH                fh = hook->fh;
1869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* look if some of the events we want already happened ? */
1871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) {
1872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _event_socket_verify( hook, &evts );
1873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook->ready)
1874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ResetEvent( hook->h );
1875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return hook->ready != 0;
1878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_socket_hook( FH  f, int  events, EventHook  hook )
1883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->prepare = _event_socket_prepare;
1885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->start   = _event_socket_start;
1886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->stop    = _event_socket_stop;
1887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->check   = _event_socket_check;
1888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->peek    = _event_socket_peek;
1889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _event_socket_start( hook );
1891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/** SOCKETPAIR EVENT HOOKS
1894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project **/
1895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _event_socketpair_prepare( EventHook  hook )
1897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH          fh   = hook->fh;
1899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair = fh->fh_pair;
1900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
1901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
1902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hook->wanted & FDE_READ && rbip->can_read)
1904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook->ready |= FDE_READ;
1905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hook->wanted & FDE_WRITE && wbip->can_write)
1907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook->ready |= FDE_WRITE;
1908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project }
1909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project static int  _event_socketpair_start( EventHook  hook )
1911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project {
1912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH          fh   = hook->fh;
1913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair = fh->fh_pair;
1914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
1915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
1916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hook->wanted == FDE_READ)
1918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook->h = rbip->evt_read;
1919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else if (hook->wanted == FDE_WRITE)
1921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook->h = wbip->evt_write;
1922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else {
1924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" );
1925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "_event_socketpair_start: hook %s for %x wanted=%x\n",
1928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project       hook->fh->name, _fh_to_int(fh), hook->wanted);
1929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 1;
1930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int  _event_socketpair_peek( EventHook  hook )
1933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _event_socketpair_prepare( hook );
1935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return hook->ready != 0;
1936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_socketpair_hook( FH  fh, int  events, EventHook  hook )
1939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->prepare = _event_socketpair_prepare;
1941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->start   = _event_socketpair_start;
1942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hook->peek    = _event_socketpair_peek;
1943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
1947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectadb_sysdeps_init( void )
1948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  ADB_MUTEX(x)  InitializeCriticalSection( & x );
1950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "mutex_list.h"
1951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    InitializeCriticalSection( &_win32_lock );
1952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1954