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    }
355ce48083fc90cee807dd66608e2c3e496145af9ffVladimir Chtchetkine
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
4388cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwoodint  adb_shutdown(int  fd)
4398cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood{
4408cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood    FH   f = _fh_from_int(fd);
4418cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood
4428cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood    if (!f) {
4438cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood        return -1;
4448cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood    }
4458cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood
4468cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood    D( "adb_shutdown: %s\n", f->name);
4478cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood    shutdown( f->fh_socket, SD_BOTH );
4488cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood    return 0;
4498cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood}
4508cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood
4518cf0d59f61ae0b8554ecf3fe051850508b761b79Mike Lockwood
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_close(int  fd)
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   f = _fh_from_int(fd);
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f) {
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_close: %s\n", f->name);
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_close(f);
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    socket-based file descriptors                               *****/
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_socket_set_errno( void )
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    switch (WSAGetLastError()) {
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case 0:              errno = 0; break;
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case WSAEWOULDBLOCK: errno = EAGAIN; break;
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    case WSAEINTR:       errno = EINTR; break;
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    default:
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "_socket_set_errno: unhandled value %d\n", WSAGetLastError() );
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EINVAL;
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_init( FH  f )
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = INVALID_SOCKET;
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->event     = WSACreateEvent();
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->mask      = 0;
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_close( FH  f )
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* gently tell any peer that we're closing the socket */
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    shutdown( f->fh_socket, SD_BOTH );
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    closesocket( f->fh_socket );
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = INVALID_SOCKET;
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( f->event );
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->mask = 0;
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_lseek( FH  f, int pos, int origin )
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    errno = EPIPE;
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_read( FH  f, void*  buf, int  len )
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  result = recv( f->fh_socket, buf, len, 0 );
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (result == SOCKET_ERROR) {
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _socket_set_errno();
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        result = -1;
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  result;
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socket_write( FH  f, const void*  buf, int  len )
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  result = send( f->fh_socket, buf, len, 0 );
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (result == SOCKET_ERROR) {
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _socket_set_errno();
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        result = -1;
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return result;
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_socket_hook( FH  f, int  event, EventHook  hook );  /* forward */
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const FHClassRec  _fh_socket_class =
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_init,
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_close,
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_lseek,
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_read,
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_write,
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socket_hook
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    replacement for libs/cutils/socket_xxxx.c                   *****/
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <winsock2.h>
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int  _winsock_init;
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_cleanup_winsock( void )
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    WSACleanup();
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_init_winsock( void )
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init) {
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        WSADATA  wsaData;
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int      rc = WSAStartup( MAKEWORD(2,2), &wsaData);
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (rc != 0) {
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fatal( "adb: could not initialize Winsock\n" );
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        atexit( _cleanup_winsock );
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _winsock_init = 1;
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_loopback_client(int port, int type)
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f = _fh_alloc( &_fh_socket_class );
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET  s;
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f)
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = AF_INET;
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(AF_INET, type, 0);
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) {
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("socket_loopback_client: could not create socket\n" );
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("socket_loopback_client: could not connect to %s:%d\n", type != SOCK_STREAM ? "udp" : "tcp", port );
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The 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) );
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define LISTEN_BACKLOG 4
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_loopback_server(int port, int type)
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   f = _fh_alloc( &_fh_socket_class );
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET  s;
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  n;
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f) {
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = AF_INET;
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(AF_INET, type, 0);
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) return -1;
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    n = 1;
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (type == SOCK_STREAM) {
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret;
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = listen(s, LISTEN_BACKLOG);
651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret < 0) {
652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            _fh_close(f);
653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(lo-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The 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) );
658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_network_client(const char *host, int port, int type)
663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f = _fh_alloc( &_fh_socket_class );
665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct hostent *hp;
666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET s;
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f)
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    hp = gethostbyname(host);
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(hp == 0) {
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = hp->h_addrtype;
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy(&addr.sin_addr, hp->h_addr, hp->h_length);
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(hp->h_addrtype, type, 0);
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) {
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The 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) );
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint socket_inaddr_any_server(int port, int type)
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH  f = _fh_alloc( &_fh_socket_class );
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    struct sockaddr_in addr;
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SOCKET  s;
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int n;
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!f)
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!_winsock_init)
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _init_winsock();
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memset(&addr, 0, sizeof(addr));
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_family = AF_INET;
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_port = htons(port);
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    addr.sin_addr.s_addr = htonl(INADDR_ANY);
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    s = socket(AF_INET, type, 0);
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(s == INVALID_SOCKET) {
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_socket = s;
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    n = 1;
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n, sizeof(n));
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close(f);
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (type == SOCK_STREAM) {
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int ret;
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = listen(s, LISTEN_BACKLOG);
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret < 0) {
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            _fh_close(f);
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( f->name, sizeof(f->name), "%d(any-server:%s%d)", _fh_to_int(f), type != SOCK_STREAM ? "udp:" : "", port );
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The 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) );
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return _fh_to_int(f);
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#undef accept
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_socket_accept(int  serverfd, struct sockaddr*  addr, socklen_t  *addrlen)
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   serverfh = _fh_from_int(serverfd);
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   fh;
756f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_socket_accept: invalid fd %d\n", serverfd );
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
761f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fh = _fh_alloc( &_fh_socket_class );
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!fh) {
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_socket_accept: not enough memory to allocate accepted socket descriptor\n" );
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen );
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (fh->fh_socket == INVALID_SOCKET) {
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _fh_close( fh );
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D( "adb_socket_accept: accept on fd %d return error %ld\n", serverfd, GetLastError() );
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
774f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", _fh_to_int(fh), serverfh->name );
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, _fh_to_int(fh) );
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return  _fh_to_int(fh);
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid  disable_tcp_nagle(int fd)
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH   fh = _fh_from_int(fd);
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  on;
785f6330a2eeb78c0971f33feee7fd1ee06472a7dbaDavid 'Digit' Turner
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !fh || fh->clazz != &_fh_socket_class )
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return;
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    setsockopt( fh->fh_socket, IPPROTO_TCP, TCP_NODELAY, (const char*)&on, sizeof(on) );
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    emulated socketpairs                                       *****/
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* we implement socketpairs directly in use space for the following reasons:
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   - it avoids copying data from/to the Nt kernel
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   - it allows us to implement fdevent hooks easily and cheaply, something
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *     that is not possible with standard Win32 pipes !!
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * basically, we use two circular buffers, each one corresponding to a given
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * direction.
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * each buffer is implemented as two regions:
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   region A which is (a_start,a_end)
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *   region B which is (0, b_end)  with b_end <= a_start
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * an empty buffer has:  a_start = a_end = b_end = 0
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a_start is the pointer where we start reading data
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE,
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * then you start writing at b_end
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * the buffer is full when  b_end == a_start && a_end == BUFFER_SIZE
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * there is room when b_end < a_start || a_end < BUFER_SIZE
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * when reading, a_start is incremented, it a_start meets a_end, then
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * we do:  a_start = 0, a_end = b_end, b_end = 0, and keep going on..
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define  BIP_BUFFER_SIZE   4096
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPD(x)      D x
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPDUMP   bip_dump_hex
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  bip_dump_hex( const unsigned char*  ptr, size_t  len )
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  nn, len2 = len;
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len2 > 8) len2 = 8;
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
840ce48083fc90cee807dd66608e2c3e496145af9ffVladimir Chtchetkine    for (nn = 0; nn < len2; nn++)
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("%02x", ptr[nn]);
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("  ");
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    for (nn = 0; nn < len2; nn++) {
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  c = ptr[nn];
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (c < 32 || c > 127)
847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            c = '.';
848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        printf("%c", c);
849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    printf("\n");
851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fflush(stdout);
852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPD(x)        do {} while (0)
856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#  define  BIPDUMP(p,l)   BIPD(p)
857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct BipBufferRec_
860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                a_start;
862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                a_end;
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                b_end;
864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                fdin;
865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                fdout;
866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                closed;
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                can_write;  /* boolean */
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE             evt_write;  /* event signaled when one can write to a buffer  */
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int                can_read;   /* boolean */
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE             evt_read;   /* event signaled when one can read from a buffer */
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CRITICAL_SECTION  lock;
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    unsigned char      buff[ BIP_BUFFER_SIZE ];
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} BipBufferRec, *BipBuffer;
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_init( BipBuffer  buffer )
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "bit_buffer_init %p\n", buffer );
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->a_start   = 0;
881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->a_end     = 0;
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->b_end     = 0;
883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->can_write = 1;
884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->can_read  = 0;
885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->fdin      = 0;
886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->fdout     = 0;
887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->closed    = 0;
888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL );
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    buffer->evt_read  = CreateEvent( NULL, TRUE, FALSE, NULL );
890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    InitializeCriticalSection( &buffer->lock );
891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_close( BipBuffer  bip )
895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->closed = 1;
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!bip->can_read) {
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_read );
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!bip->can_write) {
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_write );
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_done( BipBuffer  bip )
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout ));
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( bip->evt_read );
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    CloseHandle( bip->evt_write );
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    DeleteCriticalSection( &bip->lock );
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_write( BipBuffer  bip, const void* src, int  len )
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  avail, count = 0;
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len <= 0)
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPDUMP( src, len );
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EnterCriticalSection( &bip->lock );
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (!bip->can_write) {
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  ret;
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LeaveCriticalSection( &bip->lock );
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* spinlocking here is probably unfair, but let's live with it */
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = WaitForSingleObject( bip->evt_write, INFINITE );
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != WAIT_OBJECT_0) {  /* buffer probably closed */
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() );
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        EnterCriticalSection( &bip->lock );
947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = BIP_BUFFER_SIZE - bip->a_end;
952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > 0)
953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* we can append to region A */
955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (avail > len)
956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            avail = len;
957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy( bip->buff + bip->a_end, src, avail );
959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        src   += avail;
960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count += avail;
961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        len   -= avail;
962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->a_end += avail;
964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) {
965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip->can_write = 0;
966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            ResetEvent( bip->evt_write );
967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto Exit;
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len == 0)
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Exit;
973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = bip->a_start - bip->b_end;
975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( avail > 0 );  /* since can_write is TRUE */
976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > len)
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        avail = len;
979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy( bip->buff + bip->b_end, src, avail );
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    count += avail;
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->b_end += avail;
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (bip->b_end == bip->a_start) {
985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->can_write = 0;
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ResetEvent( bip->evt_write );
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectExit:
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( count > 0 );
991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( !bip->can_read ) {
993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->can_read = 1;
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_read );
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
997ce48083fc90cee807dd66608e2c3e496145af9ffVladimir Chtchetkine    BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LeaveCriticalSection( &bip->lock );
1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return count;
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project }
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbip_buffer_read( BipBuffer  bip, void*  dst, int  len )
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int  avail, count = 0;
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (len <= 0)
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EnterCriticalSection( &bip->lock );
1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while ( !bip->can_read )
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    {
1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LeaveCriticalSection( &bip->lock );
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        errno = EAGAIN;
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
1021ce48083fc90cee807dd66608e2c3e496145af9ffVladimir Chtchetkine#else
1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        int  ret;
1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        LeaveCriticalSection( &bip->lock );
1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        ret = WaitForSingleObject( bip->evt_read, INFINITE );
1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (ret != WAIT_OBJECT_0) { /* probably closed buffer */
1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError());
1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return 0;
1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (bip->closed) {
1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            errno = EPIPE;
1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            return -1;
1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        EnterCriticalSection( &bip->lock );
1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = bip->a_end - bip->a_start;
1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( avail > 0 );  /* since can_read is TRUE */
1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > len)
1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        avail = len;
1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    memcpy( dst, bip->buff + bip->a_start, avail );
1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    dst   += avail;
1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    count += avail;
1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    len   -= avail;
1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->a_start += avail;
1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (bip->a_start < bip->a_end)
1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Exit;
1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->a_start = 0;
1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->a_end   = bip->b_end;
1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->b_end   = 0;
1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    avail = bip->a_end;
1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (avail > 0) {
1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (avail > len)
1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            avail = len;
1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        memcpy( dst, bip->buff, avail );
1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        count += avail;
1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->a_start += avail;
1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( bip->a_start < bip->a_end )
1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            goto Exit;
1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->a_start = bip->a_end = 0;
1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip->can_read = 0;
1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    ResetEvent( bip->evt_read );
1080dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1081dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectExit:
1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    assert( count > 0 );
1083dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!bip->can_write ) {
1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip->can_write = 1;
1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SetEvent( bip->evt_write );
1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BIPDUMP( (const unsigned char*)dst - count, count );
1090ce48083fc90cee807dd66608e2c3e496145af9ffVladimir Chtchetkine    BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    LeaveCriticalSection( &bip->lock );
1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return count;
1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1097ce48083fc90cee807dd66608e2c3e496145af9ffVladimir Chtchetkinetypedef struct SocketPairRec_
1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBufferRec  a2b_bip;
1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBufferRec  b2a_bip;
1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH            a_fd;
1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int           used;
1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} SocketPairRec;
1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid _fh_socketpair_init( FH  f )
1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    f->fh_pair = NULL;
1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_close( FH  f )
1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f->fh_pair ) {
1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        SocketPair  pair = f->fh_pair;
1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( f == pair->a_fd ) {
1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            pair->a_fd = NULL;
1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip_buffer_close( &pair->b2a_bip );
1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip_buffer_close( &pair->a2b_bip );
1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if ( --pair->used == 0 ) {
1125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip_buffer_done( &pair->b2a_bip );
1126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            bip_buffer_done( &pair->a2b_bip );
1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            free( pair );
1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        f->fh_pair = NULL;
1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_lseek( FH  f, int pos, int  origin )
1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    errno = ESPIPE;
1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_read( FH  f, void* buf, int  len )
1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair = f->fh_pair;
1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   bip;
1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pair)
1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f == pair->a_fd )
1151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->b2a_bip;
1152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
1153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->a2b_bip;
1154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return bip_buffer_read( bip, buf, len );
1156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project_fh_socketpair_write( FH  f, const void*  buf, int  len )
1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair = f->fh_pair;
1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    BipBuffer   bip;
1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!pair)
1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if ( f == pair->a_fd )
1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->a2b_bip;
1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else
1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        bip = &pair->b2a_bip;
1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return bip_buffer_write( bip, buf, len );
1173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void  _fh_socketpair_hook( FH  f, int  event, EventHook  hook );  /* forward */
1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const FHClassRec  _fh_socketpair_class =
1179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_init,
1181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_close,
1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_lseek,
1183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_read,
1184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_write,
1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_socketpair_hook
1186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
1187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint  adb_socketpair( int  sv[2] )
1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH          fa, fb;
1192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    SocketPair  pair;
1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fa = _fh_alloc( &_fh_socketpair_class );
1195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fb = _fh_alloc( &_fh_socketpair_class );
1196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!fa || !fb)
1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Fail;
1199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair = malloc( sizeof(*pair) );
1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (pair == NULL) {
1202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        D("adb_socketpair: not enough memory to allocate pipes\n" );
1203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        goto Fail;
1204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip_buffer_init( &pair->a2b_bip );
1207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    bip_buffer_init( &pair->b2a_bip );
1208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fa->fh_pair = pair;
1210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fb->fh_pair = pair;
1211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->used  = 2;
1212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->a_fd  = fa;
1213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sv[0] = _fh_to_int(fa);
1215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    sv[1] = _fh_to_int(fb);
1216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->a2b_bip.fdin  = sv[0];
1218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->a2b_bip.fdout = sv[1];
1219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->b2a_bip.fdin  = sv[1];
1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    pair->b2a_bip.fdout = sv[0];
1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );
1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );
1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] );
1225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
1226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectFail:
1228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_close(fb);
1229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    _fh_close(fa);
1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1;
1231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
1236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****    fdevents emulation                                          *****/
1237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
1238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****   this is a very simple implementation, we rely on the fact    *****/
1239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****   that ADB doesn't use FDE_ERROR.                              *****/
1240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*****                                                                *****/
1241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**************************************************************************/
1243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FATAL(x...) fatal(__FUNCTION__, x)
1245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if DEBUG
1247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dump_fde(fdevent *fde, const char *info)
1248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
1250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state & FDE_READ ? 'R' : ' ',
1251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state & FDE_WRITE ? 'W' : ' ',
1252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fde->state & FDE_ERROR ? 'E' : ' ',
1253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            info);
1254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
1256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define dump_fde(fde, info) do { } while(0)
1257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_EVENTMASK  0x00ff
1260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_STATEMASK  0xff00
1261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_ACTIVE     0x0100
1263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_PENDING    0x0200
1264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define FDE_CREATED    0x0400
1265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_enqueue(fdevent *node);
1267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void fdevent_plist_remove(fdevent *node);
1268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent *fdevent_plist_dequeue(void);
1269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent list_pending = {
1271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    .next = &list_pending,
1272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    .prev = &list_pending,
1273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
1274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic fdevent **fd_table = 0;
1276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int       fd_table_max = 0;
1277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct EventLooperRec_*  EventLooper;
1279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projecttypedef struct EventHookRec_
1281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook    next;
1283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    FH           fh;
1284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    HANDLE       h;
1285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          wanted;   /* wanted event flags */
1286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int          ready;    /* ready event flags  */
1287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void*        aux;
1288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void        (*prepare)( EventHook  hook );
1289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int         (*start)  ( EventHook  hook );
1290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    void        (*stop)   ( EventHook  hook );
1291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int         (*check)  ( EventHook  hook );
1292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    int         (*peek)   ( EventHook  hook );
1293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} EventHookRec;
1294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventHook  _free_hooks;
1296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic EventHook
1298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectevent_hook_alloc( FH  fh )
1299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    EventHook  hook = _free_hooks;
1301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (hook != NULL)
1302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        _free_hooks = hook->next;
1303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    else {
1304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        hook = malloc( sizeof(*hook) );
1305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (hook == NULL)
1306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            fatal( "could not allocate event hook\n" );
1307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1308