blob: 093e90220d6de47b86f135d9d0753d9423a43c7f [file] [log] [blame]
Dan Albert33134262015-03-19 15:21:08 -07001/*
2 * Copyright (C) 2015 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define TRACE_TAG TRACE_SYSDEPS
18
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080019#include "sysdeps.h"
Dan Albert33134262015-03-19 15:21:08 -070020
21#include <winsock2.h> /* winsock.h *must* be included before windows.h. */
Stephen Hines2f431a82014-10-01 17:37:06 -070022#include <windows.h>
Dan Albert33134262015-03-19 15:21:08 -070023
24#include <errno.h>
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080025#include <stdio.h>
Christopher Ferris67a7a4a2014-11-06 14:34:24 -080026#include <stdlib.h>
Dan Albert33134262015-03-19 15:21:08 -070027
Spencer Low5200c662015-07-30 23:07:55 -070028#include <memory>
29#include <string>
30
Elliott Hughesd48dbd82015-07-24 11:35:40 -070031#include <cutils/sockets.h>
32
Spencer Low5200c662015-07-30 23:07:55 -070033#include <base/logging.h>
34#include <base/stringprintf.h>
35#include <base/strings.h>
36
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080037#include "adb.h"
38
39extern void fatal(const char *fmt, ...);
40
Elliott Hughesa2f2e562015-04-16 16:47:02 -070041/* forward declarations */
42
43typedef const struct FHClassRec_* FHClass;
44typedef struct FHRec_* FH;
45typedef struct EventHookRec_* EventHook;
46
47typedef struct FHClassRec_ {
48 void (*_fh_init)(FH);
49 int (*_fh_close)(FH);
50 int (*_fh_lseek)(FH, int, int);
51 int (*_fh_read)(FH, void*, int);
52 int (*_fh_write)(FH, const void*, int);
53 void (*_fh_hook)(FH, int, EventHook);
54} FHClassRec;
55
56static void _fh_file_init(FH);
57static int _fh_file_close(FH);
58static int _fh_file_lseek(FH, int, int);
59static int _fh_file_read(FH, void*, int);
60static int _fh_file_write(FH, const void*, int);
61static void _fh_file_hook(FH, int, EventHook);
62
63static const FHClassRec _fh_file_class = {
64 _fh_file_init,
65 _fh_file_close,
66 _fh_file_lseek,
67 _fh_file_read,
68 _fh_file_write,
69 _fh_file_hook
70};
71
72static void _fh_socket_init(FH);
73static int _fh_socket_close(FH);
74static int _fh_socket_lseek(FH, int, int);
75static int _fh_socket_read(FH, void*, int);
76static int _fh_socket_write(FH, const void*, int);
77static void _fh_socket_hook(FH, int, EventHook);
78
79static const FHClassRec _fh_socket_class = {
80 _fh_socket_init,
81 _fh_socket_close,
82 _fh_socket_lseek,
83 _fh_socket_read,
84 _fh_socket_write,
85 _fh_socket_hook
86};
87
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080088#define assert(cond) do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0)
89
Spencer Low5200c662015-07-30 23:07:55 -070090std::string SystemErrorCodeToString(const DWORD error_code) {
91 const int kErrorMessageBufferSize = 256;
92 char msgbuf[kErrorMessageBufferSize];
93 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
94 DWORD len = FormatMessageA(flags, nullptr, error_code, 0, msgbuf,
95 arraysize(msgbuf), nullptr);
96 if (len == 0) {
97 return android::base::StringPrintf(
98 "Error (%lu) while retrieving error. (%lu)", GetLastError(),
99 error_code);
100 }
101
102 std::string msg(msgbuf);
103 // Messages returned by the system end with line breaks.
104 msg = android::base::Trim(msg);
105 // There are many Windows error messages compared to POSIX, so include the
106 // numeric error code for easier, quicker, accurate identification. Use
107 // decimal instead of hex because there are decimal ranges like 10000-11999
108 // for Winsock.
109 android::base::StringAppendF(&msg, " (%lu)", error_code);
110 return msg;
111}
112
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800113/**************************************************************************/
114/**************************************************************************/
115/***** *****/
116/***** replaces libs/cutils/load_file.c *****/
117/***** *****/
118/**************************************************************************/
119/**************************************************************************/
120
121void *load_file(const char *fn, unsigned *_sz)
122{
123 HANDLE file;
124 char *data;
125 DWORD file_size;
126
127 file = CreateFile( fn,
128 GENERIC_READ,
129 FILE_SHARE_READ,
130 NULL,
131 OPEN_EXISTING,
132 0,
133 NULL );
134
135 if (file == INVALID_HANDLE_VALUE)
136 return NULL;
137
138 file_size = GetFileSize( file, NULL );
139 data = NULL;
140
141 if (file_size > 0) {
142 data = (char*) malloc( file_size + 1 );
143 if (data == NULL) {
144 D("load_file: could not allocate %ld bytes\n", file_size );
145 file_size = 0;
146 } else {
147 DWORD out_bytes;
148
149 if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) ||
150 out_bytes != file_size )
151 {
152 D("load_file: could not read %ld bytes from '%s'\n", file_size, fn);
153 free(data);
154 data = NULL;
155 file_size = 0;
156 }
157 }
158 }
159 CloseHandle( file );
160
161 *_sz = (unsigned) file_size;
162 return data;
163}
164
165/**************************************************************************/
166/**************************************************************************/
167/***** *****/
168/***** common file descriptor handling *****/
169/***** *****/
170/**************************************************************************/
171/**************************************************************************/
172
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800173/* used to emulate unix-domain socket pairs */
174typedef struct SocketPairRec_* SocketPair;
175
176typedef struct FHRec_
177{
178 FHClass clazz;
179 int used;
180 int eof;
181 union {
182 HANDLE handle;
183 SOCKET socket;
184 SocketPair pair;
185 } u;
186
187 HANDLE event;
188 int mask;
189
190 char name[32];
191
192} FHRec;
193
194#define fh_handle u.handle
195#define fh_socket u.socket
196#define fh_pair u.pair
197
198#define WIN32_FH_BASE 100
199
200#define WIN32_MAX_FHS 128
201
202static adb_mutex_t _win32_lock;
203static FHRec _win32_fhs[ WIN32_MAX_FHS ];
Spencer Lowc3211552015-07-24 15:38:19 -0700204static int _win32_fh_next; // where to start search for free FHRec
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800205
206static FH
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700207_fh_from_int( int fd, const char* func )
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800208{
209 FH f;
210
211 fd -= WIN32_FH_BASE;
212
Spencer Lowc3211552015-07-24 15:38:19 -0700213 if (fd < 0 || fd >= WIN32_MAX_FHS) {
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700214 D( "_fh_from_int: invalid fd %d passed to %s\n", fd + WIN32_FH_BASE,
215 func );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800216 errno = EBADF;
217 return NULL;
218 }
219
220 f = &_win32_fhs[fd];
221
222 if (f->used == 0) {
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700223 D( "_fh_from_int: invalid fd %d passed to %s\n", fd + WIN32_FH_BASE,
224 func );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800225 errno = EBADF;
226 return NULL;
227 }
228
229 return f;
230}
231
232
233static int
234_fh_to_int( FH f )
235{
236 if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
237 return (int)(f - _win32_fhs) + WIN32_FH_BASE;
238
239 return -1;
240}
241
242static FH
243_fh_alloc( FHClass clazz )
244{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800245 FH f = NULL;
246
247 adb_mutex_lock( &_win32_lock );
248
Spencer Lowc3211552015-07-24 15:38:19 -0700249 // Search entire array, starting from _win32_fh_next.
250 for (int nn = 0; nn < WIN32_MAX_FHS; nn++) {
251 // Keep incrementing _win32_fh_next to avoid giving out an index that
252 // was recently closed, to try to avoid use-after-free.
253 const int index = _win32_fh_next++;
254 // Handle wrap-around of _win32_fh_next.
255 if (_win32_fh_next == WIN32_MAX_FHS) {
256 _win32_fh_next = 0;
257 }
258 if (_win32_fhs[index].clazz == NULL) {
259 f = &_win32_fhs[index];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800260 goto Exit;
261 }
262 }
263 D( "_fh_alloc: no more free file descriptors\n" );
Spencer Lowc3211552015-07-24 15:38:19 -0700264 errno = EMFILE; // Too many open files
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800265Exit:
266 if (f) {
Spencer Lowc3211552015-07-24 15:38:19 -0700267 f->clazz = clazz;
268 f->used = 1;
269 f->eof = 0;
270 f->name[0] = '\0';
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800271 clazz->_fh_init(f);
272 }
273 adb_mutex_unlock( &_win32_lock );
274 return f;
275}
276
277
278static int
279_fh_close( FH f )
280{
Spencer Lowc3211552015-07-24 15:38:19 -0700281 // Use lock so that closing only happens once and so that _fh_alloc can't
282 // allocate a FH that we're in the middle of closing.
283 adb_mutex_lock(&_win32_lock);
284 if (f->used) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800285 f->clazz->_fh_close( f );
Spencer Lowc3211552015-07-24 15:38:19 -0700286 f->name[0] = '\0';
287 f->eof = 0;
288 f->used = 0;
289 f->clazz = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800290 }
Spencer Lowc3211552015-07-24 15:38:19 -0700291 adb_mutex_unlock(&_win32_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800292 return 0;
293}
294
Spencer Low5200c662015-07-30 23:07:55 -0700295// Deleter for unique_fh.
296class fh_deleter {
297 public:
298 void operator()(struct FHRec_* fh) {
299 // We're called from a destructor and destructors should not overwrite
300 // errno because callers may do:
301 // errno = EBLAH;
302 // return -1; // calls destructor, which should not overwrite errno
303 const int saved_errno = errno;
304 _fh_close(fh);
305 errno = saved_errno;
306 }
307};
308
309// Like std::unique_ptr, but calls _fh_close() instead of operator delete().
310typedef std::unique_ptr<struct FHRec_, fh_deleter> unique_fh;
311
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800312/**************************************************************************/
313/**************************************************************************/
314/***** *****/
315/***** file-based descriptor handling *****/
316/***** *****/
317/**************************************************************************/
318/**************************************************************************/
319
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700320static void _fh_file_init( FH f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800321 f->fh_handle = INVALID_HANDLE_VALUE;
322}
323
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700324static int _fh_file_close( FH f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800325 CloseHandle( f->fh_handle );
326 f->fh_handle = INVALID_HANDLE_VALUE;
327 return 0;
328}
329
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700330static int _fh_file_read( FH f, void* buf, int len ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800331 DWORD read_bytes;
332
333 if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) {
334 D( "adb_read: could not read %d bytes from %s\n", len, f->name );
335 errno = EIO;
336 return -1;
337 } else if (read_bytes < (DWORD)len) {
338 f->eof = 1;
339 }
340 return (int)read_bytes;
341}
342
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700343static int _fh_file_write( FH f, const void* buf, int len ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800344 DWORD wrote_bytes;
345
346 if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) {
347 D( "adb_file_write: could not write %d bytes from %s\n", len, f->name );
348 errno = EIO;
349 return -1;
350 } else if (wrote_bytes < (DWORD)len) {
351 f->eof = 1;
352 }
353 return (int)wrote_bytes;
354}
355
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700356static int _fh_file_lseek( FH f, int pos, int origin ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800357 DWORD method;
358 DWORD result;
359
360 switch (origin)
361 {
362 case SEEK_SET: method = FILE_BEGIN; break;
363 case SEEK_CUR: method = FILE_CURRENT; break;
364 case SEEK_END: method = FILE_END; break;
365 default:
366 errno = EINVAL;
367 return -1;
368 }
369
370 result = SetFilePointer( f->fh_handle, pos, NULL, method );
371 if (result == INVALID_SET_FILE_POINTER) {
372 errno = EIO;
373 return -1;
374 } else {
375 f->eof = 0;
376 }
377 return (int)result;
378}
379
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800380
381/**************************************************************************/
382/**************************************************************************/
383/***** *****/
384/***** file-based descriptor handling *****/
385/***** *****/
386/**************************************************************************/
387/**************************************************************************/
388
389int adb_open(const char* path, int options)
390{
391 FH f;
392
393 DWORD desiredAccess = 0;
394 DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
395
396 switch (options) {
397 case O_RDONLY:
398 desiredAccess = GENERIC_READ;
399 break;
400 case O_WRONLY:
401 desiredAccess = GENERIC_WRITE;
402 break;
403 case O_RDWR:
404 desiredAccess = GENERIC_READ | GENERIC_WRITE;
405 break;
406 default:
407 D("adb_open: invalid options (0x%0x)\n", options);
408 errno = EINVAL;
409 return -1;
410 }
411
412 f = _fh_alloc( &_fh_file_class );
413 if ( !f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800414 return -1;
415 }
416
417 f->fh_handle = CreateFile( path, desiredAccess, shareMode, NULL, OPEN_EXISTING,
418 0, NULL );
419
420 if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
Spencer Low8d8126a2015-07-21 02:06:26 -0700421 const DWORD err = GetLastError();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800422 _fh_close(f);
Spencer Low8d8126a2015-07-21 02:06:26 -0700423 D( "adb_open: could not open '%s': ", path );
424 switch (err) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800425 case ERROR_FILE_NOT_FOUND:
426 D( "file not found\n" );
427 errno = ENOENT;
428 return -1;
429
430 case ERROR_PATH_NOT_FOUND:
431 D( "path not found\n" );
432 errno = ENOTDIR;
433 return -1;
434
435 default:
Spencer Low8d8126a2015-07-21 02:06:26 -0700436 D( "unknown error: %ld\n", err );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800437 errno = ENOENT;
438 return -1;
439 }
440 }
Vladimir Chtchetkinece480832011-11-30 10:20:27 -0800441
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800442 snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
443 D( "adb_open: '%s' => fd %d\n", path, _fh_to_int(f) );
444 return _fh_to_int(f);
445}
446
447/* ignore mode on Win32 */
448int adb_creat(const char* path, int mode)
449{
450 FH f;
451
452 f = _fh_alloc( &_fh_file_class );
453 if ( !f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800454 return -1;
455 }
456
457 f->fh_handle = CreateFile( path, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
458 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
459 NULL );
460
461 if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
Spencer Low8d8126a2015-07-21 02:06:26 -0700462 const DWORD err = GetLastError();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800463 _fh_close(f);
Spencer Low8d8126a2015-07-21 02:06:26 -0700464 D( "adb_creat: could not open '%s': ", path );
465 switch (err) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800466 case ERROR_FILE_NOT_FOUND:
467 D( "file not found\n" );
468 errno = ENOENT;
469 return -1;
470
471 case ERROR_PATH_NOT_FOUND:
472 D( "path not found\n" );
473 errno = ENOTDIR;
474 return -1;
475
476 default:
Spencer Low8d8126a2015-07-21 02:06:26 -0700477 D( "unknown error: %ld\n", err );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800478 errno = ENOENT;
479 return -1;
480 }
481 }
482 snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
483 D( "adb_creat: '%s' => fd %d\n", path, _fh_to_int(f) );
484 return _fh_to_int(f);
485}
486
487
488int adb_read(int fd, void* buf, int len)
489{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700490 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800491
492 if (f == NULL) {
493 return -1;
494 }
495
496 return f->clazz->_fh_read( f, buf, len );
497}
498
499
500int adb_write(int fd, const void* buf, int len)
501{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700502 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800503
504 if (f == NULL) {
505 return -1;
506 }
507
508 return f->clazz->_fh_write(f, buf, len);
509}
510
511
512int adb_lseek(int fd, int pos, int where)
513{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700514 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800515
516 if (!f) {
517 return -1;
518 }
519
520 return f->clazz->_fh_lseek(f, pos, where);
521}
522
523
524int adb_close(int fd)
525{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700526 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800527
528 if (!f) {
529 return -1;
530 }
531
532 D( "adb_close: %s\n", f->name);
533 _fh_close(f);
534 return 0;
535}
536
537/**************************************************************************/
538/**************************************************************************/
539/***** *****/
540/***** socket-based file descriptors *****/
541/***** *****/
542/**************************************************************************/
543/**************************************************************************/
544
Spencer Lowf055c192015-01-25 14:40:16 -0800545#undef setsockopt
546
Spencer Low5200c662015-07-30 23:07:55 -0700547static void _socket_set_errno( const DWORD err ) {
548 // The Windows C Runtime (MSVCRT.DLL) strerror() does not support a lot of
549 // POSIX and socket error codes, so this can only meaningfully map so much.
550 switch ( err ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800551 case 0: errno = 0; break;
552 case WSAEWOULDBLOCK: errno = EAGAIN; break;
553 case WSAEINTR: errno = EINTR; break;
Spencer Low5200c662015-07-30 23:07:55 -0700554 case WSAEFAULT: errno = EFAULT; break;
555 case WSAEINVAL: errno = EINVAL; break;
556 case WSAEMFILE: errno = EMFILE; break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800557 default:
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800558 errno = EINVAL;
Spencer Low5200c662015-07-30 23:07:55 -0700559 D( "_socket_set_errno: mapping Windows error code %lu to errno %d\n",
560 err, errno );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800561 }
562}
563
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700564static void _fh_socket_init( FH f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800565 f->fh_socket = INVALID_SOCKET;
566 f->event = WSACreateEvent();
Spencer Low5200c662015-07-30 23:07:55 -0700567 if (f->event == WSA_INVALID_EVENT) {
568 D("WSACreateEvent failed: %s\n",
569 SystemErrorCodeToString(WSAGetLastError()).c_str());
570
571 // _event_socket_start assumes that this field is INVALID_HANDLE_VALUE
572 // on failure, instead of NULL which is what Windows really returns on
573 // error. It might be better to change all the other code to look for
574 // NULL, but that is a much riskier change.
575 f->event = INVALID_HANDLE_VALUE;
576 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800577 f->mask = 0;
578}
579
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700580static int _fh_socket_close( FH f ) {
Spencer Low5200c662015-07-30 23:07:55 -0700581 if (f->fh_socket != INVALID_SOCKET) {
582 /* gently tell any peer that we're closing the socket */
583 if (shutdown(f->fh_socket, SD_BOTH) == SOCKET_ERROR) {
584 // If the socket is not connected, this returns an error. We want to
585 // minimize logging spam, so don't log these errors for now.
586#if 0
587 D("socket shutdown failed: %s\n",
588 SystemErrorCodeToString(WSAGetLastError()).c_str());
589#endif
590 }
591 if (closesocket(f->fh_socket) == SOCKET_ERROR) {
592 D("closesocket failed: %s\n",
593 SystemErrorCodeToString(WSAGetLastError()).c_str());
594 }
595 f->fh_socket = INVALID_SOCKET;
596 }
597 if (f->event != NULL) {
598 if (!CloseHandle(f->event)) {
599 D("CloseHandle failed: %s\n",
600 SystemErrorCodeToString(GetLastError()).c_str());
601 }
602 f->event = NULL;
603 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800604 f->mask = 0;
605 return 0;
606}
607
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700608static int _fh_socket_lseek( FH f, int pos, int origin ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800609 errno = EPIPE;
610 return -1;
611}
612
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700613static int _fh_socket_read(FH f, void* buf, int len) {
614 int result = recv(f->fh_socket, reinterpret_cast<char*>(buf), len, 0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800615 if (result == SOCKET_ERROR) {
Spencer Low5200c662015-07-30 23:07:55 -0700616 const DWORD err = WSAGetLastError();
617 D("recv fd %d failed: %s\n", _fh_to_int(f),
618 SystemErrorCodeToString(err).c_str());
619 _socket_set_errno(err);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800620 result = -1;
621 }
622 return result;
623}
624
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700625static int _fh_socket_write(FH f, const void* buf, int len) {
626 int result = send(f->fh_socket, reinterpret_cast<const char*>(buf), len, 0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800627 if (result == SOCKET_ERROR) {
Spencer Low5200c662015-07-30 23:07:55 -0700628 const DWORD err = WSAGetLastError();
629 D("send fd %d failed: %s\n", _fh_to_int(f),
630 SystemErrorCodeToString(err).c_str());
631 _socket_set_errno(err);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800632 result = -1;
633 }
634 return result;
635}
636
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800637/**************************************************************************/
638/**************************************************************************/
639/***** *****/
640/***** replacement for libs/cutils/socket_xxxx.c *****/
641/***** *****/
642/**************************************************************************/
643/**************************************************************************/
644
645#include <winsock2.h>
646
647static int _winsock_init;
648
649static void
650_cleanup_winsock( void )
651{
Spencer Low5200c662015-07-30 23:07:55 -0700652 // TODO: WSAStartup() might be called multiple times and this won't properly
653 // cleanup the right number of times. Plus, WSACleanup() probably doesn't
654 // make sense since it might interrupt other threads using Winsock (since
655 // our various threads are not explicitly cleanly shutdown at process exit).
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800656 WSACleanup();
657}
658
659static void
660_init_winsock( void )
661{
Spencer Low5200c662015-07-30 23:07:55 -0700662 // TODO: Multiple threads calling this may potentially cause multiple calls
663 // to WSAStartup() and multiple atexit() calls.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800664 if (!_winsock_init) {
665 WSADATA wsaData;
666 int rc = WSAStartup( MAKEWORD(2,2), &wsaData);
667 if (rc != 0) {
Spencer Low5200c662015-07-30 23:07:55 -0700668 fatal( "adb: could not initialize Winsock: %s",
669 SystemErrorCodeToString( rc ).c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800670 }
671 atexit( _cleanup_winsock );
672 _winsock_init = 1;
673 }
674}
675
Spencer Low5200c662015-07-30 23:07:55 -0700676int network_loopback_client(int port, int type, std::string* error) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800677 struct sockaddr_in addr;
678 SOCKET s;
679
Spencer Low5200c662015-07-30 23:07:55 -0700680 unique_fh f(_fh_alloc(&_fh_socket_class));
681 if (!f) {
682 *error = strerror(errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800683 return -1;
Spencer Low5200c662015-07-30 23:07:55 -0700684 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800685
686 if (!_winsock_init)
687 _init_winsock();
688
689 memset(&addr, 0, sizeof(addr));
690 addr.sin_family = AF_INET;
691 addr.sin_port = htons(port);
692 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
693
694 s = socket(AF_INET, type, 0);
695 if(s == INVALID_SOCKET) {
Spencer Low5200c662015-07-30 23:07:55 -0700696 *error = SystemErrorCodeToString(WSAGetLastError());
697 D("could not create socket: %s\n", error->c_str());
698 return -1;
699 }
700 f->fh_socket = s;
701
702 if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
703 *error = SystemErrorCodeToString(WSAGetLastError());
704 D("could not connect to %s:%d: %s\n",
705 type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800706 return -1;
707 }
708
Spencer Low5200c662015-07-30 23:07:55 -0700709 const int fd = _fh_to_int(f.get());
710 snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", fd,
711 type != SOCK_STREAM ? "udp:" : "", port );
712 D( "port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp",
713 fd );
714 f.release();
715 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800716}
717
718#define LISTEN_BACKLOG 4
719
Spencer Low5200c662015-07-30 23:07:55 -0700720// interface_address is INADDR_LOOPBACK or INADDR_ANY.
721static int _network_server(int port, int type, u_long interface_address,
722 std::string* error) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800723 struct sockaddr_in addr;
724 SOCKET s;
725 int n;
726
Spencer Low5200c662015-07-30 23:07:55 -0700727 unique_fh f(_fh_alloc(&_fh_socket_class));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800728 if (!f) {
Spencer Low5200c662015-07-30 23:07:55 -0700729 *error = strerror(errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800730 return -1;
731 }
732
733 if (!_winsock_init)
734 _init_winsock();
735
736 memset(&addr, 0, sizeof(addr));
737 addr.sin_family = AF_INET;
738 addr.sin_port = htons(port);
Spencer Low5200c662015-07-30 23:07:55 -0700739 addr.sin_addr.s_addr = htonl(interface_address);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800740
Spencer Low5200c662015-07-30 23:07:55 -0700741 // TODO: Consider using dual-stack socket that can simultaneously listen on
742 // IPv4 and IPv6.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800743 s = socket(AF_INET, type, 0);
Spencer Low5200c662015-07-30 23:07:55 -0700744 if (s == INVALID_SOCKET) {
745 *error = SystemErrorCodeToString(WSAGetLastError());
746 D("could not create socket: %s\n", error->c_str());
747 return -1;
748 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800749
750 f->fh_socket = s;
751
752 n = 1;
Spencer Low5200c662015-07-30 23:07:55 -0700753 if (setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n,
754 sizeof(n)) == SOCKET_ERROR) {
755 *error = SystemErrorCodeToString(WSAGetLastError());
756 D("setsockopt level %d optname %d failed: %s\n",
757 SOL_SOCKET, SO_EXCLUSIVEADDRUSE, error->c_str());
758 return -1;
759 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800760
Spencer Low5200c662015-07-30 23:07:55 -0700761 if(bind(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
762 *error = SystemErrorCodeToString(WSAGetLastError());
763 D("could not bind to %s:%d: %s\n",
764 type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800765 return -1;
766 }
767 if (type == SOCK_STREAM) {
Spencer Low5200c662015-07-30 23:07:55 -0700768 if (listen(s, LISTEN_BACKLOG) == SOCKET_ERROR) {
769 *error = SystemErrorCodeToString(WSAGetLastError());
770 D("could not listen on %s:%d: %s\n",
771 type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800772 return -1;
773 }
774 }
Spencer Low5200c662015-07-30 23:07:55 -0700775 const int fd = _fh_to_int(f.get());
776 snprintf( f->name, sizeof(f->name), "%d(%s-server:%s%d)", fd,
777 interface_address == INADDR_LOOPBACK ? "lo" : "any",
778 type != SOCK_STREAM ? "udp:" : "", port );
779 D( "port %d type %s => fd %d\n", port, type != SOCK_STREAM ? "udp" : "tcp",
780 fd );
781 f.release();
782 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800783}
784
Spencer Low5200c662015-07-30 23:07:55 -0700785int network_loopback_server(int port, int type, std::string* error) {
786 return _network_server(port, type, INADDR_LOOPBACK, error);
787}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800788
Spencer Low5200c662015-07-30 23:07:55 -0700789int network_inaddr_any_server(int port, int type, std::string* error) {
790 return _network_server(port, type, INADDR_ANY, error);
791}
792
793int network_connect(const std::string& host, int port, int type, int timeout, std::string* error) {
794 unique_fh f(_fh_alloc(&_fh_socket_class));
795 if (!f) {
796 *error = strerror(errno);
797 return -1;
798 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800799
Elliott Hughes381cfa92015-07-23 17:12:58 -0700800 if (!_winsock_init) _init_winsock();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800801
Spencer Low5200c662015-07-30 23:07:55 -0700802 struct addrinfo hints;
803 memset(&hints, 0, sizeof(hints));
804 hints.ai_family = AF_UNSPEC;
805 hints.ai_socktype = type;
806
807 char port_str[16];
808 snprintf(port_str, sizeof(port_str), "%d", port);
809
810 struct addrinfo* addrinfo_ptr = nullptr;
811 if (getaddrinfo(host.c_str(), port_str, &hints, &addrinfo_ptr) != 0) {
812 *error = SystemErrorCodeToString(WSAGetLastError());
813 D("could not resolve host '%s' and port %s: %s\n", host.c_str(),
814 port_str, error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800815 return -1;
816 }
Spencer Low5200c662015-07-30 23:07:55 -0700817 std::unique_ptr<struct addrinfo, decltype(freeaddrinfo)*>
818 addrinfo(addrinfo_ptr, freeaddrinfo);
819 addrinfo_ptr = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800820
Spencer Low5200c662015-07-30 23:07:55 -0700821 // TODO: Try all the addresses if there's more than one? This just uses
822 // the first. Or, could call WSAConnectByName() (Windows Vista and newer)
823 // which tries all addresses, takes a timeout and more.
824 SOCKET s = socket(addrinfo->ai_family, addrinfo->ai_socktype,
825 addrinfo->ai_protocol);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800826 if(s == INVALID_SOCKET) {
Spencer Low5200c662015-07-30 23:07:55 -0700827 *error = SystemErrorCodeToString(WSAGetLastError());
828 D("could not create socket: %s\n", error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800829 return -1;
830 }
831 f->fh_socket = s;
832
Spencer Low5200c662015-07-30 23:07:55 -0700833 // TODO: Implement timeouts for Windows. Seems like the default in theory
834 // (according to http://serverfault.com/a/671453) and in practice is 21 sec.
835 if(connect(s, addrinfo->ai_addr, addrinfo->ai_addrlen) == SOCKET_ERROR) {
836 *error = SystemErrorCodeToString(WSAGetLastError());
837 D("could not connect to %s:%s:%s: %s\n",
838 type != SOCK_STREAM ? "udp" : "tcp", host.c_str(), port_str,
839 error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800840 return -1;
841 }
842
Spencer Low5200c662015-07-30 23:07:55 -0700843 const int fd = _fh_to_int(f.get());
844 snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", fd,
845 type != SOCK_STREAM ? "udp:" : "", port );
846 D( "host '%s' port %d type %s => fd %d\n", host.c_str(), port,
847 type != SOCK_STREAM ? "udp" : "tcp", fd );
848 f.release();
849 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800850}
851
852#undef accept
853int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen)
854{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700855 FH serverfh = _fh_from_int(serverfd, __func__);
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200856
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800857 if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
Spencer Low5200c662015-07-30 23:07:55 -0700858 D("adb_socket_accept: invalid fd %d\n", serverfd);
859 errno = EBADF;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800860 return -1;
861 }
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200862
Spencer Low5200c662015-07-30 23:07:55 -0700863 unique_fh fh(_fh_alloc( &_fh_socket_class ));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800864 if (!fh) {
Spencer Low5200c662015-07-30 23:07:55 -0700865 PLOG(ERROR) << "adb_socket_accept: failed to allocate accepted socket "
866 "descriptor";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800867 return -1;
868 }
869
870 fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen );
871 if (fh->fh_socket == INVALID_SOCKET) {
Spencer Low8d8126a2015-07-21 02:06:26 -0700872 const DWORD err = WSAGetLastError();
Spencer Low5200c662015-07-30 23:07:55 -0700873 LOG(ERROR) << "adb_socket_accept: accept on fd " << serverfd <<
874 " failed: " + SystemErrorCodeToString(err);
875 _socket_set_errno( err );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800876 return -1;
877 }
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200878
Spencer Low5200c662015-07-30 23:07:55 -0700879 const int fd = _fh_to_int(fh.get());
880 snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", fd, serverfh->name );
881 D( "adb_socket_accept on fd %d returns fd %d\n", serverfd, fd );
882 fh.release();
883 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800884}
885
886
Spencer Lowf055c192015-01-25 14:40:16 -0800887int adb_setsockopt( int fd, int level, int optname, const void* optval, socklen_t optlen )
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800888{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700889 FH fh = _fh_from_int(fd, __func__);
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200890
Spencer Lowf055c192015-01-25 14:40:16 -0800891 if ( !fh || fh->clazz != &_fh_socket_class ) {
892 D("adb_setsockopt: invalid fd %d\n", fd);
Spencer Low5200c662015-07-30 23:07:55 -0700893 errno = EBADF;
894 return -1;
895 }
896 int result = setsockopt( fh->fh_socket, level, optname,
897 reinterpret_cast<const char*>(optval), optlen );
898 if ( result == SOCKET_ERROR ) {
899 const DWORD err = WSAGetLastError();
900 D( "adb_setsockopt: setsockopt on fd %d level %d optname %d "
901 "failed: %s\n", fd, level, optname,
902 SystemErrorCodeToString(err).c_str() );
903 _socket_set_errno( err );
904 result = -1;
905 }
906 return result;
907}
908
909
910int adb_shutdown(int fd)
911{
912 FH f = _fh_from_int(fd, __func__);
913
914 if (!f || f->clazz != &_fh_socket_class) {
915 D("adb_shutdown: invalid fd %d\n", fd);
916 errno = EBADF;
Spencer Lowf055c192015-01-25 14:40:16 -0800917 return -1;
918 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800919
Spencer Low5200c662015-07-30 23:07:55 -0700920 D( "adb_shutdown: %s\n", f->name);
921 if (shutdown(f->fh_socket, SD_BOTH) == SOCKET_ERROR) {
922 const DWORD err = WSAGetLastError();
923 D("socket shutdown fd %d failed: %s\n", fd,
924 SystemErrorCodeToString(err).c_str());
925 _socket_set_errno(err);
926 return -1;
927 }
928 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800929}
930
931/**************************************************************************/
932/**************************************************************************/
933/***** *****/
934/***** emulated socketpairs *****/
935/***** *****/
936/**************************************************************************/
937/**************************************************************************/
938
939/* we implement socketpairs directly in use space for the following reasons:
940 * - it avoids copying data from/to the Nt kernel
941 * - it allows us to implement fdevent hooks easily and cheaply, something
942 * that is not possible with standard Win32 pipes !!
943 *
944 * basically, we use two circular buffers, each one corresponding to a given
945 * direction.
946 *
947 * each buffer is implemented as two regions:
948 *
949 * region A which is (a_start,a_end)
950 * region B which is (0, b_end) with b_end <= a_start
951 *
952 * an empty buffer has: a_start = a_end = b_end = 0
953 *
954 * a_start is the pointer where we start reading data
955 * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE,
956 * then you start writing at b_end
957 *
958 * the buffer is full when b_end == a_start && a_end == BUFFER_SIZE
959 *
960 * there is room when b_end < a_start || a_end < BUFER_SIZE
961 *
962 * when reading, a_start is incremented, it a_start meets a_end, then
963 * we do: a_start = 0, a_end = b_end, b_end = 0, and keep going on..
964 */
965
966#define BIP_BUFFER_SIZE 4096
967
968#if 0
969#include <stdio.h>
970# define BIPD(x) D x
971# define BIPDUMP bip_dump_hex
972
973static void bip_dump_hex( const unsigned char* ptr, size_t len )
974{
975 int nn, len2 = len;
976
977 if (len2 > 8) len2 = 8;
978
Vladimir Chtchetkinece480832011-11-30 10:20:27 -0800979 for (nn = 0; nn < len2; nn++)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800980 printf("%02x", ptr[nn]);
981 printf(" ");
982
983 for (nn = 0; nn < len2; nn++) {
984 int c = ptr[nn];
985 if (c < 32 || c > 127)
986 c = '.';
987 printf("%c", c);
988 }
989 printf("\n");
990 fflush(stdout);
991}
992
993#else
994# define BIPD(x) do {} while (0)
995# define BIPDUMP(p,l) BIPD(p)
996#endif
997
998typedef struct BipBufferRec_
999{
1000 int a_start;
1001 int a_end;
1002 int b_end;
1003 int fdin;
1004 int fdout;
1005 int closed;
1006 int can_write; /* boolean */
1007 HANDLE evt_write; /* event signaled when one can write to a buffer */
1008 int can_read; /* boolean */
1009 HANDLE evt_read; /* event signaled when one can read from a buffer */
1010 CRITICAL_SECTION lock;
1011 unsigned char buff[ BIP_BUFFER_SIZE ];
1012
1013} BipBufferRec, *BipBuffer;
1014
1015static void
1016bip_buffer_init( BipBuffer buffer )
1017{
1018 D( "bit_buffer_init %p\n", buffer );
1019 buffer->a_start = 0;
1020 buffer->a_end = 0;
1021 buffer->b_end = 0;
1022 buffer->can_write = 1;
1023 buffer->can_read = 0;
1024 buffer->fdin = 0;
1025 buffer->fdout = 0;
1026 buffer->closed = 0;
1027 buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL );
1028 buffer->evt_read = CreateEvent( NULL, TRUE, FALSE, NULL );
1029 InitializeCriticalSection( &buffer->lock );
1030}
1031
1032static void
1033bip_buffer_close( BipBuffer bip )
1034{
1035 bip->closed = 1;
1036
1037 if (!bip->can_read) {
1038 SetEvent( bip->evt_read );
1039 }
1040 if (!bip->can_write) {
1041 SetEvent( bip->evt_write );
1042 }
1043}
1044
1045static void
1046bip_buffer_done( BipBuffer bip )
1047{
1048 BIPD(( "bip_buffer_done: %d->%d\n", bip->fdin, bip->fdout ));
1049 CloseHandle( bip->evt_read );
1050 CloseHandle( bip->evt_write );
1051 DeleteCriticalSection( &bip->lock );
1052}
1053
1054static int
1055bip_buffer_write( BipBuffer bip, const void* src, int len )
1056{
1057 int avail, count = 0;
1058
1059 if (len <= 0)
1060 return 0;
1061
1062 BIPD(( "bip_buffer_write: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1063 BIPDUMP( src, len );
1064
1065 EnterCriticalSection( &bip->lock );
1066
1067 while (!bip->can_write) {
1068 int ret;
1069 LeaveCriticalSection( &bip->lock );
1070
1071 if (bip->closed) {
1072 errno = EPIPE;
1073 return -1;
1074 }
1075 /* spinlocking here is probably unfair, but let's live with it */
1076 ret = WaitForSingleObject( bip->evt_write, INFINITE );
1077 if (ret != WAIT_OBJECT_0) { /* buffer probably closed */
1078 D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError() );
1079 return 0;
1080 }
1081 if (bip->closed) {
1082 errno = EPIPE;
1083 return -1;
1084 }
1085 EnterCriticalSection( &bip->lock );
1086 }
1087
1088 BIPD(( "bip_buffer_write: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1089
1090 avail = BIP_BUFFER_SIZE - bip->a_end;
1091 if (avail > 0)
1092 {
1093 /* we can append to region A */
1094 if (avail > len)
1095 avail = len;
1096
1097 memcpy( bip->buff + bip->a_end, src, avail );
Mark Salyzyn60299df2014-04-30 09:10:31 -07001098 src = (const char *)src + avail;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001099 count += avail;
1100 len -= avail;
1101
1102 bip->a_end += avail;
1103 if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) {
1104 bip->can_write = 0;
1105 ResetEvent( bip->evt_write );
1106 goto Exit;
1107 }
1108 }
1109
1110 if (len == 0)
1111 goto Exit;
1112
1113 avail = bip->a_start - bip->b_end;
1114 assert( avail > 0 ); /* since can_write is TRUE */
1115
1116 if (avail > len)
1117 avail = len;
1118
1119 memcpy( bip->buff + bip->b_end, src, avail );
1120 count += avail;
1121 bip->b_end += avail;
1122
1123 if (bip->b_end == bip->a_start) {
1124 bip->can_write = 0;
1125 ResetEvent( bip->evt_write );
1126 }
1127
1128Exit:
1129 assert( count > 0 );
1130
1131 if ( !bip->can_read ) {
1132 bip->can_read = 1;
1133 SetEvent( bip->evt_read );
1134 }
1135
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001136 BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001137 bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
1138 LeaveCriticalSection( &bip->lock );
1139
1140 return count;
1141 }
1142
1143static int
1144bip_buffer_read( BipBuffer bip, void* dst, int len )
1145{
1146 int avail, count = 0;
1147
1148 if (len <= 0)
1149 return 0;
1150
1151 BIPD(( "bip_buffer_read: enter %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1152
1153 EnterCriticalSection( &bip->lock );
1154 while ( !bip->can_read )
1155 {
1156#if 0
1157 LeaveCriticalSection( &bip->lock );
1158 errno = EAGAIN;
1159 return -1;
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001160#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001161 int ret;
1162 LeaveCriticalSection( &bip->lock );
1163
1164 if (bip->closed) {
1165 errno = EPIPE;
1166 return -1;
1167 }
1168
1169 ret = WaitForSingleObject( bip->evt_read, INFINITE );
1170 if (ret != WAIT_OBJECT_0) { /* probably closed buffer */
1171 D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld\n", bip->fdin, bip->fdout, ret, GetLastError());
1172 return 0;
1173 }
1174 if (bip->closed) {
1175 errno = EPIPE;
1176 return -1;
1177 }
1178 EnterCriticalSection( &bip->lock );
1179#endif
1180 }
1181
1182 BIPD(( "bip_buffer_read: exec %d->%d len %d\n", bip->fdin, bip->fdout, len ));
1183
1184 avail = bip->a_end - bip->a_start;
1185 assert( avail > 0 ); /* since can_read is TRUE */
1186
1187 if (avail > len)
1188 avail = len;
1189
1190 memcpy( dst, bip->buff + bip->a_start, avail );
Mark Salyzyn60299df2014-04-30 09:10:31 -07001191 dst = (char *)dst + avail;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001192 count += avail;
1193 len -= avail;
1194
1195 bip->a_start += avail;
1196 if (bip->a_start < bip->a_end)
1197 goto Exit;
1198
1199 bip->a_start = 0;
1200 bip->a_end = bip->b_end;
1201 bip->b_end = 0;
1202
1203 avail = bip->a_end;
1204 if (avail > 0) {
1205 if (avail > len)
1206 avail = len;
1207 memcpy( dst, bip->buff, avail );
1208 count += avail;
1209 bip->a_start += avail;
1210
1211 if ( bip->a_start < bip->a_end )
1212 goto Exit;
1213
1214 bip->a_start = bip->a_end = 0;
1215 }
1216
1217 bip->can_read = 0;
1218 ResetEvent( bip->evt_read );
1219
1220Exit:
1221 assert( count > 0 );
1222
1223 if (!bip->can_write ) {
1224 bip->can_write = 1;
1225 SetEvent( bip->evt_write );
1226 }
1227
1228 BIPDUMP( (const unsigned char*)dst - count, count );
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001229 BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d\n",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001230 bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
1231 LeaveCriticalSection( &bip->lock );
1232
1233 return count;
1234}
1235
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001236typedef struct SocketPairRec_
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001237{
1238 BipBufferRec a2b_bip;
1239 BipBufferRec b2a_bip;
1240 FH a_fd;
1241 int used;
1242
1243} SocketPairRec;
1244
1245void _fh_socketpair_init( FH f )
1246{
1247 f->fh_pair = NULL;
1248}
1249
1250static int
1251_fh_socketpair_close( FH f )
1252{
1253 if ( f->fh_pair ) {
1254 SocketPair pair = f->fh_pair;
1255
1256 if ( f == pair->a_fd ) {
1257 pair->a_fd = NULL;
1258 }
1259
1260 bip_buffer_close( &pair->b2a_bip );
1261 bip_buffer_close( &pair->a2b_bip );
1262
1263 if ( --pair->used == 0 ) {
1264 bip_buffer_done( &pair->b2a_bip );
1265 bip_buffer_done( &pair->a2b_bip );
1266 free( pair );
1267 }
1268 f->fh_pair = NULL;
1269 }
1270 return 0;
1271}
1272
1273static int
1274_fh_socketpair_lseek( FH f, int pos, int origin )
1275{
1276 errno = ESPIPE;
1277 return -1;
1278}
1279
1280static int
1281_fh_socketpair_read( FH f, void* buf, int len )
1282{
1283 SocketPair pair = f->fh_pair;
1284 BipBuffer bip;
1285
1286 if (!pair)
1287 return -1;
1288
1289 if ( f == pair->a_fd )
1290 bip = &pair->b2a_bip;
1291 else
1292 bip = &pair->a2b_bip;
1293
1294 return bip_buffer_read( bip, buf, len );
1295}
1296
1297static int
1298_fh_socketpair_write( FH f, const void* buf, int len )
1299{
1300 SocketPair pair = f->fh_pair;
1301 BipBuffer bip;
1302
1303 if (!pair)
1304 return -1;
1305
1306 if ( f == pair->a_fd )
1307 bip = &pair->a2b_bip;
1308 else
1309 bip = &pair->b2a_bip;
1310
1311 return bip_buffer_write( bip, buf, len );
1312}
1313
1314
1315static void _fh_socketpair_hook( FH f, int event, EventHook hook ); /* forward */
1316
1317static const FHClassRec _fh_socketpair_class =
1318{
1319 _fh_socketpair_init,
1320 _fh_socketpair_close,
1321 _fh_socketpair_lseek,
1322 _fh_socketpair_read,
1323 _fh_socketpair_write,
1324 _fh_socketpair_hook
1325};
1326
1327
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001328int adb_socketpair(int sv[2]) {
1329 SocketPair pair;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001330
Spencer Low5200c662015-07-30 23:07:55 -07001331 unique_fh fa(_fh_alloc(&_fh_socketpair_class));
1332 if (!fa) {
1333 return -1;
1334 }
1335 unique_fh fb(_fh_alloc(&_fh_socketpair_class));
1336 if (!fb) {
1337 return -1;
1338 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001339
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001340 pair = reinterpret_cast<SocketPair>(malloc(sizeof(*pair)));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001341 if (pair == NULL) {
1342 D("adb_socketpair: not enough memory to allocate pipes\n" );
Spencer Low5200c662015-07-30 23:07:55 -07001343 return -1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001344 }
1345
1346 bip_buffer_init( &pair->a2b_bip );
1347 bip_buffer_init( &pair->b2a_bip );
1348
1349 fa->fh_pair = pair;
1350 fb->fh_pair = pair;
1351 pair->used = 2;
Spencer Low5200c662015-07-30 23:07:55 -07001352 pair->a_fd = fa.get();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001353
Spencer Low5200c662015-07-30 23:07:55 -07001354 sv[0] = _fh_to_int(fa.get());
1355 sv[1] = _fh_to_int(fb.get());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001356
1357 pair->a2b_bip.fdin = sv[0];
1358 pair->a2b_bip.fdout = sv[1];
1359 pair->b2a_bip.fdin = sv[1];
1360 pair->b2a_bip.fdout = sv[0];
1361
1362 snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );
1363 snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );
1364 D( "adb_socketpair: returns (%d, %d)\n", sv[0], sv[1] );
Spencer Low5200c662015-07-30 23:07:55 -07001365 fa.release();
1366 fb.release();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001367 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001368}
1369
1370/**************************************************************************/
1371/**************************************************************************/
1372/***** *****/
1373/***** fdevents emulation *****/
1374/***** *****/
1375/***** this is a very simple implementation, we rely on the fact *****/
1376/***** that ADB doesn't use FDE_ERROR. *****/
1377/***** *****/
1378/**************************************************************************/
1379/**************************************************************************/
1380
1381#define FATAL(x...) fatal(__FUNCTION__, x)
1382
1383#if DEBUG
1384static void dump_fde(fdevent *fde, const char *info)
1385{
1386 fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
1387 fde->state & FDE_READ ? 'R' : ' ',
1388 fde->state & FDE_WRITE ? 'W' : ' ',
1389 fde->state & FDE_ERROR ? 'E' : ' ',
1390 info);
1391}
1392#else
1393#define dump_fde(fde, info) do { } while(0)
1394#endif
1395
1396#define FDE_EVENTMASK 0x00ff
1397#define FDE_STATEMASK 0xff00
1398
1399#define FDE_ACTIVE 0x0100
1400#define FDE_PENDING 0x0200
1401#define FDE_CREATED 0x0400
1402
1403static void fdevent_plist_enqueue(fdevent *node);
1404static void fdevent_plist_remove(fdevent *node);
1405static fdevent *fdevent_plist_dequeue(void);
1406
1407static fdevent list_pending = {
1408 .next = &list_pending,
1409 .prev = &list_pending,
1410};
1411
1412static fdevent **fd_table = 0;
1413static int fd_table_max = 0;
1414
1415typedef struct EventLooperRec_* EventLooper;
1416
1417typedef struct EventHookRec_
1418{
1419 EventHook next;
1420 FH fh;
1421 HANDLE h;
1422 int wanted; /* wanted event flags */
1423 int ready; /* ready event flags */
1424 void* aux;
1425 void (*prepare)( EventHook hook );
1426 int (*start) ( EventHook hook );
1427 void (*stop) ( EventHook hook );
1428 int (*check) ( EventHook hook );
1429 int (*peek) ( EventHook hook );
1430} EventHookRec;
1431
1432static EventHook _free_hooks;
1433
1434static EventHook
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001435event_hook_alloc(FH fh) {
1436 EventHook hook = _free_hooks;
1437 if (hook != NULL) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001438 _free_hooks = hook->next;
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001439 } else {
1440 hook = reinterpret_cast<EventHook>(malloc(sizeof(*hook)));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001441 if (hook == NULL)
1442 fatal( "could not allocate event hook\n" );
1443 }
1444 hook->next = NULL;
1445 hook->fh = fh;
1446 hook->wanted = 0;
1447 hook->ready = 0;
1448 hook->h = INVALID_HANDLE_VALUE;
1449 hook->aux = NULL;
1450
1451 hook->prepare = NULL;
1452 hook->start = NULL;
1453 hook->stop = NULL;
1454 hook->check = NULL;
1455 hook->peek = NULL;
1456
1457 return hook;
1458}
1459
1460static void
1461event_hook_free( EventHook hook )
1462{
1463 hook->fh = NULL;
1464 hook->wanted = 0;
1465 hook->ready = 0;
1466 hook->next = _free_hooks;
1467 _free_hooks = hook;
1468}
1469
1470
1471static void
1472event_hook_signal( EventHook hook )
1473{
1474 FH f = hook->fh;
1475 int fd = _fh_to_int(f);
1476 fdevent* fde = fd_table[ fd - WIN32_FH_BASE ];
1477
1478 if (fde != NULL && fde->fd == fd) {
1479 if ((fde->state & FDE_PENDING) == 0) {
1480 fde->state |= FDE_PENDING;
1481 fdevent_plist_enqueue( fde );
1482 }
1483 fde->events |= hook->wanted;
1484 }
1485}
1486
1487
1488#define MAX_LOOPER_HANDLES WIN32_MAX_FHS
1489
1490typedef struct EventLooperRec_
1491{
1492 EventHook hooks;
1493 HANDLE htab[ MAX_LOOPER_HANDLES ];
1494 int htab_count;
1495
1496} EventLooperRec;
1497
1498static EventHook*
1499event_looper_find_p( EventLooper looper, FH fh )
1500{
1501 EventHook *pnode = &looper->hooks;
1502 EventHook node = *pnode;
1503 for (;;) {
1504 if ( node == NULL || node->fh == fh )
1505 break;
1506 pnode = &node->next;
1507 node = *pnode;
1508 }
1509 return pnode;
1510}
1511
1512static void
1513event_looper_hook( EventLooper looper, int fd, int events )
1514{
Spencer Low6ac5d7d2015-05-22 20:09:06 -07001515 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001516 EventHook *pnode;
1517 EventHook node;
1518
1519 if (f == NULL) /* invalid arg */ {
1520 D("event_looper_hook: invalid fd=%d\n", fd);
1521 return;
1522 }
1523
1524 pnode = event_looper_find_p( looper, f );
1525 node = *pnode;
1526 if ( node == NULL ) {
1527 node = event_hook_alloc( f );
1528 node->next = *pnode;
1529 *pnode = node;
1530 }
1531
1532 if ( (node->wanted & events) != events ) {
1533 /* this should update start/stop/check/peek */
1534 D("event_looper_hook: call hook for %d (new=%x, old=%x)\n",
1535 fd, node->wanted, events);
1536 f->clazz->_fh_hook( f, events & ~node->wanted, node );
1537 node->wanted |= events;
1538 } else {
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001539 D("event_looper_hook: ignoring events %x for %d wanted=%x)\n",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001540 events, fd, node->wanted);
1541 }
1542}
1543
1544static void
1545event_looper_unhook( EventLooper looper, int fd, int events )
1546{
Spencer Low6ac5d7d2015-05-22 20:09:06 -07001547 FH fh = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001548 EventHook *pnode = event_looper_find_p( looper, fh );
1549 EventHook node = *pnode;
1550
1551 if (node != NULL) {
1552 int events2 = events & node->wanted;
1553 if ( events2 == 0 ) {
1554 D( "event_looper_unhook: events %x not registered for fd %d\n", events, fd );
1555 return;
1556 }
1557 node->wanted &= ~events2;
1558 if (!node->wanted) {
1559 *pnode = node->next;
1560 event_hook_free( node );
1561 }
1562 }
1563}
1564
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001565/*
1566 * A fixer for WaitForMultipleObjects on condition that there are more than 64
1567 * handles to wait on.
1568 *
1569 * In cetain cases DDMS may establish more than 64 connections with ADB. For
1570 * instance, this may happen if there are more than 64 processes running on a
1571 * device, or there are multiple devices connected (including the emulator) with
1572 * the combined number of running processes greater than 64. In this case using
1573 * WaitForMultipleObjects to wait on connection events simply wouldn't cut,
1574 * because of the API limitations (64 handles max). So, we need to provide a way
1575 * to scale WaitForMultipleObjects to accept an arbitrary number of handles. The
1576 * easiest (and "Microsoft recommended") way to do that would be dividing the
1577 * handle array into chunks with the chunk size less than 64, and fire up as many
1578 * waiting threads as there are chunks. Then each thread would wait on a chunk of
1579 * handles, and will report back to the caller which handle has been set.
1580 * Here is the implementation of that algorithm.
1581 */
1582
1583/* Number of handles to wait on in each wating thread. */
1584#define WAIT_ALL_CHUNK_SIZE 63
1585
1586/* Descriptor for a wating thread */
1587typedef struct WaitForAllParam {
1588 /* A handle to an event to signal when waiting is over. This handle is shared
1589 * accross all the waiting threads, so each waiting thread knows when any
1590 * other thread has exited, so it can exit too. */
1591 HANDLE main_event;
1592 /* Upon exit from a waiting thread contains the index of the handle that has
1593 * been signaled. The index is an absolute index of the signaled handle in
1594 * the original array. This pointer is shared accross all the waiting threads
1595 * and it's not guaranteed (due to a race condition) that when all the
1596 * waiting threads exit, the value contained here would indicate the first
1597 * handle that was signaled. This is fine, because the caller cares only
1598 * about any handle being signaled. It doesn't care about the order, nor
1599 * about the whole list of handles that were signaled. */
1600 LONG volatile *signaled_index;
1601 /* Array of handles to wait on in a waiting thread. */
1602 HANDLE* handles;
1603 /* Number of handles in 'handles' array to wait on. */
1604 int handles_count;
1605 /* Index inside the main array of the first handle in the 'handles' array. */
1606 int first_handle_index;
1607 /* Waiting thread handle. */
1608 HANDLE thread;
1609} WaitForAllParam;
1610
1611/* Waiting thread routine. */
1612static unsigned __stdcall
1613_in_waiter_thread(void* arg)
1614{
1615 HANDLE wait_on[WAIT_ALL_CHUNK_SIZE + 1];
1616 int res;
1617 WaitForAllParam* const param = (WaitForAllParam*)arg;
1618
1619 /* We have to wait on the main_event in order to be notified when any of the
1620 * sibling threads is exiting. */
1621 wait_on[0] = param->main_event;
1622 /* The rest of the handles go behind the main event handle. */
1623 memcpy(wait_on + 1, param->handles, param->handles_count * sizeof(HANDLE));
1624
1625 res = WaitForMultipleObjects(param->handles_count + 1, wait_on, FALSE, INFINITE);
1626 if (res > 0 && res < (param->handles_count + 1)) {
1627 /* One of the original handles got signaled. Save its absolute index into
1628 * the output variable. */
1629 InterlockedCompareExchange(param->signaled_index,
1630 res - 1L + param->first_handle_index, -1L);
1631 }
1632
1633 /* Notify the caller (and the siblings) that the wait is over. */
1634 SetEvent(param->main_event);
1635
1636 _endthreadex(0);
1637 return 0;
1638}
1639
1640/* WaitForMultipeObjects fixer routine.
1641 * Param:
1642 * handles Array of handles to wait on.
1643 * handles_count Number of handles in the array.
1644 * Return:
1645 * (>= 0 && < handles_count) - Index of the signaled handle in the array, or
1646 * WAIT_FAILED on an error.
1647 */
1648static int
1649_wait_for_all(HANDLE* handles, int handles_count)
1650{
1651 WaitForAllParam* threads;
1652 HANDLE main_event;
1653 int chunks, chunk, remains;
1654
1655 /* This variable is going to be accessed by several threads at the same time,
1656 * this is bound to fail randomly when the core is run on multi-core machines.
1657 * To solve this, we need to do the following (1 _and_ 2):
1658 * 1. Use the "volatile" qualifier to ensure the compiler doesn't optimize
1659 * out the reads/writes in this function unexpectedly.
1660 * 2. Ensure correct memory ordering. The "simple" way to do that is to wrap
1661 * all accesses inside a critical section. But we can also use
1662 * InterlockedCompareExchange() which always provide a full memory barrier
1663 * on Win32.
1664 */
1665 volatile LONG sig_index = -1;
1666
1667 /* Calculate number of chunks, and allocate thread param array. */
1668 chunks = handles_count / WAIT_ALL_CHUNK_SIZE;
1669 remains = handles_count % WAIT_ALL_CHUNK_SIZE;
1670 threads = (WaitForAllParam*)malloc((chunks + (remains ? 1 : 0)) *
1671 sizeof(WaitForAllParam));
1672 if (threads == NULL) {
Spencer Low8d8126a2015-07-21 02:06:26 -07001673 D("Unable to allocate thread array for %d handles.\n", handles_count);
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001674 return (int)WAIT_FAILED;
1675 }
1676
1677 /* Create main event to wait on for all waiting threads. This is a "manualy
1678 * reset" event that will remain set once it was set. */
1679 main_event = CreateEvent(NULL, TRUE, FALSE, NULL);
1680 if (main_event == NULL) {
Spencer Low8d8126a2015-07-21 02:06:26 -07001681 D("Unable to create main event. Error: %ld\n", GetLastError());
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001682 free(threads);
1683 return (int)WAIT_FAILED;
1684 }
1685
1686 /*
1687 * Initialize waiting thread parameters.
1688 */
1689
1690 for (chunk = 0; chunk < chunks; chunk++) {
1691 threads[chunk].main_event = main_event;
1692 threads[chunk].signaled_index = &sig_index;
1693 threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
1694 threads[chunk].handles = handles + threads[chunk].first_handle_index;
1695 threads[chunk].handles_count = WAIT_ALL_CHUNK_SIZE;
1696 }
1697 if (remains) {
1698 threads[chunk].main_event = main_event;
1699 threads[chunk].signaled_index = &sig_index;
1700 threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
1701 threads[chunk].handles = handles + threads[chunk].first_handle_index;
1702 threads[chunk].handles_count = remains;
1703 chunks++;
1704 }
1705
1706 /* Start the waiting threads. */
1707 for (chunk = 0; chunk < chunks; chunk++) {
1708 /* Note that using adb_thread_create is not appropriate here, since we
1709 * need a handle to wait on for thread termination. */
1710 threads[chunk].thread = (HANDLE)_beginthreadex(NULL, 0, _in_waiter_thread,
1711 &threads[chunk], 0, NULL);
1712 if (threads[chunk].thread == NULL) {
1713 /* Unable to create a waiter thread. Collapse. */
Spencer Low8d8126a2015-07-21 02:06:26 -07001714 D("Unable to create a waiting thread %d of %d. errno=%d\n",
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001715 chunk, chunks, errno);
1716 chunks = chunk;
1717 SetEvent(main_event);
1718 break;
1719 }
1720 }
1721
1722 /* Wait on any of the threads to get signaled. */
1723 WaitForSingleObject(main_event, INFINITE);
1724
1725 /* Wait on all the waiting threads to exit. */
1726 for (chunk = 0; chunk < chunks; chunk++) {
1727 WaitForSingleObject(threads[chunk].thread, INFINITE);
1728 CloseHandle(threads[chunk].thread);
1729 }
1730
1731 CloseHandle(main_event);
1732 free(threads);
1733
1734
1735 const int ret = (int)InterlockedCompareExchange(&sig_index, -1, -1);
1736 return (ret >= 0) ? ret : (int)WAIT_FAILED;
1737}
1738
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001739static EventLooperRec win32_looper;
1740
1741static void fdevent_init(void)
1742{
1743 win32_looper.htab_count = 0;
1744 win32_looper.hooks = NULL;
1745}
1746
1747static void fdevent_connect(fdevent *fde)
1748{
1749 EventLooper looper = &win32_looper;
1750 int events = fde->state & FDE_EVENTMASK;
1751
1752 if (events != 0)
1753 event_looper_hook( looper, fde->fd, events );
1754}
1755
1756static void fdevent_disconnect(fdevent *fde)
1757{
1758 EventLooper looper = &win32_looper;
1759 int events = fde->state & FDE_EVENTMASK;
1760
1761 if (events != 0)
1762 event_looper_unhook( looper, fde->fd, events );
1763}
1764
1765static void fdevent_update(fdevent *fde, unsigned events)
1766{
1767 EventLooper looper = &win32_looper;
1768 unsigned events0 = fde->state & FDE_EVENTMASK;
1769
1770 if (events != events0) {
1771 int removes = events0 & ~events;
1772 int adds = events & ~events0;
1773 if (removes) {
1774 D("fdevent_update: remove %x from %d\n", removes, fde->fd);
1775 event_looper_unhook( looper, fde->fd, removes );
1776 }
1777 if (adds) {
1778 D("fdevent_update: add %x to %d\n", adds, fde->fd);
1779 event_looper_hook ( looper, fde->fd, adds );
1780 }
1781 }
1782}
1783
1784static void fdevent_process()
1785{
1786 EventLooper looper = &win32_looper;
1787 EventHook hook;
1788 int gotone = 0;
1789
1790 /* if we have at least one ready hook, execute it/them */
1791 for (hook = looper->hooks; hook; hook = hook->next) {
1792 hook->ready = 0;
1793 if (hook->prepare) {
1794 hook->prepare(hook);
1795 if (hook->ready != 0) {
1796 event_hook_signal( hook );
1797 gotone = 1;
1798 }
1799 }
1800 }
1801
1802 /* nothing's ready yet, so wait for something to happen */
1803 if (!gotone)
1804 {
1805 looper->htab_count = 0;
1806
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001807 for (hook = looper->hooks; hook; hook = hook->next)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001808 {
1809 if (hook->start && !hook->start(hook)) {
1810 D( "fdevent_process: error when starting a hook\n" );
1811 return;
1812 }
1813 if (hook->h != INVALID_HANDLE_VALUE) {
1814 int nn;
1815
1816 for (nn = 0; nn < looper->htab_count; nn++)
1817 {
1818 if ( looper->htab[nn] == hook->h )
1819 goto DontAdd;
1820 }
1821 looper->htab[ looper->htab_count++ ] = hook->h;
1822 DontAdd:
1823 ;
1824 }
1825 }
1826
1827 if (looper->htab_count == 0) {
1828 D( "fdevent_process: nothing to wait for !!\n" );
1829 return;
1830 }
1831
1832 do
1833 {
1834 int wait_ret;
1835
1836 D( "adb_win32: waiting for %d events\n", looper->htab_count );
1837 if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) {
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001838 D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS.\n", looper->htab_count);
1839 wait_ret = _wait_for_all(looper->htab, looper->htab_count);
1840 } else {
1841 wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001842 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001843 if (wait_ret == (int)WAIT_FAILED) {
1844 D( "adb_win32: wait failed, error %ld\n", GetLastError() );
1845 } else {
1846 D( "adb_win32: got one (index %d)\n", wait_ret );
1847
1848 /* according to Cygwin, some objects like consoles wake up on "inappropriate" events
1849 * like mouse movements. we need to filter these with the "check" function
1850 */
1851 if ((unsigned)wait_ret < (unsigned)looper->htab_count)
1852 {
1853 for (hook = looper->hooks; hook; hook = hook->next)
1854 {
1855 if ( looper->htab[wait_ret] == hook->h &&
1856 (!hook->check || hook->check(hook)) )
1857 {
1858 D( "adb_win32: signaling %s for %x\n", hook->fh->name, hook->ready );
1859 event_hook_signal( hook );
1860 gotone = 1;
1861 break;
1862 }
1863 }
1864 }
1865 }
1866 }
1867 while (!gotone);
1868
1869 for (hook = looper->hooks; hook; hook = hook->next) {
1870 if (hook->stop)
1871 hook->stop( hook );
1872 }
1873 }
1874
1875 for (hook = looper->hooks; hook; hook = hook->next) {
1876 if (hook->peek && hook->peek(hook))
1877 event_hook_signal( hook );
1878 }
1879}
1880
1881
1882static void fdevent_register(fdevent *fde)
1883{
1884 int fd = fde->fd - WIN32_FH_BASE;
1885
1886 if(fd < 0) {
1887 FATAL("bogus negative fd (%d)\n", fde->fd);
1888 }
1889
1890 if(fd >= fd_table_max) {
1891 int oldmax = fd_table_max;
1892 if(fde->fd > 32000) {
1893 FATAL("bogus huuuuge fd (%d)\n", fde->fd);
1894 }
1895 if(fd_table_max == 0) {
1896 fdevent_init();
1897 fd_table_max = 256;
1898 }
1899 while(fd_table_max <= fd) {
1900 fd_table_max *= 2;
1901 }
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001902 fd_table = reinterpret_cast<fdevent**>(realloc(fd_table, sizeof(fdevent*) * fd_table_max));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001903 if(fd_table == 0) {
1904 FATAL("could not expand fd_table to %d entries\n", fd_table_max);
1905 }
1906 memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
1907 }
1908
1909 fd_table[fd] = fde;
1910}
1911
1912static void fdevent_unregister(fdevent *fde)
1913{
1914 int fd = fde->fd - WIN32_FH_BASE;
1915
1916 if((fd < 0) || (fd >= fd_table_max)) {
1917 FATAL("fd out of range (%d)\n", fde->fd);
1918 }
1919
1920 if(fd_table[fd] != fde) {
1921 FATAL("fd_table out of sync");
1922 }
1923
1924 fd_table[fd] = 0;
1925
1926 if(!(fde->state & FDE_DONT_CLOSE)) {
1927 dump_fde(fde, "close");
1928 adb_close(fde->fd);
1929 }
1930}
1931
1932static void fdevent_plist_enqueue(fdevent *node)
1933{
1934 fdevent *list = &list_pending;
1935
1936 node->next = list;
1937 node->prev = list->prev;
1938 node->prev->next = node;
1939 list->prev = node;
1940}
1941
1942static void fdevent_plist_remove(fdevent *node)
1943{
1944 node->prev->next = node->next;
1945 node->next->prev = node->prev;
1946 node->next = 0;
1947 node->prev = 0;
1948}
1949
1950static fdevent *fdevent_plist_dequeue(void)
1951{
1952 fdevent *list = &list_pending;
1953 fdevent *node = list->next;
1954
1955 if(node == list) return 0;
1956
1957 list->next = node->next;
1958 list->next->prev = list;
1959 node->next = 0;
1960 node->prev = 0;
1961
1962 return node;
1963}
1964
1965fdevent *fdevent_create(int fd, fd_func func, void *arg)
1966{
1967 fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
1968 if(fde == 0) return 0;
1969 fdevent_install(fde, fd, func, arg);
1970 fde->state |= FDE_CREATED;
1971 return fde;
1972}
1973
1974void fdevent_destroy(fdevent *fde)
1975{
1976 if(fde == 0) return;
1977 if(!(fde->state & FDE_CREATED)) {
1978 FATAL("fde %p not created by fdevent_create()\n", fde);
1979 }
1980 fdevent_remove(fde);
1981}
1982
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001983void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001984{
1985 memset(fde, 0, sizeof(fdevent));
1986 fde->state = FDE_ACTIVE;
1987 fde->fd = fd;
1988 fde->func = func;
1989 fde->arg = arg;
1990
1991 fdevent_register(fde);
1992 dump_fde(fde, "connect");
1993 fdevent_connect(fde);
1994 fde->state |= FDE_ACTIVE;
1995}
1996
1997void fdevent_remove(fdevent *fde)
1998{
1999 if(fde->state & FDE_PENDING) {
2000 fdevent_plist_remove(fde);
2001 }
2002
2003 if(fde->state & FDE_ACTIVE) {
2004 fdevent_disconnect(fde);
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08002005 dump_fde(fde, "disconnect");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002006 fdevent_unregister(fde);
2007 }
2008
2009 fde->state = 0;
2010 fde->events = 0;
2011}
2012
2013
2014void fdevent_set(fdevent *fde, unsigned events)
2015{
2016 events &= FDE_EVENTMASK;
2017
2018 if((fde->state & FDE_EVENTMASK) == (int)events) return;
2019
2020 if(fde->state & FDE_ACTIVE) {
2021 fdevent_update(fde, events);
2022 dump_fde(fde, "update");
2023 }
2024
2025 fde->state = (fde->state & FDE_STATEMASK) | events;
2026
2027 if(fde->state & FDE_PENDING) {
2028 /* if we're pending, make sure
2029 ** we don't signal an event that
2030 ** is no longer wanted.
2031 */
2032 fde->events &= (~events);
2033 if(fde->events == 0) {
2034 fdevent_plist_remove(fde);
2035 fde->state &= (~FDE_PENDING);
2036 }
2037 }
2038}
2039
2040void fdevent_add(fdevent *fde, unsigned events)
2041{
2042 fdevent_set(
2043 fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
2044}
2045
2046void fdevent_del(fdevent *fde, unsigned events)
2047{
2048 fdevent_set(
2049 fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
2050}
2051
2052void fdevent_loop()
2053{
2054 fdevent *fde;
2055
2056 for(;;) {
2057#if DEBUG
2058 fprintf(stderr,"--- ---- waiting for events\n");
2059#endif
2060 fdevent_process();
2061
2062 while((fde = fdevent_plist_dequeue())) {
2063 unsigned events = fde->events;
2064 fde->events = 0;
2065 fde->state &= (~FDE_PENDING);
2066 dump_fde(fde, "callback");
2067 fde->func(fde->fd, events, fde->arg);
2068 }
2069 }
2070}
2071
2072/** FILE EVENT HOOKS
2073 **/
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +02002074
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002075static void _event_file_prepare( EventHook hook )
2076{
2077 if (hook->wanted & (FDE_READ|FDE_WRITE)) {
2078 /* we can always read/write */
2079 hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE);
2080 }
2081}
2082
2083static int _event_file_peek( EventHook hook )
2084{
2085 return (hook->wanted & (FDE_READ|FDE_WRITE));
2086}
2087
2088static void _fh_file_hook( FH f, int events, EventHook hook )
2089{
2090 hook->h = f->fh_handle;
2091 hook->prepare = _event_file_prepare;
2092 hook->peek = _event_file_peek;
2093}
2094
2095/** SOCKET EVENT HOOKS
2096 **/
2097
2098static void _event_socket_verify( EventHook hook, WSANETWORKEVENTS* evts )
2099{
2100 if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) {
2101 if (hook->wanted & FDE_READ)
2102 hook->ready |= FDE_READ;
2103 if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR)
2104 hook->ready |= FDE_ERROR;
2105 }
2106 if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) {
2107 if (hook->wanted & FDE_WRITE)
2108 hook->ready |= FDE_WRITE;
2109 if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR)
2110 hook->ready |= FDE_ERROR;
2111 }
2112 if ( evts->lNetworkEvents & FD_OOB ) {
2113 if (hook->wanted & FDE_ERROR)
2114 hook->ready |= FDE_ERROR;
2115 }
2116}
2117
2118static void _event_socket_prepare( EventHook hook )
2119{
2120 WSANETWORKEVENTS evts;
2121
2122 /* look if some of the events we want already happened ? */
2123 if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts ))
2124 _event_socket_verify( hook, &evts );
2125}
2126
2127static int _socket_wanted_to_flags( int wanted )
2128{
2129 int flags = 0;
2130 if (wanted & FDE_READ)
2131 flags |= FD_READ | FD_ACCEPT | FD_CLOSE;
2132
2133 if (wanted & FDE_WRITE)
2134 flags |= FD_WRITE | FD_CONNECT | FD_CLOSE;
2135
2136 if (wanted & FDE_ERROR)
2137 flags |= FD_OOB;
2138
2139 return flags;
2140}
2141
2142static int _event_socket_start( EventHook hook )
2143{
2144 /* create an event which we're going to wait for */
2145 FH fh = hook->fh;
2146 long flags = _socket_wanted_to_flags( hook->wanted );
2147
2148 hook->h = fh->event;
2149 if (hook->h == INVALID_HANDLE_VALUE) {
2150 D( "_event_socket_start: no event for %s\n", fh->name );
2151 return 0;
2152 }
2153
2154 if ( flags != fh->mask ) {
2155 D( "_event_socket_start: hooking %s for %x (flags %ld)\n", hook->fh->name, hook->wanted, flags );
2156 if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) {
2157 D( "_event_socket_start: WSAEventSelect() for %s failed, error %d\n", hook->fh->name, WSAGetLastError() );
2158 CloseHandle( hook->h );
2159 hook->h = INVALID_HANDLE_VALUE;
2160 exit(1);
2161 return 0;
2162 }
2163 fh->mask = flags;
2164 }
2165 return 1;
2166}
2167
2168static void _event_socket_stop( EventHook hook )
2169{
2170 hook->h = INVALID_HANDLE_VALUE;
2171}
2172
2173static int _event_socket_check( EventHook hook )
2174{
2175 int result = 0;
2176 FH fh = hook->fh;
2177 WSANETWORKEVENTS evts;
2178
2179 if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) {
2180 _event_socket_verify( hook, &evts );
2181 result = (hook->ready != 0);
2182 if (result) {
2183 ResetEvent( hook->h );
2184 }
2185 }
2186 D( "_event_socket_check %s returns %d\n", fh->name, result );
2187 return result;
2188}
2189
2190static int _event_socket_peek( EventHook hook )
2191{
2192 WSANETWORKEVENTS evts;
2193 FH fh = hook->fh;
2194
2195 /* look if some of the events we want already happened ? */
2196 if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) {
2197 _event_socket_verify( hook, &evts );
2198 if (hook->ready)
2199 ResetEvent( hook->h );
2200 }
2201
2202 return hook->ready != 0;
2203}
2204
2205
2206
2207static void _fh_socket_hook( FH f, int events, EventHook hook )
2208{
2209 hook->prepare = _event_socket_prepare;
2210 hook->start = _event_socket_start;
2211 hook->stop = _event_socket_stop;
2212 hook->check = _event_socket_check;
2213 hook->peek = _event_socket_peek;
2214
Spencer Low5200c662015-07-30 23:07:55 -07002215 // TODO: check return value?
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002216 _event_socket_start( hook );
2217}
2218
2219/** SOCKETPAIR EVENT HOOKS
2220 **/
2221
2222static void _event_socketpair_prepare( EventHook hook )
2223{
2224 FH fh = hook->fh;
2225 SocketPair pair = fh->fh_pair;
2226 BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
2227 BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
2228
2229 if (hook->wanted & FDE_READ && rbip->can_read)
2230 hook->ready |= FDE_READ;
2231
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08002232 if (hook->wanted & FDE_WRITE && wbip->can_write)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002233 hook->ready |= FDE_WRITE;
2234 }
2235
2236 static int _event_socketpair_start( EventHook hook )
2237 {
2238 FH fh = hook->fh;
2239 SocketPair pair = fh->fh_pair;
2240 BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
2241 BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
2242
2243 if (hook->wanted == FDE_READ)
2244 hook->h = rbip->evt_read;
2245
2246 else if (hook->wanted == FDE_WRITE)
2247 hook->h = wbip->evt_write;
2248
2249 else {
2250 D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE\n" );
2251 return 0;
2252 }
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08002253 D( "_event_socketpair_start: hook %s for %x wanted=%x\n",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002254 hook->fh->name, _fh_to_int(fh), hook->wanted);
2255 return 1;
2256}
2257
2258static int _event_socketpair_peek( EventHook hook )
2259{
2260 _event_socketpair_prepare( hook );
2261 return hook->ready != 0;
2262}
2263
2264static void _fh_socketpair_hook( FH fh, int events, EventHook hook )
2265{
2266 hook->prepare = _event_socketpair_prepare;
2267 hook->start = _event_socketpair_start;
2268 hook->peek = _event_socketpair_peek;
2269}
2270
2271
2272void
2273adb_sysdeps_init( void )
2274{
2275#define ADB_MUTEX(x) InitializeCriticalSection( & x );
2276#include "mutex_list.h"
2277 InitializeCriticalSection( &_win32_lock );
2278}
2279
Spencer Low50184062015-03-01 15:06:21 -08002280/**************************************************************************/
2281/**************************************************************************/
2282/***** *****/
2283/***** Console Window Terminal Emulation *****/
2284/***** *****/
2285/**************************************************************************/
2286/**************************************************************************/
2287
2288// This reads input from a Win32 console window and translates it into Unix
2289// terminal-style sequences. This emulates mostly Gnome Terminal (in Normal
2290// mode, not Application mode), which itself emulates xterm. Gnome Terminal
2291// is emulated instead of xterm because it is probably more popular than xterm:
2292// Ubuntu's default Ctrl-Alt-T shortcut opens Gnome Terminal, Gnome Terminal
2293// supports modern fonts, etc. It seems best to emulate the terminal that most
2294// Android developers use because they'll fix apps (the shell, etc.) to keep
2295// working with that terminal's emulation.
2296//
2297// The point of this emulation is not to be perfect or to solve all issues with
2298// console windows on Windows, but to be better than the original code which
2299// just called read() (which called ReadFile(), which called ReadConsoleA())
2300// which did not support Ctrl-C, tab completion, shell input line editing
2301// keys, server echo, and more.
2302//
2303// This implementation reconfigures the console with SetConsoleMode(), then
2304// calls ReadConsoleInput() to get raw input which it remaps to Unix
2305// terminal-style sequences which is returned via unix_read() which is used
2306// by the 'adb shell' command.
2307//
2308// Code organization:
2309//
2310// * stdin_raw_init() and stdin_raw_restore() reconfigure the console.
2311// * unix_read() detects console windows (as opposed to pipes, files, etc.).
2312// * _console_read() is the main code of the emulation.
2313
2314
2315// Read an input record from the console; one that should be processed.
2316static bool _get_interesting_input_record_uncached(const HANDLE console,
2317 INPUT_RECORD* const input_record) {
2318 for (;;) {
2319 DWORD read_count = 0;
2320 memset(input_record, 0, sizeof(*input_record));
2321 if (!ReadConsoleInputA(console, input_record, 1, &read_count)) {
2322 D("_get_interesting_input_record_uncached: ReadConsoleInputA() "
2323 "failure, error %ld\n", GetLastError());
2324 errno = EIO;
2325 return false;
2326 }
2327
2328 if (read_count == 0) { // should be impossible
2329 fatal("ReadConsoleInputA returned 0");
2330 }
2331
2332 if (read_count != 1) { // should be impossible
2333 fatal("ReadConsoleInputA did not return one input record");
2334 }
2335
2336 if ((input_record->EventType == KEY_EVENT) &&
2337 (input_record->Event.KeyEvent.bKeyDown)) {
2338 if (input_record->Event.KeyEvent.wRepeatCount == 0) {
2339 fatal("ReadConsoleInputA returned a key event with zero repeat"
2340 " count");
2341 }
2342
2343 // Got an interesting INPUT_RECORD, so return
2344 return true;
2345 }
2346 }
2347}
2348
2349// Cached input record (in case _console_read() is passed a buffer that doesn't
2350// have enough space to fit wRepeatCount number of key sequences). A non-zero
2351// wRepeatCount indicates that a record is cached.
2352static INPUT_RECORD _win32_input_record;
2353
2354// Get the next KEY_EVENT_RECORD that should be processed.
2355static KEY_EVENT_RECORD* _get_key_event_record(const HANDLE console) {
2356 // If nothing cached, read directly from the console until we get an
2357 // interesting record.
2358 if (_win32_input_record.Event.KeyEvent.wRepeatCount == 0) {
2359 if (!_get_interesting_input_record_uncached(console,
2360 &_win32_input_record)) {
2361 // There was an error, so make sure wRepeatCount is zero because
2362 // that signifies no cached input record.
2363 _win32_input_record.Event.KeyEvent.wRepeatCount = 0;
2364 return NULL;
2365 }
2366 }
2367
2368 return &_win32_input_record.Event.KeyEvent;
2369}
2370
2371static __inline__ bool _is_shift_pressed(const DWORD control_key_state) {
2372 return (control_key_state & SHIFT_PRESSED) != 0;
2373}
2374
2375static __inline__ bool _is_ctrl_pressed(const DWORD control_key_state) {
2376 return (control_key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0;
2377}
2378
2379static __inline__ bool _is_alt_pressed(const DWORD control_key_state) {
2380 return (control_key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0;
2381}
2382
2383static __inline__ bool _is_numlock_on(const DWORD control_key_state) {
2384 return (control_key_state & NUMLOCK_ON) != 0;
2385}
2386
2387static __inline__ bool _is_capslock_on(const DWORD control_key_state) {
2388 return (control_key_state & CAPSLOCK_ON) != 0;
2389}
2390
2391static __inline__ bool _is_enhanced_key(const DWORD control_key_state) {
2392 return (control_key_state & ENHANCED_KEY) != 0;
2393}
2394
2395// Constants from MSDN for ToAscii().
2396static const BYTE TOASCII_KEY_OFF = 0x00;
2397static const BYTE TOASCII_KEY_DOWN = 0x80;
2398static const BYTE TOASCII_KEY_TOGGLED_ON = 0x01; // for CapsLock
2399
2400// Given a key event, ignore a modifier key and return the character that was
2401// entered without the modifier. Writes to *ch and returns the number of bytes
2402// written.
2403static size_t _get_char_ignoring_modifier(char* const ch,
2404 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state,
2405 const WORD modifier) {
2406 // If there is no character from Windows, try ignoring the specified
2407 // modifier and look for a character. Note that if AltGr is being used,
2408 // there will be a character from Windows.
2409 if (key_event->uChar.AsciiChar == '\0') {
2410 // Note that we read the control key state from the passed in argument
2411 // instead of from key_event since the argument has been normalized.
2412 if (((modifier == VK_SHIFT) &&
2413 _is_shift_pressed(control_key_state)) ||
2414 ((modifier == VK_CONTROL) &&
2415 _is_ctrl_pressed(control_key_state)) ||
2416 ((modifier == VK_MENU) && _is_alt_pressed(control_key_state))) {
2417
2418 BYTE key_state[256] = {0};
2419 key_state[VK_SHIFT] = _is_shift_pressed(control_key_state) ?
2420 TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
2421 key_state[VK_CONTROL] = _is_ctrl_pressed(control_key_state) ?
2422 TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
2423 key_state[VK_MENU] = _is_alt_pressed(control_key_state) ?
2424 TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
2425 key_state[VK_CAPITAL] = _is_capslock_on(control_key_state) ?
2426 TOASCII_KEY_TOGGLED_ON : TOASCII_KEY_OFF;
2427
2428 // cause this modifier to be ignored
2429 key_state[modifier] = TOASCII_KEY_OFF;
2430
2431 WORD translated = 0;
2432 if (ToAscii(key_event->wVirtualKeyCode,
2433 key_event->wVirtualScanCode, key_state, &translated, 0) == 1) {
2434 // Ignoring the modifier, we found a character.
2435 *ch = (CHAR)translated;
2436 return 1;
2437 }
2438 }
2439 }
2440
2441 // Just use whatever Windows told us originally.
2442 *ch = key_event->uChar.AsciiChar;
2443
2444 // If the character from Windows is NULL, return a size of zero.
2445 return (*ch == '\0') ? 0 : 1;
2446}
2447
2448// If a Ctrl key is pressed, lookup the character, ignoring the Ctrl key,
2449// but taking into account the shift key. This is because for a sequence like
2450// Ctrl-Alt-0, we want to find the character '0' and for Ctrl-Alt-Shift-0,
2451// we want to find the character ')'.
2452//
2453// Note that Windows doesn't seem to pass bKeyDown for Ctrl-Shift-NoAlt-0
2454// because it is the default key-sequence to switch the input language.
2455// This is configurable in the Region and Language control panel.
2456static __inline__ size_t _get_non_control_char(char* const ch,
2457 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
2458 return _get_char_ignoring_modifier(ch, key_event, control_key_state,
2459 VK_CONTROL);
2460}
2461
2462// Get without Alt.
2463static __inline__ size_t _get_non_alt_char(char* const ch,
2464 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
2465 return _get_char_ignoring_modifier(ch, key_event, control_key_state,
2466 VK_MENU);
2467}
2468
2469// Ignore the control key, find the character from Windows, and apply any
2470// Control key mappings (for example, Ctrl-2 is a NULL character). Writes to
2471// *pch and returns number of bytes written.
2472static size_t _get_control_character(char* const pch,
2473 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
2474 const size_t len = _get_non_control_char(pch, key_event,
2475 control_key_state);
2476
2477 if ((len == 1) && _is_ctrl_pressed(control_key_state)) {
2478 char ch = *pch;
2479 switch (ch) {
2480 case '2':
2481 case '@':
2482 case '`':
2483 ch = '\0';
2484 break;
2485 case '3':
2486 case '[':
2487 case '{':
2488 ch = '\x1b';
2489 break;
2490 case '4':
2491 case '\\':
2492 case '|':
2493 ch = '\x1c';
2494 break;
2495 case '5':
2496 case ']':
2497 case '}':
2498 ch = '\x1d';
2499 break;
2500 case '6':
2501 case '^':
2502 case '~':
2503 ch = '\x1e';
2504 break;
2505 case '7':
2506 case '-':
2507 case '_':
2508 ch = '\x1f';
2509 break;
2510 case '8':
2511 ch = '\x7f';
2512 break;
2513 case '/':
2514 if (!_is_alt_pressed(control_key_state)) {
2515 ch = '\x1f';
2516 }
2517 break;
2518 case '?':
2519 if (!_is_alt_pressed(control_key_state)) {
2520 ch = '\x7f';
2521 }
2522 break;
2523 }
2524 *pch = ch;
2525 }
2526
2527 return len;
2528}
2529
2530static DWORD _normalize_altgr_control_key_state(
2531 const KEY_EVENT_RECORD* const key_event) {
2532 DWORD control_key_state = key_event->dwControlKeyState;
2533
2534 // If we're in an AltGr situation where the AltGr key is down (depending on
2535 // the keyboard layout, that might be the physical right alt key which
2536 // produces a control_key_state where Right-Alt and Left-Ctrl are down) or
2537 // AltGr-equivalent keys are down (any Ctrl key + any Alt key), and we have
2538 // a character (which indicates that there was an AltGr mapping), then act
2539 // as if alt and control are not really down for the purposes of modifiers.
2540 // This makes it so that if the user with, say, a German keyboard layout
2541 // presses AltGr-] (which we see as Right-Alt + Left-Ctrl + key), we just
2542 // output the key and we don't see the Alt and Ctrl keys.
2543 if (_is_ctrl_pressed(control_key_state) &&
2544 _is_alt_pressed(control_key_state)
2545 && (key_event->uChar.AsciiChar != '\0')) {
2546 // Try to remove as few bits as possible to improve our chances of
2547 // detecting combinations like Left-Alt + AltGr, Right-Ctrl + AltGr, or
2548 // Left-Alt + Right-Ctrl + AltGr.
2549 if ((control_key_state & RIGHT_ALT_PRESSED) != 0) {
2550 // Remove Right-Alt.
2551 control_key_state &= ~RIGHT_ALT_PRESSED;
2552 // If uChar is set, a Ctrl key is pressed, and Right-Alt is
2553 // pressed, Left-Ctrl is almost always set, except if the user
2554 // presses Right-Ctrl, then AltGr (in that specific order) for
2555 // whatever reason. At any rate, make sure the bit is not set.
2556 control_key_state &= ~LEFT_CTRL_PRESSED;
2557 } else if ((control_key_state & LEFT_ALT_PRESSED) != 0) {
2558 // Remove Left-Alt.
2559 control_key_state &= ~LEFT_ALT_PRESSED;
2560 // Whichever Ctrl key is down, remove it from the state. We only
2561 // remove one key, to improve our chances of detecting the
2562 // corner-case of Left-Ctrl + Left-Alt + Right-Ctrl.
2563 if ((control_key_state & LEFT_CTRL_PRESSED) != 0) {
2564 // Remove Left-Ctrl.
2565 control_key_state &= ~LEFT_CTRL_PRESSED;
2566 } else if ((control_key_state & RIGHT_CTRL_PRESSED) != 0) {
2567 // Remove Right-Ctrl.
2568 control_key_state &= ~RIGHT_CTRL_PRESSED;
2569 }
2570 }
2571
2572 // Note that this logic isn't 100% perfect because Windows doesn't
2573 // allow us to detect all combinations because a physical AltGr key
2574 // press shows up as two bits, plus some combinations are ambiguous
2575 // about what is actually physically pressed.
2576 }
2577
2578 return control_key_state;
2579}
2580
2581// If NumLock is on and Shift is pressed, SHIFT_PRESSED is not set in
2582// dwControlKeyState for the following keypad keys: period, 0-9. If we detect
2583// this scenario, set the SHIFT_PRESSED bit so we can add modifiers
2584// appropriately.
2585static DWORD _normalize_keypad_control_key_state(const WORD vk,
2586 const DWORD control_key_state) {
2587 if (!_is_numlock_on(control_key_state)) {
2588 return control_key_state;
2589 }
2590 if (!_is_enhanced_key(control_key_state)) {
2591 switch (vk) {
2592 case VK_INSERT: // 0
2593 case VK_DELETE: // .
2594 case VK_END: // 1
2595 case VK_DOWN: // 2
2596 case VK_NEXT: // 3
2597 case VK_LEFT: // 4
2598 case VK_CLEAR: // 5
2599 case VK_RIGHT: // 6
2600 case VK_HOME: // 7
2601 case VK_UP: // 8
2602 case VK_PRIOR: // 9
2603 return control_key_state | SHIFT_PRESSED;
2604 }
2605 }
2606
2607 return control_key_state;
2608}
2609
2610static const char* _get_keypad_sequence(const DWORD control_key_state,
2611 const char* const normal, const char* const shifted) {
2612 if (_is_shift_pressed(control_key_state)) {
2613 // Shift is pressed and NumLock is off
2614 return shifted;
2615 } else {
2616 // Shift is not pressed and NumLock is off, or,
2617 // Shift is pressed and NumLock is on, in which case we want the
2618 // NumLock and Shift to neutralize each other, thus, we want the normal
2619 // sequence.
2620 return normal;
2621 }
2622 // If Shift is not pressed and NumLock is on, a different virtual key code
2623 // is returned by Windows, which can be taken care of by a different case
2624 // statement in _console_read().
2625}
2626
2627// Write sequence to buf and return the number of bytes written.
2628static size_t _get_modifier_sequence(char* const buf, const WORD vk,
2629 DWORD control_key_state, const char* const normal) {
2630 // Copy the base sequence into buf.
2631 const size_t len = strlen(normal);
2632 memcpy(buf, normal, len);
2633
2634 int code = 0;
2635
2636 control_key_state = _normalize_keypad_control_key_state(vk,
2637 control_key_state);
2638
2639 if (_is_shift_pressed(control_key_state)) {
2640 code |= 0x1;
2641 }
2642 if (_is_alt_pressed(control_key_state)) { // any alt key pressed
2643 code |= 0x2;
2644 }
2645 if (_is_ctrl_pressed(control_key_state)) { // any control key pressed
2646 code |= 0x4;
2647 }
2648 // If some modifier was held down, then we need to insert the modifier code
2649 if (code != 0) {
2650 if (len == 0) {
2651 // Should be impossible because caller should pass a string of
2652 // non-zero length.
2653 return 0;
2654 }
2655 size_t index = len - 1;
2656 const char lastChar = buf[index];
2657 if (lastChar != '~') {
2658 buf[index++] = '1';
2659 }
2660 buf[index++] = ';'; // modifier separator
2661 // 2 = shift, 3 = alt, 4 = shift & alt, 5 = control,
2662 // 6 = shift & control, 7 = alt & control, 8 = shift & alt & control
2663 buf[index++] = '1' + code;
2664 buf[index++] = lastChar; // move ~ (or other last char) to the end
2665 return index;
2666 }
2667 return len;
2668}
2669
2670// Write sequence to buf and return the number of bytes written.
2671static size_t _get_modifier_keypad_sequence(char* const buf, const WORD vk,
2672 const DWORD control_key_state, const char* const normal,
2673 const char shifted) {
2674 if (_is_shift_pressed(control_key_state)) {
2675 // Shift is pressed and NumLock is off
2676 if (shifted != '\0') {
2677 buf[0] = shifted;
2678 return sizeof(buf[0]);
2679 } else {
2680 return 0;
2681 }
2682 } else {
2683 // Shift is not pressed and NumLock is off, or,
2684 // Shift is pressed and NumLock is on, in which case we want the
2685 // NumLock and Shift to neutralize each other, thus, we want the normal
2686 // sequence.
2687 return _get_modifier_sequence(buf, vk, control_key_state, normal);
2688 }
2689 // If Shift is not pressed and NumLock is on, a different virtual key code
2690 // is returned by Windows, which can be taken care of by a different case
2691 // statement in _console_read().
2692}
2693
2694// The decimal key on the keypad produces a '.' for U.S. English and a ',' for
2695// Standard German. Figure this out at runtime so we know what to output for
2696// Shift-VK_DELETE.
2697static char _get_decimal_char() {
2698 return (char)MapVirtualKeyA(VK_DECIMAL, MAPVK_VK_TO_CHAR);
2699}
2700
2701// Prefix the len bytes in buf with the escape character, and then return the
2702// new buffer length.
2703size_t _escape_prefix(char* const buf, const size_t len) {
2704 // If nothing to prefix, don't do anything. We might be called with
2705 // len == 0, if alt was held down with a dead key which produced nothing.
2706 if (len == 0) {
2707 return 0;
2708 }
2709
2710 memmove(&buf[1], buf, len);
2711 buf[0] = '\x1b';
2712 return len + 1;
2713}
2714
2715// Writes to buffer buf (of length len), returning number of bytes written or
2716// -1 on error. Never returns zero because Win32 consoles are never 'closed'
2717// (as far as I can tell).
2718static int _console_read(const HANDLE console, void* buf, size_t len) {
2719 for (;;) {
2720 KEY_EVENT_RECORD* const key_event = _get_key_event_record(console);
2721 if (key_event == NULL) {
2722 return -1;
2723 }
2724
2725 const WORD vk = key_event->wVirtualKeyCode;
2726 const CHAR ch = key_event->uChar.AsciiChar;
2727 const DWORD control_key_state = _normalize_altgr_control_key_state(
2728 key_event);
2729
2730 // The following emulation code should write the output sequence to
2731 // either seqstr or to seqbuf and seqbuflen.
2732 const char* seqstr = NULL; // NULL terminated C-string
2733 // Enough space for max sequence string below, plus modifiers and/or
2734 // escape prefix.
2735 char seqbuf[16];
2736 size_t seqbuflen = 0; // Space used in seqbuf.
2737
2738#define MATCH(vk, normal) \
2739 case (vk): \
2740 { \
2741 seqstr = (normal); \
2742 } \
2743 break;
2744
2745 // Modifier keys should affect the output sequence.
2746#define MATCH_MODIFIER(vk, normal) \
2747 case (vk): \
2748 { \
2749 seqbuflen = _get_modifier_sequence(seqbuf, (vk), \
2750 control_key_state, (normal)); \
2751 } \
2752 break;
2753
2754 // The shift key should affect the output sequence.
2755#define MATCH_KEYPAD(vk, normal, shifted) \
2756 case (vk): \
2757 { \
2758 seqstr = _get_keypad_sequence(control_key_state, (normal), \
2759 (shifted)); \
2760 } \
2761 break;
2762
2763 // The shift key and other modifier keys should affect the output
2764 // sequence.
2765#define MATCH_MODIFIER_KEYPAD(vk, normal, shifted) \
2766 case (vk): \
2767 { \
2768 seqbuflen = _get_modifier_keypad_sequence(seqbuf, (vk), \
2769 control_key_state, (normal), (shifted)); \
2770 } \
2771 break;
2772
2773#define ESC "\x1b"
2774#define CSI ESC "["
2775#define SS3 ESC "O"
2776
2777 // Only support normal mode, not application mode.
2778
2779 // Enhanced keys:
2780 // * 6-pack: insert, delete, home, end, page up, page down
2781 // * cursor keys: up, down, right, left
2782 // * keypad: divide, enter
2783 // * Undocumented: VK_PAUSE (Ctrl-NumLock), VK_SNAPSHOT,
2784 // VK_CANCEL (Ctrl-Pause/Break), VK_NUMLOCK
2785 if (_is_enhanced_key(control_key_state)) {
2786 switch (vk) {
2787 case VK_RETURN: // Enter key on keypad
2788 if (_is_ctrl_pressed(control_key_state)) {
2789 seqstr = "\n";
2790 } else {
2791 seqstr = "\r";
2792 }
2793 break;
2794
2795 MATCH_MODIFIER(VK_PRIOR, CSI "5~"); // Page Up
2796 MATCH_MODIFIER(VK_NEXT, CSI "6~"); // Page Down
2797
2798 // gnome-terminal currently sends SS3 "F" and SS3 "H", but that
2799 // will be fixed soon to match xterm which sends CSI "F" and
2800 // CSI "H". https://bugzilla.redhat.com/show_bug.cgi?id=1119764
2801 MATCH(VK_END, CSI "F");
2802 MATCH(VK_HOME, CSI "H");
2803
2804 MATCH_MODIFIER(VK_LEFT, CSI "D");
2805 MATCH_MODIFIER(VK_UP, CSI "A");
2806 MATCH_MODIFIER(VK_RIGHT, CSI "C");
2807 MATCH_MODIFIER(VK_DOWN, CSI "B");
2808
2809 MATCH_MODIFIER(VK_INSERT, CSI "2~");
2810 MATCH_MODIFIER(VK_DELETE, CSI "3~");
2811
2812 MATCH(VK_DIVIDE, "/");
2813 }
2814 } else { // Non-enhanced keys:
2815 switch (vk) {
2816 case VK_BACK: // backspace
2817 if (_is_alt_pressed(control_key_state)) {
2818 seqstr = ESC "\x7f";
2819 } else {
2820 seqstr = "\x7f";
2821 }
2822 break;
2823
2824 case VK_TAB:
2825 if (_is_shift_pressed(control_key_state)) {
2826 seqstr = CSI "Z";
2827 } else {
2828 seqstr = "\t";
2829 }
2830 break;
2831
2832 // Number 5 key in keypad when NumLock is off, or if NumLock is
2833 // on and Shift is down.
2834 MATCH_KEYPAD(VK_CLEAR, CSI "E", "5");
2835
2836 case VK_RETURN: // Enter key on main keyboard
2837 if (_is_alt_pressed(control_key_state)) {
2838 seqstr = ESC "\n";
2839 } else if (_is_ctrl_pressed(control_key_state)) {
2840 seqstr = "\n";
2841 } else {
2842 seqstr = "\r";
2843 }
2844 break;
2845
2846 // VK_ESCAPE: Don't do any special handling. The OS uses many
2847 // of the sequences with Escape and many of the remaining
2848 // sequences don't produce bKeyDown messages, only !bKeyDown
2849 // for whatever reason.
2850
2851 case VK_SPACE:
2852 if (_is_alt_pressed(control_key_state)) {
2853 seqstr = ESC " ";
2854 } else if (_is_ctrl_pressed(control_key_state)) {
2855 seqbuf[0] = '\0'; // NULL char
2856 seqbuflen = 1;
2857 } else {
2858 seqstr = " ";
2859 }
2860 break;
2861
2862 MATCH_MODIFIER_KEYPAD(VK_PRIOR, CSI "5~", '9'); // Page Up
2863 MATCH_MODIFIER_KEYPAD(VK_NEXT, CSI "6~", '3'); // Page Down
2864
2865 MATCH_KEYPAD(VK_END, CSI "4~", "1");
2866 MATCH_KEYPAD(VK_HOME, CSI "1~", "7");
2867
2868 MATCH_MODIFIER_KEYPAD(VK_LEFT, CSI "D", '4');
2869 MATCH_MODIFIER_KEYPAD(VK_UP, CSI "A", '8');
2870 MATCH_MODIFIER_KEYPAD(VK_RIGHT, CSI "C", '6');
2871 MATCH_MODIFIER_KEYPAD(VK_DOWN, CSI "B", '2');
2872
2873 MATCH_MODIFIER_KEYPAD(VK_INSERT, CSI "2~", '0');
2874 MATCH_MODIFIER_KEYPAD(VK_DELETE, CSI "3~",
2875 _get_decimal_char());
2876
2877 case 0x30: // 0
2878 case 0x31: // 1
2879 case 0x39: // 9
2880 case VK_OEM_1: // ;:
2881 case VK_OEM_PLUS: // =+
2882 case VK_OEM_COMMA: // ,<
2883 case VK_OEM_PERIOD: // .>
2884 case VK_OEM_7: // '"
2885 case VK_OEM_102: // depends on keyboard, could be <> or \|
2886 case VK_OEM_2: // /?
2887 case VK_OEM_3: // `~
2888 case VK_OEM_4: // [{
2889 case VK_OEM_5: // \|
2890 case VK_OEM_6: // ]}
2891 {
2892 seqbuflen = _get_control_character(seqbuf, key_event,
2893 control_key_state);
2894
2895 if (_is_alt_pressed(control_key_state)) {
2896 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
2897 }
2898 }
2899 break;
2900
2901 case 0x32: // 2
2902 case 0x36: // 6
2903 case VK_OEM_MINUS: // -_
2904 {
2905 seqbuflen = _get_control_character(seqbuf, key_event,
2906 control_key_state);
2907
2908 // If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
2909 // prefix with escape.
2910 if (_is_alt_pressed(control_key_state) &&
2911 !(_is_ctrl_pressed(control_key_state) &&
2912 !_is_shift_pressed(control_key_state))) {
2913 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
2914 }
2915 }
2916 break;
2917
2918 case 0x33: // 3
2919 case 0x34: // 4
2920 case 0x35: // 5
2921 case 0x37: // 7
2922 case 0x38: // 8
2923 {
2924 seqbuflen = _get_control_character(seqbuf, key_event,
2925 control_key_state);
2926
2927 // If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
2928 // prefix with escape.
2929 if (_is_alt_pressed(control_key_state) &&
2930 !(_is_ctrl_pressed(control_key_state) &&
2931 !_is_shift_pressed(control_key_state))) {
2932 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
2933 }
2934 }
2935 break;
2936
2937 case 0x41: // a
2938 case 0x42: // b
2939 case 0x43: // c
2940 case 0x44: // d
2941 case 0x45: // e
2942 case 0x46: // f
2943 case 0x47: // g
2944 case 0x48: // h
2945 case 0x49: // i
2946 case 0x4a: // j
2947 case 0x4b: // k
2948 case 0x4c: // l
2949 case 0x4d: // m
2950 case 0x4e: // n
2951 case 0x4f: // o
2952 case 0x50: // p
2953 case 0x51: // q
2954 case 0x52: // r
2955 case 0x53: // s
2956 case 0x54: // t
2957 case 0x55: // u
2958 case 0x56: // v
2959 case 0x57: // w
2960 case 0x58: // x
2961 case 0x59: // y
2962 case 0x5a: // z
2963 {
2964 seqbuflen = _get_non_alt_char(seqbuf, key_event,
2965 control_key_state);
2966
2967 // If Alt is pressed, then prefix with escape.
2968 if (_is_alt_pressed(control_key_state)) {
2969 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
2970 }
2971 }
2972 break;
2973
2974 // These virtual key codes are generated by the keys on the
2975 // keypad *when NumLock is on* and *Shift is up*.
2976 MATCH(VK_NUMPAD0, "0");
2977 MATCH(VK_NUMPAD1, "1");
2978 MATCH(VK_NUMPAD2, "2");
2979 MATCH(VK_NUMPAD3, "3");
2980 MATCH(VK_NUMPAD4, "4");
2981 MATCH(VK_NUMPAD5, "5");
2982 MATCH(VK_NUMPAD6, "6");
2983 MATCH(VK_NUMPAD7, "7");
2984 MATCH(VK_NUMPAD8, "8");
2985 MATCH(VK_NUMPAD9, "9");
2986
2987 MATCH(VK_MULTIPLY, "*");
2988 MATCH(VK_ADD, "+");
2989 MATCH(VK_SUBTRACT, "-");
2990 // VK_DECIMAL is generated by the . key on the keypad *when
2991 // NumLock is on* and *Shift is up* and the sequence is not
2992 // Ctrl-Alt-NoShift-. (which causes Ctrl-Alt-Del and the
2993 // Windows Security screen to come up).
2994 case VK_DECIMAL:
2995 // U.S. English uses '.', Germany German uses ','.
2996 seqbuflen = _get_non_control_char(seqbuf, key_event,
2997 control_key_state);
2998 break;
2999
3000 MATCH_MODIFIER(VK_F1, SS3 "P");
3001 MATCH_MODIFIER(VK_F2, SS3 "Q");
3002 MATCH_MODIFIER(VK_F3, SS3 "R");
3003 MATCH_MODIFIER(VK_F4, SS3 "S");
3004 MATCH_MODIFIER(VK_F5, CSI "15~");
3005 MATCH_MODIFIER(VK_F6, CSI "17~");
3006 MATCH_MODIFIER(VK_F7, CSI "18~");
3007 MATCH_MODIFIER(VK_F8, CSI "19~");
3008 MATCH_MODIFIER(VK_F9, CSI "20~");
3009 MATCH_MODIFIER(VK_F10, CSI "21~");
3010 MATCH_MODIFIER(VK_F11, CSI "23~");
3011 MATCH_MODIFIER(VK_F12, CSI "24~");
3012
3013 MATCH_MODIFIER(VK_F13, CSI "25~");
3014 MATCH_MODIFIER(VK_F14, CSI "26~");
3015 MATCH_MODIFIER(VK_F15, CSI "28~");
3016 MATCH_MODIFIER(VK_F16, CSI "29~");
3017 MATCH_MODIFIER(VK_F17, CSI "31~");
3018 MATCH_MODIFIER(VK_F18, CSI "32~");
3019 MATCH_MODIFIER(VK_F19, CSI "33~");
3020 MATCH_MODIFIER(VK_F20, CSI "34~");
3021
3022 // MATCH_MODIFIER(VK_F21, ???);
3023 // MATCH_MODIFIER(VK_F22, ???);
3024 // MATCH_MODIFIER(VK_F23, ???);
3025 // MATCH_MODIFIER(VK_F24, ???);
3026 }
3027 }
3028
3029#undef MATCH
3030#undef MATCH_MODIFIER
3031#undef MATCH_KEYPAD
3032#undef MATCH_MODIFIER_KEYPAD
3033#undef ESC
3034#undef CSI
3035#undef SS3
3036
3037 const char* out;
3038 size_t outlen;
3039
3040 // Check for output in any of:
3041 // * seqstr is set (and strlen can be used to determine the length).
3042 // * seqbuf and seqbuflen are set
3043 // Fallback to ch from Windows.
3044 if (seqstr != NULL) {
3045 out = seqstr;
3046 outlen = strlen(seqstr);
3047 } else if (seqbuflen > 0) {
3048 out = seqbuf;
3049 outlen = seqbuflen;
3050 } else if (ch != '\0') {
3051 // Use whatever Windows told us it is.
3052 seqbuf[0] = ch;
3053 seqbuflen = 1;
3054 out = seqbuf;
3055 outlen = seqbuflen;
3056 } else {
3057 // No special handling for the virtual key code and Windows isn't
3058 // telling us a character code, then we don't know how to translate
3059 // the key press.
3060 //
3061 // Consume the input and 'continue' to cause us to get a new key
3062 // event.
3063 D("_console_read: unknown virtual key code: %d, enhanced: %s\n",
3064 vk, _is_enhanced_key(control_key_state) ? "true" : "false");
3065 key_event->wRepeatCount = 0;
3066 continue;
3067 }
3068
3069 int bytesRead = 0;
3070
3071 // put output wRepeatCount times into buf/len
3072 while (key_event->wRepeatCount > 0) {
3073 if (len >= outlen) {
3074 // Write to buf/len
3075 memcpy(buf, out, outlen);
3076 buf = (void*)((char*)buf + outlen);
3077 len -= outlen;
3078 bytesRead += outlen;
3079
3080 // consume the input
3081 --key_event->wRepeatCount;
3082 } else {
3083 // Not enough space, so just leave it in _win32_input_record
3084 // for a subsequent retrieval.
3085 if (bytesRead == 0) {
3086 // We didn't write anything because there wasn't enough
3087 // space to even write one sequence. This should never
3088 // happen if the caller uses sensible buffer sizes
3089 // (i.e. >= maximum sequence length which is probably a
3090 // few bytes long).
3091 D("_console_read: no buffer space to write one sequence; "
3092 "buffer: %ld, sequence: %ld\n", (long)len,
3093 (long)outlen);
3094 errno = ENOMEM;
3095 return -1;
3096 } else {
3097 // Stop trying to write to buf/len, just return whatever
3098 // we wrote so far.
3099 break;
3100 }
3101 }
3102 }
3103
3104 return bytesRead;
3105 }
3106}
3107
3108static DWORD _old_console_mode; // previous GetConsoleMode() result
3109static HANDLE _console_handle; // when set, console mode should be restored
3110
3111void stdin_raw_init(const int fd) {
3112 if (STDIN_FILENO == fd) {
3113 const HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
3114 if ((in == INVALID_HANDLE_VALUE) || (in == NULL)) {
3115 return;
3116 }
3117
3118 if (GetFileType(in) != FILE_TYPE_CHAR) {
3119 // stdin might be a file or pipe.
3120 return;
3121 }
3122
3123 if (!GetConsoleMode(in, &_old_console_mode)) {
3124 // If GetConsoleMode() fails, stdin is probably is not a console.
3125 return;
3126 }
3127
3128 // Disable ENABLE_PROCESSED_INPUT so that Ctrl-C is read instead of
3129 // calling the process Ctrl-C routine (configured by
3130 // SetConsoleCtrlHandler()).
3131 // Disable ENABLE_LINE_INPUT so that input is immediately sent.
3132 // Disable ENABLE_ECHO_INPUT to disable local echo. Disabling this
3133 // flag also seems necessary to have proper line-ending processing.
3134 if (!SetConsoleMode(in, _old_console_mode & ~(ENABLE_PROCESSED_INPUT |
3135 ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))) {
3136 // This really should not fail.
3137 D("stdin_raw_init: SetConsoleMode() failure, error %ld\n",
3138 GetLastError());
3139 }
3140
3141 // Once this is set, it means that stdin has been configured for
3142 // reading from and that the old console mode should be restored later.
3143 _console_handle = in;
3144
3145 // Note that we don't need to configure C Runtime line-ending
3146 // translation because _console_read() does not call the C Runtime to
3147 // read from the console.
3148 }
3149}
3150
3151void stdin_raw_restore(const int fd) {
3152 if (STDIN_FILENO == fd) {
3153 if (_console_handle != NULL) {
3154 const HANDLE in = _console_handle;
3155 _console_handle = NULL; // clear state
3156
3157 if (!SetConsoleMode(in, _old_console_mode)) {
3158 // This really should not fail.
3159 D("stdin_raw_restore: SetConsoleMode() failure, error %ld\n",
3160 GetLastError());
3161 }
3162 }
3163 }
3164}
3165
Spencer Low6ac5d7d2015-05-22 20:09:06 -07003166// Called by 'adb shell' and 'adb exec-in' to read from stdin.
Spencer Low50184062015-03-01 15:06:21 -08003167int unix_read(int fd, void* buf, size_t len) {
3168 if ((fd == STDIN_FILENO) && (_console_handle != NULL)) {
3169 // If it is a request to read from stdin, and stdin_raw_init() has been
3170 // called, and it successfully configured the console, then read from
3171 // the console using Win32 console APIs and partially emulate a unix
3172 // terminal.
3173 return _console_read(_console_handle, buf, len);
3174 } else {
3175 // Just call into C Runtime which can read from pipes/files and which
Spencer Low6ac5d7d2015-05-22 20:09:06 -07003176 // can do LF/CR translation (which is overridable with _setmode()).
3177 // Undefine the macro that is set in sysdeps.h which bans calls to
3178 // plain read() in favor of unix_read() or adb_read().
3179#pragma push_macro("read")
Spencer Low50184062015-03-01 15:06:21 -08003180#undef read
3181 return read(fd, buf, len);
Spencer Low6ac5d7d2015-05-22 20:09:06 -07003182#pragma pop_macro("read")
Spencer Low50184062015-03-01 15:06:21 -08003183 }
3184}