blob: 5b23c793fd3ee4187e437a1bc97690c735966ff7 [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 Lowe6ae5732015-09-08 17:13:04 -070028#include <algorithm>
Spencer Low5200c662015-07-30 23:07:55 -070029#include <memory>
30#include <string>
Spencer Lowcf4ff642015-05-11 01:08:48 -070031#include <unordered_map>
Spencer Low5200c662015-07-30 23:07:55 -070032
Elliott Hughesd48dbd82015-07-24 11:35:40 -070033#include <cutils/sockets.h>
34
Spencer Low5200c662015-07-30 23:07:55 -070035#include <base/logging.h>
36#include <base/stringprintf.h>
37#include <base/strings.h>
38
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080039#include "adb.h"
40
41extern void fatal(const char *fmt, ...);
42
Elliott Hughesa2f2e562015-04-16 16:47:02 -070043/* forward declarations */
44
45typedef const struct FHClassRec_* FHClass;
46typedef struct FHRec_* FH;
47typedef struct EventHookRec_* EventHook;
48
49typedef struct FHClassRec_ {
50 void (*_fh_init)(FH);
51 int (*_fh_close)(FH);
52 int (*_fh_lseek)(FH, int, int);
53 int (*_fh_read)(FH, void*, int);
54 int (*_fh_write)(FH, const void*, int);
55 void (*_fh_hook)(FH, int, EventHook);
56} FHClassRec;
57
58static void _fh_file_init(FH);
59static int _fh_file_close(FH);
60static int _fh_file_lseek(FH, int, int);
61static int _fh_file_read(FH, void*, int);
62static int _fh_file_write(FH, const void*, int);
63static void _fh_file_hook(FH, int, EventHook);
64
65static const FHClassRec _fh_file_class = {
66 _fh_file_init,
67 _fh_file_close,
68 _fh_file_lseek,
69 _fh_file_read,
70 _fh_file_write,
71 _fh_file_hook
72};
73
74static void _fh_socket_init(FH);
75static int _fh_socket_close(FH);
76static int _fh_socket_lseek(FH, int, int);
77static int _fh_socket_read(FH, void*, int);
78static int _fh_socket_write(FH, const void*, int);
79static void _fh_socket_hook(FH, int, EventHook);
80
81static const FHClassRec _fh_socket_class = {
82 _fh_socket_init,
83 _fh_socket_close,
84 _fh_socket_lseek,
85 _fh_socket_read,
86 _fh_socket_write,
87 _fh_socket_hook
88};
89
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -080090#define assert(cond) do { if (!(cond)) fatal( "assertion failed '%s' on %s:%ld\n", #cond, __FILE__, __LINE__ ); } while (0)
91
Spencer Low5200c662015-07-30 23:07:55 -070092std::string SystemErrorCodeToString(const DWORD error_code) {
93 const int kErrorMessageBufferSize = 256;
Spencer Lowe347c1d2015-08-02 18:13:54 -070094 WCHAR msgbuf[kErrorMessageBufferSize];
Spencer Low5200c662015-07-30 23:07:55 -070095 DWORD flags = FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
Spencer Lowe347c1d2015-08-02 18:13:54 -070096 DWORD len = FormatMessageW(flags, nullptr, error_code, 0, msgbuf,
Spencer Low5200c662015-07-30 23:07:55 -070097 arraysize(msgbuf), nullptr);
98 if (len == 0) {
99 return android::base::StringPrintf(
100 "Error (%lu) while retrieving error. (%lu)", GetLastError(),
101 error_code);
102 }
103
Spencer Lowe347c1d2015-08-02 18:13:54 -0700104 // Convert UTF-16 to UTF-8.
105 std::string msg(narrow(msgbuf));
Spencer Low5200c662015-07-30 23:07:55 -0700106 // Messages returned by the system end with line breaks.
107 msg = android::base::Trim(msg);
108 // There are many Windows error messages compared to POSIX, so include the
109 // numeric error code for easier, quicker, accurate identification. Use
110 // decimal instead of hex because there are decimal ranges like 10000-11999
111 // for Winsock.
112 android::base::StringAppendF(&msg, " (%lu)", error_code);
113 return msg;
114}
115
Spencer Low2122c7a2015-08-26 18:46:09 -0700116void handle_deleter::operator()(HANDLE h) {
117 // CreateFile() is documented to return INVALID_HANDLE_FILE on error,
118 // implying that NULL is a valid handle, but this is probably impossible.
119 // Other APIs like CreateEvent() are documented to return NULL on error,
120 // implying that INVALID_HANDLE_VALUE is a valid handle, but this is also
121 // probably impossible. Thus, consider both NULL and INVALID_HANDLE_VALUE
122 // as invalid handles. std::unique_ptr won't call a deleter with NULL, so we
123 // only need to check for INVALID_HANDLE_VALUE.
124 if (h != INVALID_HANDLE_VALUE) {
125 if (!CloseHandle(h)) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700126 D("CloseHandle(%p) failed: %s", h,
Spencer Low2122c7a2015-08-26 18:46:09 -0700127 SystemErrorCodeToString(GetLastError()).c_str());
128 }
129 }
130}
131
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800132/**************************************************************************/
133/**************************************************************************/
134/***** *****/
135/***** replaces libs/cutils/load_file.c *****/
136/***** *****/
137/**************************************************************************/
138/**************************************************************************/
139
140void *load_file(const char *fn, unsigned *_sz)
141{
142 HANDLE file;
143 char *data;
144 DWORD file_size;
145
Spencer Lowcf4ff642015-05-11 01:08:48 -0700146 file = CreateFileW( widen(fn).c_str(),
147 GENERIC_READ,
148 FILE_SHARE_READ,
149 NULL,
150 OPEN_EXISTING,
151 0,
152 NULL );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800153
154 if (file == INVALID_HANDLE_VALUE)
155 return NULL;
156
157 file_size = GetFileSize( file, NULL );
158 data = NULL;
159
160 if (file_size > 0) {
161 data = (char*) malloc( file_size + 1 );
162 if (data == NULL) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700163 D("load_file: could not allocate %ld bytes", file_size );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800164 file_size = 0;
165 } else {
166 DWORD out_bytes;
167
168 if ( !ReadFile( file, data, file_size, &out_bytes, NULL ) ||
169 out_bytes != file_size )
170 {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700171 D("load_file: could not read %ld bytes from '%s'", file_size, fn);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800172 free(data);
173 data = NULL;
174 file_size = 0;
175 }
176 }
177 }
178 CloseHandle( file );
179
180 *_sz = (unsigned) file_size;
181 return data;
182}
183
184/**************************************************************************/
185/**************************************************************************/
186/***** *****/
187/***** common file descriptor handling *****/
188/***** *****/
189/**************************************************************************/
190/**************************************************************************/
191
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800192/* used to emulate unix-domain socket pairs */
193typedef struct SocketPairRec_* SocketPair;
194
195typedef struct FHRec_
196{
197 FHClass clazz;
198 int used;
199 int eof;
200 union {
201 HANDLE handle;
202 SOCKET socket;
203 SocketPair pair;
204 } u;
205
206 HANDLE event;
207 int mask;
208
209 char name[32];
210
211} FHRec;
212
213#define fh_handle u.handle
214#define fh_socket u.socket
215#define fh_pair u.pair
216
217#define WIN32_FH_BASE 100
218
219#define WIN32_MAX_FHS 128
220
221static adb_mutex_t _win32_lock;
222static FHRec _win32_fhs[ WIN32_MAX_FHS ];
Spencer Lowc3211552015-07-24 15:38:19 -0700223static int _win32_fh_next; // where to start search for free FHRec
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800224
225static FH
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700226_fh_from_int( int fd, const char* func )
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800227{
228 FH f;
229
230 fd -= WIN32_FH_BASE;
231
Spencer Lowc3211552015-07-24 15:38:19 -0700232 if (fd < 0 || fd >= WIN32_MAX_FHS) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700233 D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700234 func );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800235 errno = EBADF;
236 return NULL;
237 }
238
239 f = &_win32_fhs[fd];
240
241 if (f->used == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700242 D( "_fh_from_int: invalid fd %d passed to %s", fd + WIN32_FH_BASE,
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700243 func );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800244 errno = EBADF;
245 return NULL;
246 }
247
248 return f;
249}
250
251
252static int
253_fh_to_int( FH f )
254{
255 if (f && f->used && f >= _win32_fhs && f < _win32_fhs + WIN32_MAX_FHS)
256 return (int)(f - _win32_fhs) + WIN32_FH_BASE;
257
258 return -1;
259}
260
261static FH
262_fh_alloc( FHClass clazz )
263{
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800264 FH f = NULL;
265
266 adb_mutex_lock( &_win32_lock );
267
Spencer Lowc3211552015-07-24 15:38:19 -0700268 // Search entire array, starting from _win32_fh_next.
269 for (int nn = 0; nn < WIN32_MAX_FHS; nn++) {
270 // Keep incrementing _win32_fh_next to avoid giving out an index that
271 // was recently closed, to try to avoid use-after-free.
272 const int index = _win32_fh_next++;
273 // Handle wrap-around of _win32_fh_next.
274 if (_win32_fh_next == WIN32_MAX_FHS) {
275 _win32_fh_next = 0;
276 }
277 if (_win32_fhs[index].clazz == NULL) {
278 f = &_win32_fhs[index];
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800279 goto Exit;
280 }
281 }
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700282 D( "_fh_alloc: no more free file descriptors" );
Spencer Lowc3211552015-07-24 15:38:19 -0700283 errno = EMFILE; // Too many open files
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800284Exit:
285 if (f) {
Spencer Lowc3211552015-07-24 15:38:19 -0700286 f->clazz = clazz;
287 f->used = 1;
288 f->eof = 0;
289 f->name[0] = '\0';
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800290 clazz->_fh_init(f);
291 }
292 adb_mutex_unlock( &_win32_lock );
293 return f;
294}
295
296
297static int
298_fh_close( FH f )
299{
Spencer Lowc3211552015-07-24 15:38:19 -0700300 // Use lock so that closing only happens once and so that _fh_alloc can't
301 // allocate a FH that we're in the middle of closing.
302 adb_mutex_lock(&_win32_lock);
303 if (f->used) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800304 f->clazz->_fh_close( f );
Spencer Lowc3211552015-07-24 15:38:19 -0700305 f->name[0] = '\0';
306 f->eof = 0;
307 f->used = 0;
308 f->clazz = NULL;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800309 }
Spencer Lowc3211552015-07-24 15:38:19 -0700310 adb_mutex_unlock(&_win32_lock);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800311 return 0;
312}
313
Spencer Low5200c662015-07-30 23:07:55 -0700314// Deleter for unique_fh.
315class fh_deleter {
316 public:
317 void operator()(struct FHRec_* fh) {
318 // We're called from a destructor and destructors should not overwrite
319 // errno because callers may do:
320 // errno = EBLAH;
321 // return -1; // calls destructor, which should not overwrite errno
322 const int saved_errno = errno;
323 _fh_close(fh);
324 errno = saved_errno;
325 }
326};
327
328// Like std::unique_ptr, but calls _fh_close() instead of operator delete().
329typedef std::unique_ptr<struct FHRec_, fh_deleter> unique_fh;
330
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800331/**************************************************************************/
332/**************************************************************************/
333/***** *****/
334/***** file-based descriptor handling *****/
335/***** *****/
336/**************************************************************************/
337/**************************************************************************/
338
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700339static void _fh_file_init( FH f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800340 f->fh_handle = INVALID_HANDLE_VALUE;
341}
342
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700343static int _fh_file_close( FH f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800344 CloseHandle( f->fh_handle );
345 f->fh_handle = INVALID_HANDLE_VALUE;
346 return 0;
347}
348
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700349static int _fh_file_read( FH f, void* buf, int len ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800350 DWORD read_bytes;
351
352 if ( !ReadFile( f->fh_handle, buf, (DWORD)len, &read_bytes, NULL ) ) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700353 D( "adb_read: could not read %d bytes from %s", len, f->name );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800354 errno = EIO;
355 return -1;
356 } else if (read_bytes < (DWORD)len) {
357 f->eof = 1;
358 }
359 return (int)read_bytes;
360}
361
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700362static int _fh_file_write( FH f, const void* buf, int len ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800363 DWORD wrote_bytes;
364
365 if ( !WriteFile( f->fh_handle, buf, (DWORD)len, &wrote_bytes, NULL ) ) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700366 D( "adb_file_write: could not write %d bytes from %s", len, f->name );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800367 errno = EIO;
368 return -1;
369 } else if (wrote_bytes < (DWORD)len) {
370 f->eof = 1;
371 }
372 return (int)wrote_bytes;
373}
374
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700375static int _fh_file_lseek( FH f, int pos, int origin ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800376 DWORD method;
377 DWORD result;
378
379 switch (origin)
380 {
381 case SEEK_SET: method = FILE_BEGIN; break;
382 case SEEK_CUR: method = FILE_CURRENT; break;
383 case SEEK_END: method = FILE_END; break;
384 default:
385 errno = EINVAL;
386 return -1;
387 }
388
389 result = SetFilePointer( f->fh_handle, pos, NULL, method );
390 if (result == INVALID_SET_FILE_POINTER) {
391 errno = EIO;
392 return -1;
393 } else {
394 f->eof = 0;
395 }
396 return (int)result;
397}
398
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800399
400/**************************************************************************/
401/**************************************************************************/
402/***** *****/
403/***** file-based descriptor handling *****/
404/***** *****/
405/**************************************************************************/
406/**************************************************************************/
407
408int adb_open(const char* path, int options)
409{
410 FH f;
411
412 DWORD desiredAccess = 0;
413 DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE;
414
415 switch (options) {
416 case O_RDONLY:
417 desiredAccess = GENERIC_READ;
418 break;
419 case O_WRONLY:
420 desiredAccess = GENERIC_WRITE;
421 break;
422 case O_RDWR:
423 desiredAccess = GENERIC_READ | GENERIC_WRITE;
424 break;
425 default:
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700426 D("adb_open: invalid options (0x%0x)", options);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800427 errno = EINVAL;
428 return -1;
429 }
430
431 f = _fh_alloc( &_fh_file_class );
432 if ( !f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800433 return -1;
434 }
435
Spencer Lowcf4ff642015-05-11 01:08:48 -0700436 f->fh_handle = CreateFileW( widen(path).c_str(), desiredAccess, shareMode,
437 NULL, OPEN_EXISTING, 0, NULL );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800438
439 if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
Spencer Low8d8126a2015-07-21 02:06:26 -0700440 const DWORD err = GetLastError();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800441 _fh_close(f);
Spencer Low8d8126a2015-07-21 02:06:26 -0700442 D( "adb_open: could not open '%s': ", path );
443 switch (err) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800444 case ERROR_FILE_NOT_FOUND:
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700445 D( "file not found" );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800446 errno = ENOENT;
447 return -1;
448
449 case ERROR_PATH_NOT_FOUND:
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700450 D( "path not found" );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800451 errno = ENOTDIR;
452 return -1;
453
454 default:
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700455 D( "unknown error: %s",
Spencer Low8df90322015-08-02 18:50:17 -0700456 SystemErrorCodeToString( err ).c_str() );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800457 errno = ENOENT;
458 return -1;
459 }
460 }
Vladimir Chtchetkinece480832011-11-30 10:20:27 -0800461
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800462 snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700463 D( "adb_open: '%s' => fd %d", path, _fh_to_int(f) );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800464 return _fh_to_int(f);
465}
466
467/* ignore mode on Win32 */
468int adb_creat(const char* path, int mode)
469{
470 FH f;
471
472 f = _fh_alloc( &_fh_file_class );
473 if ( !f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800474 return -1;
475 }
476
Spencer Lowcf4ff642015-05-11 01:08:48 -0700477 f->fh_handle = CreateFileW( widen(path).c_str(), GENERIC_WRITE,
478 FILE_SHARE_READ | FILE_SHARE_WRITE,
479 NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,
480 NULL );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800481
482 if ( f->fh_handle == INVALID_HANDLE_VALUE ) {
Spencer Low8d8126a2015-07-21 02:06:26 -0700483 const DWORD err = GetLastError();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800484 _fh_close(f);
Spencer Low8d8126a2015-07-21 02:06:26 -0700485 D( "adb_creat: could not open '%s': ", path );
486 switch (err) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800487 case ERROR_FILE_NOT_FOUND:
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700488 D( "file not found" );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800489 errno = ENOENT;
490 return -1;
491
492 case ERROR_PATH_NOT_FOUND:
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700493 D( "path not found" );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800494 errno = ENOTDIR;
495 return -1;
496
497 default:
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700498 D( "unknown error: %s",
Spencer Low8df90322015-08-02 18:50:17 -0700499 SystemErrorCodeToString( err ).c_str() );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800500 errno = ENOENT;
501 return -1;
502 }
503 }
504 snprintf( f->name, sizeof(f->name), "%d(%s)", _fh_to_int(f), path );
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700505 D( "adb_creat: '%s' => fd %d", path, _fh_to_int(f) );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800506 return _fh_to_int(f);
507}
508
509
510int adb_read(int fd, void* buf, int len)
511{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700512 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800513
514 if (f == NULL) {
515 return -1;
516 }
517
518 return f->clazz->_fh_read( f, buf, len );
519}
520
521
522int adb_write(int fd, const void* buf, int len)
523{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700524 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800525
526 if (f == NULL) {
527 return -1;
528 }
529
530 return f->clazz->_fh_write(f, buf, len);
531}
532
533
534int adb_lseek(int fd, int pos, int where)
535{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700536 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800537
538 if (!f) {
539 return -1;
540 }
541
542 return f->clazz->_fh_lseek(f, pos, where);
543}
544
545
546int adb_close(int fd)
547{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700548 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800549
550 if (!f) {
551 return -1;
552 }
553
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700554 D( "adb_close: %s", f->name);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800555 _fh_close(f);
556 return 0;
557}
558
559/**************************************************************************/
560/**************************************************************************/
561/***** *****/
562/***** socket-based file descriptors *****/
563/***** *****/
564/**************************************************************************/
565/**************************************************************************/
566
Spencer Lowf055c192015-01-25 14:40:16 -0800567#undef setsockopt
568
Spencer Low5200c662015-07-30 23:07:55 -0700569static void _socket_set_errno( const DWORD err ) {
570 // The Windows C Runtime (MSVCRT.DLL) strerror() does not support a lot of
571 // POSIX and socket error codes, so this can only meaningfully map so much.
572 switch ( err ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800573 case 0: errno = 0; break;
Spencer Lowbf7c6052015-08-11 16:45:32 -0700574 // Mapping WSAEWOULDBLOCK to EAGAIN is absolutely critical because
575 // non-blocking sockets can cause an error code of WSAEWOULDBLOCK and
576 // callers check specifically for EAGAIN.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800577 case WSAEWOULDBLOCK: errno = EAGAIN; break;
578 case WSAEINTR: errno = EINTR; break;
Spencer Low5200c662015-07-30 23:07:55 -0700579 case WSAEFAULT: errno = EFAULT; break;
580 case WSAEINVAL: errno = EINVAL; break;
581 case WSAEMFILE: errno = EMFILE; break;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800582 default:
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800583 errno = EINVAL;
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700584 D( "_socket_set_errno: mapping Windows error code %lu to errno %d",
Spencer Low5200c662015-07-30 23:07:55 -0700585 err, errno );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800586 }
587}
588
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700589static void _fh_socket_init( FH f ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800590 f->fh_socket = INVALID_SOCKET;
591 f->event = WSACreateEvent();
Spencer Low5200c662015-07-30 23:07:55 -0700592 if (f->event == WSA_INVALID_EVENT) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700593 D("WSACreateEvent failed: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700594 SystemErrorCodeToString(WSAGetLastError()).c_str());
595
596 // _event_socket_start assumes that this field is INVALID_HANDLE_VALUE
597 // on failure, instead of NULL which is what Windows really returns on
598 // error. It might be better to change all the other code to look for
599 // NULL, but that is a much riskier change.
600 f->event = INVALID_HANDLE_VALUE;
601 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800602 f->mask = 0;
603}
604
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700605static int _fh_socket_close( FH f ) {
Spencer Low5200c662015-07-30 23:07:55 -0700606 if (f->fh_socket != INVALID_SOCKET) {
607 /* gently tell any peer that we're closing the socket */
608 if (shutdown(f->fh_socket, SD_BOTH) == SOCKET_ERROR) {
609 // If the socket is not connected, this returns an error. We want to
610 // minimize logging spam, so don't log these errors for now.
611#if 0
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700612 D("socket shutdown failed: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700613 SystemErrorCodeToString(WSAGetLastError()).c_str());
614#endif
615 }
616 if (closesocket(f->fh_socket) == SOCKET_ERROR) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700617 D("closesocket failed: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700618 SystemErrorCodeToString(WSAGetLastError()).c_str());
619 }
620 f->fh_socket = INVALID_SOCKET;
621 }
622 if (f->event != NULL) {
623 if (!CloseHandle(f->event)) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700624 D("CloseHandle failed: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700625 SystemErrorCodeToString(GetLastError()).c_str());
626 }
627 f->event = NULL;
628 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800629 f->mask = 0;
630 return 0;
631}
632
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700633static int _fh_socket_lseek( FH f, int pos, int origin ) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800634 errno = EPIPE;
635 return -1;
636}
637
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700638static int _fh_socket_read(FH f, void* buf, int len) {
639 int result = recv(f->fh_socket, reinterpret_cast<char*>(buf), len, 0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800640 if (result == SOCKET_ERROR) {
Spencer Low5200c662015-07-30 23:07:55 -0700641 const DWORD err = WSAGetLastError();
Spencer Lowbf7c6052015-08-11 16:45:32 -0700642 // WSAEWOULDBLOCK is normal with a non-blocking socket, so don't trace
643 // that to reduce spam and confusion.
644 if (err != WSAEWOULDBLOCK) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700645 D("recv fd %d failed: %s", _fh_to_int(f),
Spencer Lowbf7c6052015-08-11 16:45:32 -0700646 SystemErrorCodeToString(err).c_str());
647 }
Spencer Low5200c662015-07-30 23:07:55 -0700648 _socket_set_errno(err);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800649 result = -1;
650 }
651 return result;
652}
653
Elliott Hughesa2f2e562015-04-16 16:47:02 -0700654static int _fh_socket_write(FH f, const void* buf, int len) {
655 int result = send(f->fh_socket, reinterpret_cast<const char*>(buf), len, 0);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800656 if (result == SOCKET_ERROR) {
Spencer Low5200c662015-07-30 23:07:55 -0700657 const DWORD err = WSAGetLastError();
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700658 D("send fd %d failed: %s", _fh_to_int(f),
Spencer Low5200c662015-07-30 23:07:55 -0700659 SystemErrorCodeToString(err).c_str());
660 _socket_set_errno(err);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800661 result = -1;
662 }
663 return result;
664}
665
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800666/**************************************************************************/
667/**************************************************************************/
668/***** *****/
669/***** replacement for libs/cutils/socket_xxxx.c *****/
670/***** *****/
671/**************************************************************************/
672/**************************************************************************/
673
674#include <winsock2.h>
675
676static int _winsock_init;
677
678static void
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800679_init_winsock( void )
680{
Spencer Low5200c662015-07-30 23:07:55 -0700681 // TODO: Multiple threads calling this may potentially cause multiple calls
Spencer Low87e97ee2015-08-12 18:19:16 -0700682 // to WSAStartup() which offers no real benefit.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800683 if (!_winsock_init) {
684 WSADATA wsaData;
685 int rc = WSAStartup( MAKEWORD(2,2), &wsaData);
686 if (rc != 0) {
Spencer Low5200c662015-07-30 23:07:55 -0700687 fatal( "adb: could not initialize Winsock: %s",
688 SystemErrorCodeToString( rc ).c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800689 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800690 _winsock_init = 1;
Spencer Low87e97ee2015-08-12 18:19:16 -0700691
692 // Note that we do not call atexit() to register WSACleanup to be called
693 // at normal process termination because:
694 // 1) When exit() is called, there are still threads actively using
695 // Winsock because we don't cleanly shutdown all threads, so it
696 // doesn't make sense to call WSACleanup() and may cause problems
697 // with those threads.
698 // 2) A deadlock can occur when exit() holds a C Runtime lock, then it
699 // calls WSACleanup() which tries to unload a DLL, which tries to
700 // grab the LoaderLock. This conflicts with the device_poll_thread
701 // which holds the LoaderLock because AdbWinApi.dll calls
702 // setupapi.dll which tries to load wintrust.dll which tries to load
703 // crypt32.dll which calls atexit() which tries to acquire the C
704 // Runtime lock that the other thread holds.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800705 }
706}
707
Spencer Low5200c662015-07-30 23:07:55 -0700708int network_loopback_client(int port, int type, std::string* error) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800709 struct sockaddr_in addr;
710 SOCKET s;
711
Spencer Low5200c662015-07-30 23:07:55 -0700712 unique_fh f(_fh_alloc(&_fh_socket_class));
713 if (!f) {
714 *error = strerror(errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800715 return -1;
Spencer Low5200c662015-07-30 23:07:55 -0700716 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800717
718 if (!_winsock_init)
719 _init_winsock();
720
721 memset(&addr, 0, sizeof(addr));
722 addr.sin_family = AF_INET;
723 addr.sin_port = htons(port);
724 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
725
726 s = socket(AF_INET, type, 0);
727 if(s == INVALID_SOCKET) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700728 *error = android::base::StringPrintf("cannot create socket: %s",
729 SystemErrorCodeToString(WSAGetLastError()).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700730 D("%s", error->c_str());
Spencer Low5200c662015-07-30 23:07:55 -0700731 return -1;
732 }
733 f->fh_socket = s;
734
735 if(connect(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700736 // Save err just in case inet_ntoa() or ntohs() changes the last error.
737 const DWORD err = WSAGetLastError();
738 *error = android::base::StringPrintf("cannot connect to %s:%u: %s",
739 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
740 SystemErrorCodeToString(err).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700741 D("could not connect to %s:%d: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700742 type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800743 return -1;
744 }
745
Spencer Low5200c662015-07-30 23:07:55 -0700746 const int fd = _fh_to_int(f.get());
747 snprintf( f->name, sizeof(f->name), "%d(lo-client:%s%d)", fd,
748 type != SOCK_STREAM ? "udp:" : "", port );
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700749 D( "port %d type %s => fd %d", port, type != SOCK_STREAM ? "udp" : "tcp",
Spencer Low5200c662015-07-30 23:07:55 -0700750 fd );
751 f.release();
752 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800753}
754
755#define LISTEN_BACKLOG 4
756
Spencer Low5200c662015-07-30 23:07:55 -0700757// interface_address is INADDR_LOOPBACK or INADDR_ANY.
758static int _network_server(int port, int type, u_long interface_address,
759 std::string* error) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800760 struct sockaddr_in addr;
761 SOCKET s;
762 int n;
763
Spencer Low5200c662015-07-30 23:07:55 -0700764 unique_fh f(_fh_alloc(&_fh_socket_class));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800765 if (!f) {
Spencer Low5200c662015-07-30 23:07:55 -0700766 *error = strerror(errno);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800767 return -1;
768 }
769
770 if (!_winsock_init)
771 _init_winsock();
772
773 memset(&addr, 0, sizeof(addr));
774 addr.sin_family = AF_INET;
775 addr.sin_port = htons(port);
Spencer Low5200c662015-07-30 23:07:55 -0700776 addr.sin_addr.s_addr = htonl(interface_address);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800777
Spencer Low5200c662015-07-30 23:07:55 -0700778 // TODO: Consider using dual-stack socket that can simultaneously listen on
779 // IPv4 and IPv6.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800780 s = socket(AF_INET, type, 0);
Spencer Low5200c662015-07-30 23:07:55 -0700781 if (s == INVALID_SOCKET) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700782 *error = android::base::StringPrintf("cannot create socket: %s",
783 SystemErrorCodeToString(WSAGetLastError()).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700784 D("%s", error->c_str());
Spencer Low5200c662015-07-30 23:07:55 -0700785 return -1;
786 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800787
788 f->fh_socket = s;
789
Spencer Lowbf7c6052015-08-11 16:45:32 -0700790 // Note: SO_REUSEADDR on Windows allows multiple processes to bind to the
791 // same port, so instead use SO_EXCLUSIVEADDRUSE.
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800792 n = 1;
Spencer Low5200c662015-07-30 23:07:55 -0700793 if (setsockopt(s, SOL_SOCKET, SO_EXCLUSIVEADDRUSE, (const char*)&n,
794 sizeof(n)) == SOCKET_ERROR) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700795 *error = android::base::StringPrintf(
796 "cannot set socket option SO_EXCLUSIVEADDRUSE: %s",
797 SystemErrorCodeToString(WSAGetLastError()).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700798 D("%s", error->c_str());
Spencer Low5200c662015-07-30 23:07:55 -0700799 return -1;
800 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800801
Spencer Lowbf7c6052015-08-11 16:45:32 -0700802 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) == SOCKET_ERROR) {
803 // Save err just in case inet_ntoa() or ntohs() changes the last error.
804 const DWORD err = WSAGetLastError();
805 *error = android::base::StringPrintf("cannot bind to %s:%u: %s",
806 inet_ntoa(addr.sin_addr), ntohs(addr.sin_port),
807 SystemErrorCodeToString(err).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700808 D("could not bind to %s:%d: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700809 type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800810 return -1;
811 }
812 if (type == SOCK_STREAM) {
Spencer Low5200c662015-07-30 23:07:55 -0700813 if (listen(s, LISTEN_BACKLOG) == SOCKET_ERROR) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700814 *error = android::base::StringPrintf("cannot listen on socket: %s",
815 SystemErrorCodeToString(WSAGetLastError()).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700816 D("could not listen on %s:%d: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700817 type != SOCK_STREAM ? "udp" : "tcp", port, error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800818 return -1;
819 }
820 }
Spencer Low5200c662015-07-30 23:07:55 -0700821 const int fd = _fh_to_int(f.get());
822 snprintf( f->name, sizeof(f->name), "%d(%s-server:%s%d)", fd,
823 interface_address == INADDR_LOOPBACK ? "lo" : "any",
824 type != SOCK_STREAM ? "udp:" : "", port );
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700825 D( "port %d type %s => fd %d", port, type != SOCK_STREAM ? "udp" : "tcp",
Spencer Low5200c662015-07-30 23:07:55 -0700826 fd );
827 f.release();
828 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800829}
830
Spencer Low5200c662015-07-30 23:07:55 -0700831int network_loopback_server(int port, int type, std::string* error) {
832 return _network_server(port, type, INADDR_LOOPBACK, error);
833}
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800834
Spencer Low5200c662015-07-30 23:07:55 -0700835int network_inaddr_any_server(int port, int type, std::string* error) {
836 return _network_server(port, type, INADDR_ANY, error);
837}
838
839int network_connect(const std::string& host, int port, int type, int timeout, std::string* error) {
840 unique_fh f(_fh_alloc(&_fh_socket_class));
841 if (!f) {
842 *error = strerror(errno);
843 return -1;
844 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800845
Elliott Hughes381cfa92015-07-23 17:12:58 -0700846 if (!_winsock_init) _init_winsock();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800847
Spencer Low5200c662015-07-30 23:07:55 -0700848 struct addrinfo hints;
849 memset(&hints, 0, sizeof(hints));
850 hints.ai_family = AF_UNSPEC;
851 hints.ai_socktype = type;
852
853 char port_str[16];
854 snprintf(port_str, sizeof(port_str), "%d", port);
855
856 struct addrinfo* addrinfo_ptr = nullptr;
Spencer Lowe347c1d2015-08-02 18:13:54 -0700857
858#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= _WIN32_WINNT_WS03)
859 // TODO: When the Android SDK tools increases the Windows system
860 // requirements >= WinXP SP2, switch to GetAddrInfoW(widen(host).c_str()).
861#else
862 // Otherwise, keep using getaddrinfo(), or do runtime API detection
863 // with GetProcAddress("GetAddrInfoW").
864#endif
Spencer Low5200c662015-07-30 23:07:55 -0700865 if (getaddrinfo(host.c_str(), port_str, &hints, &addrinfo_ptr) != 0) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700866 *error = android::base::StringPrintf(
867 "cannot resolve host '%s' and port %s: %s", host.c_str(),
868 port_str, SystemErrorCodeToString(WSAGetLastError()).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700869 D("%s", error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800870 return -1;
871 }
Spencer Low5200c662015-07-30 23:07:55 -0700872 std::unique_ptr<struct addrinfo, decltype(freeaddrinfo)*>
873 addrinfo(addrinfo_ptr, freeaddrinfo);
874 addrinfo_ptr = nullptr;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800875
Spencer Low5200c662015-07-30 23:07:55 -0700876 // TODO: Try all the addresses if there's more than one? This just uses
877 // the first. Or, could call WSAConnectByName() (Windows Vista and newer)
878 // which tries all addresses, takes a timeout and more.
879 SOCKET s = socket(addrinfo->ai_family, addrinfo->ai_socktype,
880 addrinfo->ai_protocol);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800881 if(s == INVALID_SOCKET) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700882 *error = android::base::StringPrintf("cannot create socket: %s",
883 SystemErrorCodeToString(WSAGetLastError()).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700884 D("%s", error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800885 return -1;
886 }
887 f->fh_socket = s;
888
Spencer Low5200c662015-07-30 23:07:55 -0700889 // TODO: Implement timeouts for Windows. Seems like the default in theory
890 // (according to http://serverfault.com/a/671453) and in practice is 21 sec.
891 if(connect(s, addrinfo->ai_addr, addrinfo->ai_addrlen) == SOCKET_ERROR) {
Spencer Lowbf7c6052015-08-11 16:45:32 -0700892 // TODO: Use WSAAddressToString or inet_ntop on address.
893 *error = android::base::StringPrintf("cannot connect to %s:%s: %s",
894 host.c_str(), port_str,
895 SystemErrorCodeToString(WSAGetLastError()).c_str());
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700896 D("could not connect to %s:%s:%s: %s",
Spencer Low5200c662015-07-30 23:07:55 -0700897 type != SOCK_STREAM ? "udp" : "tcp", host.c_str(), port_str,
898 error->c_str());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800899 return -1;
900 }
901
Spencer Low5200c662015-07-30 23:07:55 -0700902 const int fd = _fh_to_int(f.get());
903 snprintf( f->name, sizeof(f->name), "%d(net-client:%s%d)", fd,
904 type != SOCK_STREAM ? "udp:" : "", port );
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700905 D( "host '%s' port %d type %s => fd %d", host.c_str(), port,
Spencer Low5200c662015-07-30 23:07:55 -0700906 type != SOCK_STREAM ? "udp" : "tcp", fd );
907 f.release();
908 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800909}
910
911#undef accept
912int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen)
913{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700914 FH serverfh = _fh_from_int(serverfd, __func__);
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200915
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800916 if ( !serverfh || serverfh->clazz != &_fh_socket_class ) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700917 D("adb_socket_accept: invalid fd %d", serverfd);
Spencer Low5200c662015-07-30 23:07:55 -0700918 errno = EBADF;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800919 return -1;
920 }
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200921
Spencer Low5200c662015-07-30 23:07:55 -0700922 unique_fh fh(_fh_alloc( &_fh_socket_class ));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800923 if (!fh) {
Spencer Low5200c662015-07-30 23:07:55 -0700924 PLOG(ERROR) << "adb_socket_accept: failed to allocate accepted socket "
925 "descriptor";
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800926 return -1;
927 }
928
929 fh->fh_socket = accept( serverfh->fh_socket, addr, addrlen );
930 if (fh->fh_socket == INVALID_SOCKET) {
Spencer Low8d8126a2015-07-21 02:06:26 -0700931 const DWORD err = WSAGetLastError();
Spencer Low5200c662015-07-30 23:07:55 -0700932 LOG(ERROR) << "adb_socket_accept: accept on fd " << serverfd <<
933 " failed: " + SystemErrorCodeToString(err);
934 _socket_set_errno( err );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800935 return -1;
936 }
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200937
Spencer Low5200c662015-07-30 23:07:55 -0700938 const int fd = _fh_to_int(fh.get());
939 snprintf( fh->name, sizeof(fh->name), "%d(accept:%s)", fd, serverfh->name );
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700940 D( "adb_socket_accept on fd %d returns fd %d", serverfd, fd );
Spencer Low5200c662015-07-30 23:07:55 -0700941 fh.release();
942 return fd;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800943}
944
945
Spencer Lowf055c192015-01-25 14:40:16 -0800946int adb_setsockopt( int fd, int level, int optname, const void* optval, socklen_t optlen )
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800947{
Spencer Low6ac5d7d2015-05-22 20:09:06 -0700948 FH fh = _fh_from_int(fd, __func__);
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +0200949
Spencer Lowf055c192015-01-25 14:40:16 -0800950 if ( !fh || fh->clazz != &_fh_socket_class ) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700951 D("adb_setsockopt: invalid fd %d", fd);
Spencer Low5200c662015-07-30 23:07:55 -0700952 errno = EBADF;
953 return -1;
954 }
955 int result = setsockopt( fh->fh_socket, level, optname,
956 reinterpret_cast<const char*>(optval), optlen );
957 if ( result == SOCKET_ERROR ) {
958 const DWORD err = WSAGetLastError();
959 D( "adb_setsockopt: setsockopt on fd %d level %d optname %d "
960 "failed: %s\n", fd, level, optname,
961 SystemErrorCodeToString(err).c_str() );
962 _socket_set_errno( err );
963 result = -1;
964 }
965 return result;
966}
967
968
969int adb_shutdown(int fd)
970{
971 FH f = _fh_from_int(fd, __func__);
972
973 if (!f || f->clazz != &_fh_socket_class) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700974 D("adb_shutdown: invalid fd %d", fd);
Spencer Low5200c662015-07-30 23:07:55 -0700975 errno = EBADF;
Spencer Lowf055c192015-01-25 14:40:16 -0800976 return -1;
977 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800978
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700979 D( "adb_shutdown: %s", f->name);
Spencer Low5200c662015-07-30 23:07:55 -0700980 if (shutdown(f->fh_socket, SD_BOTH) == SOCKET_ERROR) {
981 const DWORD err = WSAGetLastError();
Yabin Cui7a3f8d62015-09-02 17:44:28 -0700982 D("socket shutdown fd %d failed: %s", fd,
Spencer Low5200c662015-07-30 23:07:55 -0700983 SystemErrorCodeToString(err).c_str());
984 _socket_set_errno(err);
985 return -1;
986 }
987 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -0800988}
989
990/**************************************************************************/
991/**************************************************************************/
992/***** *****/
993/***** emulated socketpairs *****/
994/***** *****/
995/**************************************************************************/
996/**************************************************************************/
997
998/* we implement socketpairs directly in use space for the following reasons:
999 * - it avoids copying data from/to the Nt kernel
1000 * - it allows us to implement fdevent hooks easily and cheaply, something
1001 * that is not possible with standard Win32 pipes !!
1002 *
1003 * basically, we use two circular buffers, each one corresponding to a given
1004 * direction.
1005 *
1006 * each buffer is implemented as two regions:
1007 *
1008 * region A which is (a_start,a_end)
1009 * region B which is (0, b_end) with b_end <= a_start
1010 *
1011 * an empty buffer has: a_start = a_end = b_end = 0
1012 *
1013 * a_start is the pointer where we start reading data
1014 * a_end is the pointer where we start writing data, unless it is BUFFER_SIZE,
1015 * then you start writing at b_end
1016 *
1017 * the buffer is full when b_end == a_start && a_end == BUFFER_SIZE
1018 *
1019 * there is room when b_end < a_start || a_end < BUFER_SIZE
1020 *
1021 * when reading, a_start is incremented, it a_start meets a_end, then
1022 * we do: a_start = 0, a_end = b_end, b_end = 0, and keep going on..
1023 */
1024
1025#define BIP_BUFFER_SIZE 4096
1026
1027#if 0
1028#include <stdio.h>
1029# define BIPD(x) D x
1030# define BIPDUMP bip_dump_hex
1031
1032static void bip_dump_hex( const unsigned char* ptr, size_t len )
1033{
1034 int nn, len2 = len;
1035
1036 if (len2 > 8) len2 = 8;
1037
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001038 for (nn = 0; nn < len2; nn++)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001039 printf("%02x", ptr[nn]);
1040 printf(" ");
1041
1042 for (nn = 0; nn < len2; nn++) {
1043 int c = ptr[nn];
1044 if (c < 32 || c > 127)
1045 c = '.';
1046 printf("%c", c);
1047 }
1048 printf("\n");
1049 fflush(stdout);
1050}
1051
1052#else
1053# define BIPD(x) do {} while (0)
1054# define BIPDUMP(p,l) BIPD(p)
1055#endif
1056
1057typedef struct BipBufferRec_
1058{
1059 int a_start;
1060 int a_end;
1061 int b_end;
1062 int fdin;
1063 int fdout;
1064 int closed;
1065 int can_write; /* boolean */
1066 HANDLE evt_write; /* event signaled when one can write to a buffer */
1067 int can_read; /* boolean */
1068 HANDLE evt_read; /* event signaled when one can read from a buffer */
1069 CRITICAL_SECTION lock;
1070 unsigned char buff[ BIP_BUFFER_SIZE ];
1071
1072} BipBufferRec, *BipBuffer;
1073
1074static void
1075bip_buffer_init( BipBuffer buffer )
1076{
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001077 D( "bit_buffer_init %p", buffer );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001078 buffer->a_start = 0;
1079 buffer->a_end = 0;
1080 buffer->b_end = 0;
1081 buffer->can_write = 1;
1082 buffer->can_read = 0;
1083 buffer->fdin = 0;
1084 buffer->fdout = 0;
1085 buffer->closed = 0;
1086 buffer->evt_write = CreateEvent( NULL, TRUE, TRUE, NULL );
1087 buffer->evt_read = CreateEvent( NULL, TRUE, FALSE, NULL );
1088 InitializeCriticalSection( &buffer->lock );
1089}
1090
1091static void
1092bip_buffer_close( BipBuffer bip )
1093{
1094 bip->closed = 1;
1095
1096 if (!bip->can_read) {
1097 SetEvent( bip->evt_read );
1098 }
1099 if (!bip->can_write) {
1100 SetEvent( bip->evt_write );
1101 }
1102}
1103
1104static void
1105bip_buffer_done( BipBuffer bip )
1106{
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001107 BIPD(( "bip_buffer_done: %d->%d", bip->fdin, bip->fdout ));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001108 CloseHandle( bip->evt_read );
1109 CloseHandle( bip->evt_write );
1110 DeleteCriticalSection( &bip->lock );
1111}
1112
1113static int
1114bip_buffer_write( BipBuffer bip, const void* src, int len )
1115{
1116 int avail, count = 0;
1117
1118 if (len <= 0)
1119 return 0;
1120
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001121 BIPD(( "bip_buffer_write: enter %d->%d len %d", bip->fdin, bip->fdout, len ));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001122 BIPDUMP( src, len );
1123
David Pursellb404dec2015-09-11 16:06:59 -07001124 if (bip->closed) {
1125 errno = EPIPE;
1126 return -1;
1127 }
1128
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001129 EnterCriticalSection( &bip->lock );
1130
1131 while (!bip->can_write) {
1132 int ret;
1133 LeaveCriticalSection( &bip->lock );
1134
1135 if (bip->closed) {
1136 errno = EPIPE;
1137 return -1;
1138 }
1139 /* spinlocking here is probably unfair, but let's live with it */
1140 ret = WaitForSingleObject( bip->evt_write, INFINITE );
1141 if (ret != WAIT_OBJECT_0) { /* buffer probably closed */
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001142 D( "bip_buffer_write: error %d->%d WaitForSingleObject returned %d, error %ld", bip->fdin, bip->fdout, ret, GetLastError() );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001143 return 0;
1144 }
1145 if (bip->closed) {
1146 errno = EPIPE;
1147 return -1;
1148 }
1149 EnterCriticalSection( &bip->lock );
1150 }
1151
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001152 BIPD(( "bip_buffer_write: exec %d->%d len %d", bip->fdin, bip->fdout, len ));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001153
1154 avail = BIP_BUFFER_SIZE - bip->a_end;
1155 if (avail > 0)
1156 {
1157 /* we can append to region A */
1158 if (avail > len)
1159 avail = len;
1160
1161 memcpy( bip->buff + bip->a_end, src, avail );
Mark Salyzyn60299df2014-04-30 09:10:31 -07001162 src = (const char *)src + avail;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001163 count += avail;
1164 len -= avail;
1165
1166 bip->a_end += avail;
1167 if (bip->a_end == BIP_BUFFER_SIZE && bip->a_start == 0) {
1168 bip->can_write = 0;
1169 ResetEvent( bip->evt_write );
1170 goto Exit;
1171 }
1172 }
1173
1174 if (len == 0)
1175 goto Exit;
1176
1177 avail = bip->a_start - bip->b_end;
1178 assert( avail > 0 ); /* since can_write is TRUE */
1179
1180 if (avail > len)
1181 avail = len;
1182
1183 memcpy( bip->buff + bip->b_end, src, avail );
1184 count += avail;
1185 bip->b_end += avail;
1186
1187 if (bip->b_end == bip->a_start) {
1188 bip->can_write = 0;
1189 ResetEvent( bip->evt_write );
1190 }
1191
1192Exit:
1193 assert( count > 0 );
1194
1195 if ( !bip->can_read ) {
1196 bip->can_read = 1;
1197 SetEvent( bip->evt_read );
1198 }
1199
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001200 BIPD(( "bip_buffer_write: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001201 bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
1202 LeaveCriticalSection( &bip->lock );
1203
1204 return count;
1205 }
1206
1207static int
1208bip_buffer_read( BipBuffer bip, void* dst, int len )
1209{
1210 int avail, count = 0;
1211
1212 if (len <= 0)
1213 return 0;
1214
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001215 BIPD(( "bip_buffer_read: enter %d->%d len %d", bip->fdin, bip->fdout, len ));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001216
1217 EnterCriticalSection( &bip->lock );
1218 while ( !bip->can_read )
1219 {
1220#if 0
1221 LeaveCriticalSection( &bip->lock );
1222 errno = EAGAIN;
1223 return -1;
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001224#else
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001225 int ret;
1226 LeaveCriticalSection( &bip->lock );
1227
1228 if (bip->closed) {
1229 errno = EPIPE;
1230 return -1;
1231 }
1232
1233 ret = WaitForSingleObject( bip->evt_read, INFINITE );
1234 if (ret != WAIT_OBJECT_0) { /* probably closed buffer */
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001235 D( "bip_buffer_read: error %d->%d WaitForSingleObject returned %d, error %ld", bip->fdin, bip->fdout, ret, GetLastError());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001236 return 0;
1237 }
1238 if (bip->closed) {
1239 errno = EPIPE;
1240 return -1;
1241 }
1242 EnterCriticalSection( &bip->lock );
1243#endif
1244 }
1245
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001246 BIPD(( "bip_buffer_read: exec %d->%d len %d", bip->fdin, bip->fdout, len ));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001247
1248 avail = bip->a_end - bip->a_start;
1249 assert( avail > 0 ); /* since can_read is TRUE */
1250
1251 if (avail > len)
1252 avail = len;
1253
1254 memcpy( dst, bip->buff + bip->a_start, avail );
Mark Salyzyn60299df2014-04-30 09:10:31 -07001255 dst = (char *)dst + avail;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001256 count += avail;
1257 len -= avail;
1258
1259 bip->a_start += avail;
1260 if (bip->a_start < bip->a_end)
1261 goto Exit;
1262
1263 bip->a_start = 0;
1264 bip->a_end = bip->b_end;
1265 bip->b_end = 0;
1266
1267 avail = bip->a_end;
1268 if (avail > 0) {
1269 if (avail > len)
1270 avail = len;
1271 memcpy( dst, bip->buff, avail );
1272 count += avail;
1273 bip->a_start += avail;
1274
1275 if ( bip->a_start < bip->a_end )
1276 goto Exit;
1277
1278 bip->a_start = bip->a_end = 0;
1279 }
1280
1281 bip->can_read = 0;
1282 ResetEvent( bip->evt_read );
1283
1284Exit:
1285 assert( count > 0 );
1286
1287 if (!bip->can_write ) {
1288 bip->can_write = 1;
1289 SetEvent( bip->evt_write );
1290 }
1291
1292 BIPDUMP( (const unsigned char*)dst - count, count );
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001293 BIPD(( "bip_buffer_read: exit %d->%d count %d (as=%d ae=%d be=%d cw=%d cr=%d",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001294 bip->fdin, bip->fdout, count, bip->a_start, bip->a_end, bip->b_end, bip->can_write, bip->can_read ));
1295 LeaveCriticalSection( &bip->lock );
1296
1297 return count;
1298}
1299
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001300typedef struct SocketPairRec_
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001301{
1302 BipBufferRec a2b_bip;
1303 BipBufferRec b2a_bip;
1304 FH a_fd;
1305 int used;
1306
1307} SocketPairRec;
1308
1309void _fh_socketpair_init( FH f )
1310{
1311 f->fh_pair = NULL;
1312}
1313
1314static int
1315_fh_socketpair_close( FH f )
1316{
1317 if ( f->fh_pair ) {
1318 SocketPair pair = f->fh_pair;
1319
1320 if ( f == pair->a_fd ) {
1321 pair->a_fd = NULL;
1322 }
1323
1324 bip_buffer_close( &pair->b2a_bip );
1325 bip_buffer_close( &pair->a2b_bip );
1326
1327 if ( --pair->used == 0 ) {
1328 bip_buffer_done( &pair->b2a_bip );
1329 bip_buffer_done( &pair->a2b_bip );
1330 free( pair );
1331 }
1332 f->fh_pair = NULL;
1333 }
1334 return 0;
1335}
1336
1337static int
1338_fh_socketpair_lseek( FH f, int pos, int origin )
1339{
1340 errno = ESPIPE;
1341 return -1;
1342}
1343
1344static int
1345_fh_socketpair_read( FH f, void* buf, int len )
1346{
1347 SocketPair pair = f->fh_pair;
1348 BipBuffer bip;
1349
1350 if (!pair)
1351 return -1;
1352
1353 if ( f == pair->a_fd )
1354 bip = &pair->b2a_bip;
1355 else
1356 bip = &pair->a2b_bip;
1357
1358 return bip_buffer_read( bip, buf, len );
1359}
1360
1361static int
1362_fh_socketpair_write( FH f, const void* buf, int len )
1363{
1364 SocketPair pair = f->fh_pair;
1365 BipBuffer bip;
1366
1367 if (!pair)
1368 return -1;
1369
1370 if ( f == pair->a_fd )
1371 bip = &pair->a2b_bip;
1372 else
1373 bip = &pair->b2a_bip;
1374
1375 return bip_buffer_write( bip, buf, len );
1376}
1377
1378
1379static void _fh_socketpair_hook( FH f, int event, EventHook hook ); /* forward */
1380
1381static const FHClassRec _fh_socketpair_class =
1382{
1383 _fh_socketpair_init,
1384 _fh_socketpair_close,
1385 _fh_socketpair_lseek,
1386 _fh_socketpair_read,
1387 _fh_socketpair_write,
1388 _fh_socketpair_hook
1389};
1390
1391
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001392int adb_socketpair(int sv[2]) {
1393 SocketPair pair;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001394
Spencer Low5200c662015-07-30 23:07:55 -07001395 unique_fh fa(_fh_alloc(&_fh_socketpair_class));
1396 if (!fa) {
1397 return -1;
1398 }
1399 unique_fh fb(_fh_alloc(&_fh_socketpair_class));
1400 if (!fb) {
1401 return -1;
1402 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001403
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001404 pair = reinterpret_cast<SocketPair>(malloc(sizeof(*pair)));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001405 if (pair == NULL) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001406 D("adb_socketpair: not enough memory to allocate pipes" );
Spencer Low5200c662015-07-30 23:07:55 -07001407 return -1;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001408 }
1409
1410 bip_buffer_init( &pair->a2b_bip );
1411 bip_buffer_init( &pair->b2a_bip );
1412
1413 fa->fh_pair = pair;
1414 fb->fh_pair = pair;
1415 pair->used = 2;
Spencer Low5200c662015-07-30 23:07:55 -07001416 pair->a_fd = fa.get();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001417
Spencer Low5200c662015-07-30 23:07:55 -07001418 sv[0] = _fh_to_int(fa.get());
1419 sv[1] = _fh_to_int(fb.get());
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001420
1421 pair->a2b_bip.fdin = sv[0];
1422 pair->a2b_bip.fdout = sv[1];
1423 pair->b2a_bip.fdin = sv[1];
1424 pair->b2a_bip.fdout = sv[0];
1425
1426 snprintf( fa->name, sizeof(fa->name), "%d(pair:%d)", sv[0], sv[1] );
1427 snprintf( fb->name, sizeof(fb->name), "%d(pair:%d)", sv[1], sv[0] );
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001428 D( "adb_socketpair: returns (%d, %d)", sv[0], sv[1] );
Spencer Low5200c662015-07-30 23:07:55 -07001429 fa.release();
1430 fb.release();
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001431 return 0;
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001432}
1433
1434/**************************************************************************/
1435/**************************************************************************/
1436/***** *****/
1437/***** fdevents emulation *****/
1438/***** *****/
1439/***** this is a very simple implementation, we rely on the fact *****/
1440/***** that ADB doesn't use FDE_ERROR. *****/
1441/***** *****/
1442/**************************************************************************/
1443/**************************************************************************/
1444
1445#define FATAL(x...) fatal(__FUNCTION__, x)
1446
1447#if DEBUG
1448static void dump_fde(fdevent *fde, const char *info)
1449{
1450 fprintf(stderr,"FDE #%03d %c%c%c %s\n", fde->fd,
1451 fde->state & FDE_READ ? 'R' : ' ',
1452 fde->state & FDE_WRITE ? 'W' : ' ',
1453 fde->state & FDE_ERROR ? 'E' : ' ',
1454 info);
1455}
1456#else
1457#define dump_fde(fde, info) do { } while(0)
1458#endif
1459
1460#define FDE_EVENTMASK 0x00ff
1461#define FDE_STATEMASK 0xff00
1462
1463#define FDE_ACTIVE 0x0100
1464#define FDE_PENDING 0x0200
1465#define FDE_CREATED 0x0400
1466
1467static void fdevent_plist_enqueue(fdevent *node);
1468static void fdevent_plist_remove(fdevent *node);
1469static fdevent *fdevent_plist_dequeue(void);
1470
1471static fdevent list_pending = {
1472 .next = &list_pending,
1473 .prev = &list_pending,
1474};
1475
1476static fdevent **fd_table = 0;
1477static int fd_table_max = 0;
1478
1479typedef struct EventLooperRec_* EventLooper;
1480
1481typedef struct EventHookRec_
1482{
1483 EventHook next;
1484 FH fh;
1485 HANDLE h;
1486 int wanted; /* wanted event flags */
1487 int ready; /* ready event flags */
1488 void* aux;
1489 void (*prepare)( EventHook hook );
1490 int (*start) ( EventHook hook );
1491 void (*stop) ( EventHook hook );
1492 int (*check) ( EventHook hook );
1493 int (*peek) ( EventHook hook );
1494} EventHookRec;
1495
1496static EventHook _free_hooks;
1497
1498static EventHook
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001499event_hook_alloc(FH fh) {
1500 EventHook hook = _free_hooks;
1501 if (hook != NULL) {
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001502 _free_hooks = hook->next;
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001503 } else {
1504 hook = reinterpret_cast<EventHook>(malloc(sizeof(*hook)));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001505 if (hook == NULL)
1506 fatal( "could not allocate event hook\n" );
1507 }
1508 hook->next = NULL;
1509 hook->fh = fh;
1510 hook->wanted = 0;
1511 hook->ready = 0;
1512 hook->h = INVALID_HANDLE_VALUE;
1513 hook->aux = NULL;
1514
1515 hook->prepare = NULL;
1516 hook->start = NULL;
1517 hook->stop = NULL;
1518 hook->check = NULL;
1519 hook->peek = NULL;
1520
1521 return hook;
1522}
1523
1524static void
1525event_hook_free( EventHook hook )
1526{
1527 hook->fh = NULL;
1528 hook->wanted = 0;
1529 hook->ready = 0;
1530 hook->next = _free_hooks;
1531 _free_hooks = hook;
1532}
1533
1534
1535static void
1536event_hook_signal( EventHook hook )
1537{
1538 FH f = hook->fh;
1539 int fd = _fh_to_int(f);
1540 fdevent* fde = fd_table[ fd - WIN32_FH_BASE ];
1541
1542 if (fde != NULL && fde->fd == fd) {
1543 if ((fde->state & FDE_PENDING) == 0) {
1544 fde->state |= FDE_PENDING;
1545 fdevent_plist_enqueue( fde );
1546 }
1547 fde->events |= hook->wanted;
1548 }
1549}
1550
1551
1552#define MAX_LOOPER_HANDLES WIN32_MAX_FHS
1553
1554typedef struct EventLooperRec_
1555{
1556 EventHook hooks;
1557 HANDLE htab[ MAX_LOOPER_HANDLES ];
1558 int htab_count;
1559
1560} EventLooperRec;
1561
1562static EventHook*
1563event_looper_find_p( EventLooper looper, FH fh )
1564{
1565 EventHook *pnode = &looper->hooks;
1566 EventHook node = *pnode;
1567 for (;;) {
1568 if ( node == NULL || node->fh == fh )
1569 break;
1570 pnode = &node->next;
1571 node = *pnode;
1572 }
1573 return pnode;
1574}
1575
1576static void
1577event_looper_hook( EventLooper looper, int fd, int events )
1578{
Spencer Low6ac5d7d2015-05-22 20:09:06 -07001579 FH f = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001580 EventHook *pnode;
1581 EventHook node;
1582
1583 if (f == NULL) /* invalid arg */ {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001584 D("event_looper_hook: invalid fd=%d", fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001585 return;
1586 }
1587
1588 pnode = event_looper_find_p( looper, f );
1589 node = *pnode;
1590 if ( node == NULL ) {
1591 node = event_hook_alloc( f );
1592 node->next = *pnode;
1593 *pnode = node;
1594 }
1595
1596 if ( (node->wanted & events) != events ) {
1597 /* this should update start/stop/check/peek */
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001598 D("event_looper_hook: call hook for %d (new=%x, old=%x)",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001599 fd, node->wanted, events);
1600 f->clazz->_fh_hook( f, events & ~node->wanted, node );
1601 node->wanted |= events;
1602 } else {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001603 D("event_looper_hook: ignoring events %x for %d wanted=%x)",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001604 events, fd, node->wanted);
1605 }
1606}
1607
1608static void
1609event_looper_unhook( EventLooper looper, int fd, int events )
1610{
Spencer Low6ac5d7d2015-05-22 20:09:06 -07001611 FH fh = _fh_from_int(fd, __func__);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001612 EventHook *pnode = event_looper_find_p( looper, fh );
1613 EventHook node = *pnode;
1614
1615 if (node != NULL) {
1616 int events2 = events & node->wanted;
1617 if ( events2 == 0 ) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001618 D( "event_looper_unhook: events %x not registered for fd %d", events, fd );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001619 return;
1620 }
1621 node->wanted &= ~events2;
1622 if (!node->wanted) {
1623 *pnode = node->next;
1624 event_hook_free( node );
1625 }
1626 }
1627}
1628
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001629/*
1630 * A fixer for WaitForMultipleObjects on condition that there are more than 64
1631 * handles to wait on.
1632 *
1633 * In cetain cases DDMS may establish more than 64 connections with ADB. For
1634 * instance, this may happen if there are more than 64 processes running on a
1635 * device, or there are multiple devices connected (including the emulator) with
1636 * the combined number of running processes greater than 64. In this case using
1637 * WaitForMultipleObjects to wait on connection events simply wouldn't cut,
1638 * because of the API limitations (64 handles max). So, we need to provide a way
1639 * to scale WaitForMultipleObjects to accept an arbitrary number of handles. The
1640 * easiest (and "Microsoft recommended") way to do that would be dividing the
1641 * handle array into chunks with the chunk size less than 64, and fire up as many
1642 * waiting threads as there are chunks. Then each thread would wait on a chunk of
1643 * handles, and will report back to the caller which handle has been set.
1644 * Here is the implementation of that algorithm.
1645 */
1646
1647/* Number of handles to wait on in each wating thread. */
1648#define WAIT_ALL_CHUNK_SIZE 63
1649
1650/* Descriptor for a wating thread */
1651typedef struct WaitForAllParam {
1652 /* A handle to an event to signal when waiting is over. This handle is shared
1653 * accross all the waiting threads, so each waiting thread knows when any
1654 * other thread has exited, so it can exit too. */
1655 HANDLE main_event;
1656 /* Upon exit from a waiting thread contains the index of the handle that has
1657 * been signaled. The index is an absolute index of the signaled handle in
1658 * the original array. This pointer is shared accross all the waiting threads
1659 * and it's not guaranteed (due to a race condition) that when all the
1660 * waiting threads exit, the value contained here would indicate the first
1661 * handle that was signaled. This is fine, because the caller cares only
1662 * about any handle being signaled. It doesn't care about the order, nor
1663 * about the whole list of handles that were signaled. */
1664 LONG volatile *signaled_index;
1665 /* Array of handles to wait on in a waiting thread. */
1666 HANDLE* handles;
1667 /* Number of handles in 'handles' array to wait on. */
1668 int handles_count;
1669 /* Index inside the main array of the first handle in the 'handles' array. */
1670 int first_handle_index;
1671 /* Waiting thread handle. */
1672 HANDLE thread;
1673} WaitForAllParam;
1674
1675/* Waiting thread routine. */
1676static unsigned __stdcall
1677_in_waiter_thread(void* arg)
1678{
1679 HANDLE wait_on[WAIT_ALL_CHUNK_SIZE + 1];
1680 int res;
1681 WaitForAllParam* const param = (WaitForAllParam*)arg;
1682
1683 /* We have to wait on the main_event in order to be notified when any of the
1684 * sibling threads is exiting. */
1685 wait_on[0] = param->main_event;
1686 /* The rest of the handles go behind the main event handle. */
1687 memcpy(wait_on + 1, param->handles, param->handles_count * sizeof(HANDLE));
1688
1689 res = WaitForMultipleObjects(param->handles_count + 1, wait_on, FALSE, INFINITE);
1690 if (res > 0 && res < (param->handles_count + 1)) {
1691 /* One of the original handles got signaled. Save its absolute index into
1692 * the output variable. */
1693 InterlockedCompareExchange(param->signaled_index,
1694 res - 1L + param->first_handle_index, -1L);
1695 }
1696
1697 /* Notify the caller (and the siblings) that the wait is over. */
1698 SetEvent(param->main_event);
1699
1700 _endthreadex(0);
1701 return 0;
1702}
1703
1704/* WaitForMultipeObjects fixer routine.
1705 * Param:
1706 * handles Array of handles to wait on.
1707 * handles_count Number of handles in the array.
1708 * Return:
1709 * (>= 0 && < handles_count) - Index of the signaled handle in the array, or
1710 * WAIT_FAILED on an error.
1711 */
1712static int
1713_wait_for_all(HANDLE* handles, int handles_count)
1714{
1715 WaitForAllParam* threads;
1716 HANDLE main_event;
1717 int chunks, chunk, remains;
1718
1719 /* This variable is going to be accessed by several threads at the same time,
1720 * this is bound to fail randomly when the core is run on multi-core machines.
1721 * To solve this, we need to do the following (1 _and_ 2):
1722 * 1. Use the "volatile" qualifier to ensure the compiler doesn't optimize
1723 * out the reads/writes in this function unexpectedly.
1724 * 2. Ensure correct memory ordering. The "simple" way to do that is to wrap
1725 * all accesses inside a critical section. But we can also use
1726 * InterlockedCompareExchange() which always provide a full memory barrier
1727 * on Win32.
1728 */
1729 volatile LONG sig_index = -1;
1730
1731 /* Calculate number of chunks, and allocate thread param array. */
1732 chunks = handles_count / WAIT_ALL_CHUNK_SIZE;
1733 remains = handles_count % WAIT_ALL_CHUNK_SIZE;
1734 threads = (WaitForAllParam*)malloc((chunks + (remains ? 1 : 0)) *
1735 sizeof(WaitForAllParam));
1736 if (threads == NULL) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001737 D("Unable to allocate thread array for %d handles.", handles_count);
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001738 return (int)WAIT_FAILED;
1739 }
1740
1741 /* Create main event to wait on for all waiting threads. This is a "manualy
1742 * reset" event that will remain set once it was set. */
1743 main_event = CreateEvent(NULL, TRUE, FALSE, NULL);
1744 if (main_event == NULL) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001745 D("Unable to create main event. Error: %ld", GetLastError());
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001746 free(threads);
1747 return (int)WAIT_FAILED;
1748 }
1749
1750 /*
1751 * Initialize waiting thread parameters.
1752 */
1753
1754 for (chunk = 0; chunk < chunks; chunk++) {
1755 threads[chunk].main_event = main_event;
1756 threads[chunk].signaled_index = &sig_index;
1757 threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
1758 threads[chunk].handles = handles + threads[chunk].first_handle_index;
1759 threads[chunk].handles_count = WAIT_ALL_CHUNK_SIZE;
1760 }
1761 if (remains) {
1762 threads[chunk].main_event = main_event;
1763 threads[chunk].signaled_index = &sig_index;
1764 threads[chunk].first_handle_index = WAIT_ALL_CHUNK_SIZE * chunk;
1765 threads[chunk].handles = handles + threads[chunk].first_handle_index;
1766 threads[chunk].handles_count = remains;
1767 chunks++;
1768 }
1769
1770 /* Start the waiting threads. */
1771 for (chunk = 0; chunk < chunks; chunk++) {
1772 /* Note that using adb_thread_create is not appropriate here, since we
1773 * need a handle to wait on for thread termination. */
1774 threads[chunk].thread = (HANDLE)_beginthreadex(NULL, 0, _in_waiter_thread,
1775 &threads[chunk], 0, NULL);
1776 if (threads[chunk].thread == NULL) {
1777 /* Unable to create a waiter thread. Collapse. */
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001778 D("Unable to create a waiting thread %d of %d. errno=%d",
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001779 chunk, chunks, errno);
1780 chunks = chunk;
1781 SetEvent(main_event);
1782 break;
1783 }
1784 }
1785
1786 /* Wait on any of the threads to get signaled. */
1787 WaitForSingleObject(main_event, INFINITE);
1788
1789 /* Wait on all the waiting threads to exit. */
1790 for (chunk = 0; chunk < chunks; chunk++) {
1791 WaitForSingleObject(threads[chunk].thread, INFINITE);
1792 CloseHandle(threads[chunk].thread);
1793 }
1794
1795 CloseHandle(main_event);
1796 free(threads);
1797
1798
1799 const int ret = (int)InterlockedCompareExchange(&sig_index, -1, -1);
1800 return (ret >= 0) ? ret : (int)WAIT_FAILED;
1801}
1802
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001803static EventLooperRec win32_looper;
1804
1805static void fdevent_init(void)
1806{
1807 win32_looper.htab_count = 0;
1808 win32_looper.hooks = NULL;
1809}
1810
1811static void fdevent_connect(fdevent *fde)
1812{
1813 EventLooper looper = &win32_looper;
1814 int events = fde->state & FDE_EVENTMASK;
1815
1816 if (events != 0)
1817 event_looper_hook( looper, fde->fd, events );
1818}
1819
1820static void fdevent_disconnect(fdevent *fde)
1821{
1822 EventLooper looper = &win32_looper;
1823 int events = fde->state & FDE_EVENTMASK;
1824
1825 if (events != 0)
1826 event_looper_unhook( looper, fde->fd, events );
1827}
1828
1829static void fdevent_update(fdevent *fde, unsigned events)
1830{
1831 EventLooper looper = &win32_looper;
1832 unsigned events0 = fde->state & FDE_EVENTMASK;
1833
1834 if (events != events0) {
1835 int removes = events0 & ~events;
1836 int adds = events & ~events0;
1837 if (removes) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001838 D("fdevent_update: remove %x from %d", removes, fde->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001839 event_looper_unhook( looper, fde->fd, removes );
1840 }
1841 if (adds) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001842 D("fdevent_update: add %x to %d", adds, fde->fd);
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001843 event_looper_hook ( looper, fde->fd, adds );
1844 }
1845 }
1846}
1847
1848static void fdevent_process()
1849{
1850 EventLooper looper = &win32_looper;
1851 EventHook hook;
1852 int gotone = 0;
1853
1854 /* if we have at least one ready hook, execute it/them */
1855 for (hook = looper->hooks; hook; hook = hook->next) {
1856 hook->ready = 0;
1857 if (hook->prepare) {
1858 hook->prepare(hook);
1859 if (hook->ready != 0) {
1860 event_hook_signal( hook );
1861 gotone = 1;
1862 }
1863 }
1864 }
1865
1866 /* nothing's ready yet, so wait for something to happen */
1867 if (!gotone)
1868 {
1869 looper->htab_count = 0;
1870
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001871 for (hook = looper->hooks; hook; hook = hook->next)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001872 {
1873 if (hook->start && !hook->start(hook)) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001874 D( "fdevent_process: error when starting a hook" );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001875 return;
1876 }
1877 if (hook->h != INVALID_HANDLE_VALUE) {
1878 int nn;
1879
1880 for (nn = 0; nn < looper->htab_count; nn++)
1881 {
1882 if ( looper->htab[nn] == hook->h )
1883 goto DontAdd;
1884 }
1885 looper->htab[ looper->htab_count++ ] = hook->h;
1886 DontAdd:
1887 ;
1888 }
1889 }
1890
1891 if (looper->htab_count == 0) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001892 D( "fdevent_process: nothing to wait for !!" );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001893 return;
1894 }
1895
1896 do
1897 {
1898 int wait_ret;
1899
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001900 D( "adb_win32: waiting for %d events", looper->htab_count );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001901 if (looper->htab_count > MAXIMUM_WAIT_OBJECTS) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001902 D("handle count %d exceeds MAXIMUM_WAIT_OBJECTS.", looper->htab_count);
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08001903 wait_ret = _wait_for_all(looper->htab, looper->htab_count);
1904 } else {
1905 wait_ret = WaitForMultipleObjects( looper->htab_count, looper->htab, FALSE, INFINITE );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001906 }
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001907 if (wait_ret == (int)WAIT_FAILED) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001908 D( "adb_win32: wait failed, error %ld", GetLastError() );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001909 } else {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001910 D( "adb_win32: got one (index %d)", wait_ret );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001911
1912 /* according to Cygwin, some objects like consoles wake up on "inappropriate" events
1913 * like mouse movements. we need to filter these with the "check" function
1914 */
1915 if ((unsigned)wait_ret < (unsigned)looper->htab_count)
1916 {
1917 for (hook = looper->hooks; hook; hook = hook->next)
1918 {
1919 if ( looper->htab[wait_ret] == hook->h &&
1920 (!hook->check || hook->check(hook)) )
1921 {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07001922 D( "adb_win32: signaling %s for %x", hook->fh->name, hook->ready );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001923 event_hook_signal( hook );
1924 gotone = 1;
1925 break;
1926 }
1927 }
1928 }
1929 }
1930 }
1931 while (!gotone);
1932
1933 for (hook = looper->hooks; hook; hook = hook->next) {
1934 if (hook->stop)
1935 hook->stop( hook );
1936 }
1937 }
1938
1939 for (hook = looper->hooks; hook; hook = hook->next) {
1940 if (hook->peek && hook->peek(hook))
1941 event_hook_signal( hook );
1942 }
1943}
1944
1945
1946static void fdevent_register(fdevent *fde)
1947{
1948 int fd = fde->fd - WIN32_FH_BASE;
1949
1950 if(fd < 0) {
1951 FATAL("bogus negative fd (%d)\n", fde->fd);
1952 }
1953
1954 if(fd >= fd_table_max) {
1955 int oldmax = fd_table_max;
1956 if(fde->fd > 32000) {
1957 FATAL("bogus huuuuge fd (%d)\n", fde->fd);
1958 }
1959 if(fd_table_max == 0) {
1960 fdevent_init();
1961 fd_table_max = 256;
1962 }
1963 while(fd_table_max <= fd) {
1964 fd_table_max *= 2;
1965 }
Elliott Hughesa2f2e562015-04-16 16:47:02 -07001966 fd_table = reinterpret_cast<fdevent**>(realloc(fd_table, sizeof(fdevent*) * fd_table_max));
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08001967 if(fd_table == 0) {
1968 FATAL("could not expand fd_table to %d entries\n", fd_table_max);
1969 }
1970 memset(fd_table + oldmax, 0, sizeof(int) * (fd_table_max - oldmax));
1971 }
1972
1973 fd_table[fd] = fde;
1974}
1975
1976static void fdevent_unregister(fdevent *fde)
1977{
1978 int fd = fde->fd - WIN32_FH_BASE;
1979
1980 if((fd < 0) || (fd >= fd_table_max)) {
1981 FATAL("fd out of range (%d)\n", fde->fd);
1982 }
1983
1984 if(fd_table[fd] != fde) {
1985 FATAL("fd_table out of sync");
1986 }
1987
1988 fd_table[fd] = 0;
1989
1990 if(!(fde->state & FDE_DONT_CLOSE)) {
1991 dump_fde(fde, "close");
1992 adb_close(fde->fd);
1993 }
1994}
1995
1996static void fdevent_plist_enqueue(fdevent *node)
1997{
1998 fdevent *list = &list_pending;
1999
2000 node->next = list;
2001 node->prev = list->prev;
2002 node->prev->next = node;
2003 list->prev = node;
2004}
2005
2006static void fdevent_plist_remove(fdevent *node)
2007{
2008 node->prev->next = node->next;
2009 node->next->prev = node->prev;
2010 node->next = 0;
2011 node->prev = 0;
2012}
2013
2014static fdevent *fdevent_plist_dequeue(void)
2015{
2016 fdevent *list = &list_pending;
2017 fdevent *node = list->next;
2018
2019 if(node == list) return 0;
2020
2021 list->next = node->next;
2022 list->next->prev = list;
2023 node->next = 0;
2024 node->prev = 0;
2025
2026 return node;
2027}
2028
2029fdevent *fdevent_create(int fd, fd_func func, void *arg)
2030{
2031 fdevent *fde = (fdevent*) malloc(sizeof(fdevent));
2032 if(fde == 0) return 0;
2033 fdevent_install(fde, fd, func, arg);
2034 fde->state |= FDE_CREATED;
2035 return fde;
2036}
2037
2038void fdevent_destroy(fdevent *fde)
2039{
2040 if(fde == 0) return;
2041 if(!(fde->state & FDE_CREATED)) {
2042 FATAL("fde %p not created by fdevent_create()\n", fde);
2043 }
2044 fdevent_remove(fde);
2045}
2046
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08002047void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002048{
2049 memset(fde, 0, sizeof(fdevent));
2050 fde->state = FDE_ACTIVE;
2051 fde->fd = fd;
2052 fde->func = func;
2053 fde->arg = arg;
2054
2055 fdevent_register(fde);
2056 dump_fde(fde, "connect");
2057 fdevent_connect(fde);
2058 fde->state |= FDE_ACTIVE;
2059}
2060
2061void fdevent_remove(fdevent *fde)
2062{
2063 if(fde->state & FDE_PENDING) {
2064 fdevent_plist_remove(fde);
2065 }
2066
2067 if(fde->state & FDE_ACTIVE) {
2068 fdevent_disconnect(fde);
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08002069 dump_fde(fde, "disconnect");
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002070 fdevent_unregister(fde);
2071 }
2072
2073 fde->state = 0;
2074 fde->events = 0;
2075}
2076
2077
2078void fdevent_set(fdevent *fde, unsigned events)
2079{
2080 events &= FDE_EVENTMASK;
2081
2082 if((fde->state & FDE_EVENTMASK) == (int)events) return;
2083
2084 if(fde->state & FDE_ACTIVE) {
2085 fdevent_update(fde, events);
2086 dump_fde(fde, "update");
2087 }
2088
2089 fde->state = (fde->state & FDE_STATEMASK) | events;
2090
2091 if(fde->state & FDE_PENDING) {
2092 /* if we're pending, make sure
2093 ** we don't signal an event that
2094 ** is no longer wanted.
2095 */
2096 fde->events &= (~events);
2097 if(fde->events == 0) {
2098 fdevent_plist_remove(fde);
2099 fde->state &= (~FDE_PENDING);
2100 }
2101 }
2102}
2103
2104void fdevent_add(fdevent *fde, unsigned events)
2105{
2106 fdevent_set(
2107 fde, (fde->state & FDE_EVENTMASK) | (events & FDE_EVENTMASK));
2108}
2109
2110void fdevent_del(fdevent *fde, unsigned events)
2111{
2112 fdevent_set(
2113 fde, (fde->state & FDE_EVENTMASK) & (~(events & FDE_EVENTMASK)));
2114}
2115
2116void fdevent_loop()
2117{
2118 fdevent *fde;
2119
2120 for(;;) {
2121#if DEBUG
2122 fprintf(stderr,"--- ---- waiting for events\n");
2123#endif
2124 fdevent_process();
2125
2126 while((fde = fdevent_plist_dequeue())) {
2127 unsigned events = fde->events;
2128 fde->events = 0;
2129 fde->state &= (~FDE_PENDING);
2130 dump_fde(fde, "callback");
2131 fde->func(fde->fd, events, fde->arg);
2132 }
2133 }
2134}
2135
2136/** FILE EVENT HOOKS
2137 **/
David 'Digit' Turnerf6330a22009-05-18 17:36:28 +02002138
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002139static void _event_file_prepare( EventHook hook )
2140{
2141 if (hook->wanted & (FDE_READ|FDE_WRITE)) {
2142 /* we can always read/write */
2143 hook->ready |= hook->wanted & (FDE_READ|FDE_WRITE);
2144 }
2145}
2146
2147static int _event_file_peek( EventHook hook )
2148{
2149 return (hook->wanted & (FDE_READ|FDE_WRITE));
2150}
2151
2152static void _fh_file_hook( FH f, int events, EventHook hook )
2153{
2154 hook->h = f->fh_handle;
2155 hook->prepare = _event_file_prepare;
2156 hook->peek = _event_file_peek;
2157}
2158
2159/** SOCKET EVENT HOOKS
2160 **/
2161
2162static void _event_socket_verify( EventHook hook, WSANETWORKEVENTS* evts )
2163{
2164 if ( evts->lNetworkEvents & (FD_READ|FD_ACCEPT|FD_CLOSE) ) {
2165 if (hook->wanted & FDE_READ)
2166 hook->ready |= FDE_READ;
2167 if ((evts->iErrorCode[FD_READ] != 0) && hook->wanted & FDE_ERROR)
2168 hook->ready |= FDE_ERROR;
2169 }
2170 if ( evts->lNetworkEvents & (FD_WRITE|FD_CONNECT|FD_CLOSE) ) {
2171 if (hook->wanted & FDE_WRITE)
2172 hook->ready |= FDE_WRITE;
2173 if ((evts->iErrorCode[FD_WRITE] != 0) && hook->wanted & FDE_ERROR)
2174 hook->ready |= FDE_ERROR;
2175 }
2176 if ( evts->lNetworkEvents & FD_OOB ) {
2177 if (hook->wanted & FDE_ERROR)
2178 hook->ready |= FDE_ERROR;
2179 }
2180}
2181
2182static void _event_socket_prepare( EventHook hook )
2183{
2184 WSANETWORKEVENTS evts;
2185
2186 /* look if some of the events we want already happened ? */
2187 if (!WSAEnumNetworkEvents( hook->fh->fh_socket, NULL, &evts ))
2188 _event_socket_verify( hook, &evts );
2189}
2190
2191static int _socket_wanted_to_flags( int wanted )
2192{
2193 int flags = 0;
2194 if (wanted & FDE_READ)
2195 flags |= FD_READ | FD_ACCEPT | FD_CLOSE;
2196
2197 if (wanted & FDE_WRITE)
2198 flags |= FD_WRITE | FD_CONNECT | FD_CLOSE;
2199
2200 if (wanted & FDE_ERROR)
2201 flags |= FD_OOB;
2202
2203 return flags;
2204}
2205
2206static int _event_socket_start( EventHook hook )
2207{
2208 /* create an event which we're going to wait for */
2209 FH fh = hook->fh;
2210 long flags = _socket_wanted_to_flags( hook->wanted );
2211
2212 hook->h = fh->event;
2213 if (hook->h == INVALID_HANDLE_VALUE) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07002214 D( "_event_socket_start: no event for %s", fh->name );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002215 return 0;
2216 }
2217
2218 if ( flags != fh->mask ) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07002219 D( "_event_socket_start: hooking %s for %x (flags %ld)", hook->fh->name, hook->wanted, flags );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002220 if ( WSAEventSelect( fh->fh_socket, hook->h, flags ) ) {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07002221 D( "_event_socket_start: WSAEventSelect() for %s failed, error %d", hook->fh->name, WSAGetLastError() );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002222 CloseHandle( hook->h );
2223 hook->h = INVALID_HANDLE_VALUE;
2224 exit(1);
2225 return 0;
2226 }
2227 fh->mask = flags;
2228 }
2229 return 1;
2230}
2231
2232static void _event_socket_stop( EventHook hook )
2233{
2234 hook->h = INVALID_HANDLE_VALUE;
2235}
2236
2237static int _event_socket_check( EventHook hook )
2238{
2239 int result = 0;
2240 FH fh = hook->fh;
2241 WSANETWORKEVENTS evts;
2242
2243 if (!WSAEnumNetworkEvents( fh->fh_socket, hook->h, &evts ) ) {
2244 _event_socket_verify( hook, &evts );
2245 result = (hook->ready != 0);
2246 if (result) {
2247 ResetEvent( hook->h );
2248 }
2249 }
Yabin Cui7a3f8d62015-09-02 17:44:28 -07002250 D( "_event_socket_check %s returns %d", fh->name, result );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002251 return result;
2252}
2253
2254static int _event_socket_peek( EventHook hook )
2255{
2256 WSANETWORKEVENTS evts;
2257 FH fh = hook->fh;
2258
2259 /* look if some of the events we want already happened ? */
2260 if (!WSAEnumNetworkEvents( fh->fh_socket, NULL, &evts )) {
2261 _event_socket_verify( hook, &evts );
2262 if (hook->ready)
2263 ResetEvent( hook->h );
2264 }
2265
2266 return hook->ready != 0;
2267}
2268
2269
2270
2271static void _fh_socket_hook( FH f, int events, EventHook hook )
2272{
2273 hook->prepare = _event_socket_prepare;
2274 hook->start = _event_socket_start;
2275 hook->stop = _event_socket_stop;
2276 hook->check = _event_socket_check;
2277 hook->peek = _event_socket_peek;
2278
Spencer Low5200c662015-07-30 23:07:55 -07002279 // TODO: check return value?
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002280 _event_socket_start( hook );
2281}
2282
2283/** SOCKETPAIR EVENT HOOKS
2284 **/
2285
2286static void _event_socketpair_prepare( EventHook hook )
2287{
2288 FH fh = hook->fh;
2289 SocketPair pair = fh->fh_pair;
2290 BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
2291 BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
2292
2293 if (hook->wanted & FDE_READ && rbip->can_read)
2294 hook->ready |= FDE_READ;
2295
Vladimir Chtchetkinece480832011-11-30 10:20:27 -08002296 if (hook->wanted & FDE_WRITE && wbip->can_write)
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002297 hook->ready |= FDE_WRITE;
2298 }
2299
2300 static int _event_socketpair_start( EventHook hook )
2301 {
2302 FH fh = hook->fh;
2303 SocketPair pair = fh->fh_pair;
2304 BipBuffer rbip = (pair->a_fd == fh) ? &pair->b2a_bip : &pair->a2b_bip;
2305 BipBuffer wbip = (pair->a_fd == fh) ? &pair->a2b_bip : &pair->b2a_bip;
2306
2307 if (hook->wanted == FDE_READ)
2308 hook->h = rbip->evt_read;
2309
2310 else if (hook->wanted == FDE_WRITE)
2311 hook->h = wbip->evt_write;
2312
2313 else {
Yabin Cui7a3f8d62015-09-02 17:44:28 -07002314 D("_event_socketpair_start: can't handle FDE_READ+FDE_WRITE" );
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002315 return 0;
2316 }
Yabin Cui7a3f8d62015-09-02 17:44:28 -07002317 D( "_event_socketpair_start: hook %s for %x wanted=%x",
The Android Open Source Projectdd7bc332009-03-03 19:32:55 -08002318 hook->fh->name, _fh_to_int(fh), hook->wanted);
2319 return 1;
2320}
2321
2322static int _event_socketpair_peek( EventHook hook )
2323{
2324 _event_socketpair_prepare( hook );
2325 return hook->ready != 0;
2326}
2327
2328static void _fh_socketpair_hook( FH fh, int events, EventHook hook )
2329{
2330 hook->prepare = _event_socketpair_prepare;
2331 hook->start = _event_socketpair_start;
2332 hook->peek = _event_socketpair_peek;
2333}
2334
2335
2336void
2337adb_sysdeps_init( void )
2338{
2339#define ADB_MUTEX(x) InitializeCriticalSection( & x );
2340#include "mutex_list.h"
2341 InitializeCriticalSection( &_win32_lock );
2342}
2343
Spencer Low50184062015-03-01 15:06:21 -08002344/**************************************************************************/
2345/**************************************************************************/
2346/***** *****/
2347/***** Console Window Terminal Emulation *****/
2348/***** *****/
2349/**************************************************************************/
2350/**************************************************************************/
2351
2352// This reads input from a Win32 console window and translates it into Unix
2353// terminal-style sequences. This emulates mostly Gnome Terminal (in Normal
2354// mode, not Application mode), which itself emulates xterm. Gnome Terminal
2355// is emulated instead of xterm because it is probably more popular than xterm:
2356// Ubuntu's default Ctrl-Alt-T shortcut opens Gnome Terminal, Gnome Terminal
2357// supports modern fonts, etc. It seems best to emulate the terminal that most
2358// Android developers use because they'll fix apps (the shell, etc.) to keep
2359// working with that terminal's emulation.
2360//
2361// The point of this emulation is not to be perfect or to solve all issues with
2362// console windows on Windows, but to be better than the original code which
2363// just called read() (which called ReadFile(), which called ReadConsoleA())
2364// which did not support Ctrl-C, tab completion, shell input line editing
2365// keys, server echo, and more.
2366//
2367// This implementation reconfigures the console with SetConsoleMode(), then
2368// calls ReadConsoleInput() to get raw input which it remaps to Unix
2369// terminal-style sequences which is returned via unix_read() which is used
2370// by the 'adb shell' command.
2371//
2372// Code organization:
2373//
2374// * stdin_raw_init() and stdin_raw_restore() reconfigure the console.
2375// * unix_read() detects console windows (as opposed to pipes, files, etc.).
2376// * _console_read() is the main code of the emulation.
2377
2378
2379// Read an input record from the console; one that should be processed.
2380static bool _get_interesting_input_record_uncached(const HANDLE console,
2381 INPUT_RECORD* const input_record) {
2382 for (;;) {
2383 DWORD read_count = 0;
2384 memset(input_record, 0, sizeof(*input_record));
2385 if (!ReadConsoleInputA(console, input_record, 1, &read_count)) {
2386 D("_get_interesting_input_record_uncached: ReadConsoleInputA() "
Spencer Low8df90322015-08-02 18:50:17 -07002387 "failed: %s\n", SystemErrorCodeToString(GetLastError()).c_str());
Spencer Low50184062015-03-01 15:06:21 -08002388 errno = EIO;
2389 return false;
2390 }
2391
2392 if (read_count == 0) { // should be impossible
2393 fatal("ReadConsoleInputA returned 0");
2394 }
2395
2396 if (read_count != 1) { // should be impossible
2397 fatal("ReadConsoleInputA did not return one input record");
2398 }
2399
2400 if ((input_record->EventType == KEY_EVENT) &&
2401 (input_record->Event.KeyEvent.bKeyDown)) {
2402 if (input_record->Event.KeyEvent.wRepeatCount == 0) {
2403 fatal("ReadConsoleInputA returned a key event with zero repeat"
2404 " count");
2405 }
2406
2407 // Got an interesting INPUT_RECORD, so return
2408 return true;
2409 }
2410 }
2411}
2412
2413// Cached input record (in case _console_read() is passed a buffer that doesn't
2414// have enough space to fit wRepeatCount number of key sequences). A non-zero
2415// wRepeatCount indicates that a record is cached.
2416static INPUT_RECORD _win32_input_record;
2417
2418// Get the next KEY_EVENT_RECORD that should be processed.
2419static KEY_EVENT_RECORD* _get_key_event_record(const HANDLE console) {
2420 // If nothing cached, read directly from the console until we get an
2421 // interesting record.
2422 if (_win32_input_record.Event.KeyEvent.wRepeatCount == 0) {
2423 if (!_get_interesting_input_record_uncached(console,
2424 &_win32_input_record)) {
2425 // There was an error, so make sure wRepeatCount is zero because
2426 // that signifies no cached input record.
2427 _win32_input_record.Event.KeyEvent.wRepeatCount = 0;
2428 return NULL;
2429 }
2430 }
2431
2432 return &_win32_input_record.Event.KeyEvent;
2433}
2434
2435static __inline__ bool _is_shift_pressed(const DWORD control_key_state) {
2436 return (control_key_state & SHIFT_PRESSED) != 0;
2437}
2438
2439static __inline__ bool _is_ctrl_pressed(const DWORD control_key_state) {
2440 return (control_key_state & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0;
2441}
2442
2443static __inline__ bool _is_alt_pressed(const DWORD control_key_state) {
2444 return (control_key_state & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) != 0;
2445}
2446
2447static __inline__ bool _is_numlock_on(const DWORD control_key_state) {
2448 return (control_key_state & NUMLOCK_ON) != 0;
2449}
2450
2451static __inline__ bool _is_capslock_on(const DWORD control_key_state) {
2452 return (control_key_state & CAPSLOCK_ON) != 0;
2453}
2454
2455static __inline__ bool _is_enhanced_key(const DWORD control_key_state) {
2456 return (control_key_state & ENHANCED_KEY) != 0;
2457}
2458
2459// Constants from MSDN for ToAscii().
2460static const BYTE TOASCII_KEY_OFF = 0x00;
2461static const BYTE TOASCII_KEY_DOWN = 0x80;
2462static const BYTE TOASCII_KEY_TOGGLED_ON = 0x01; // for CapsLock
2463
2464// Given a key event, ignore a modifier key and return the character that was
2465// entered without the modifier. Writes to *ch and returns the number of bytes
2466// written.
2467static size_t _get_char_ignoring_modifier(char* const ch,
2468 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state,
2469 const WORD modifier) {
2470 // If there is no character from Windows, try ignoring the specified
2471 // modifier and look for a character. Note that if AltGr is being used,
2472 // there will be a character from Windows.
2473 if (key_event->uChar.AsciiChar == '\0') {
2474 // Note that we read the control key state from the passed in argument
2475 // instead of from key_event since the argument has been normalized.
2476 if (((modifier == VK_SHIFT) &&
2477 _is_shift_pressed(control_key_state)) ||
2478 ((modifier == VK_CONTROL) &&
2479 _is_ctrl_pressed(control_key_state)) ||
2480 ((modifier == VK_MENU) && _is_alt_pressed(control_key_state))) {
2481
2482 BYTE key_state[256] = {0};
2483 key_state[VK_SHIFT] = _is_shift_pressed(control_key_state) ?
2484 TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
2485 key_state[VK_CONTROL] = _is_ctrl_pressed(control_key_state) ?
2486 TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
2487 key_state[VK_MENU] = _is_alt_pressed(control_key_state) ?
2488 TOASCII_KEY_DOWN : TOASCII_KEY_OFF;
2489 key_state[VK_CAPITAL] = _is_capslock_on(control_key_state) ?
2490 TOASCII_KEY_TOGGLED_ON : TOASCII_KEY_OFF;
2491
2492 // cause this modifier to be ignored
2493 key_state[modifier] = TOASCII_KEY_OFF;
2494
2495 WORD translated = 0;
2496 if (ToAscii(key_event->wVirtualKeyCode,
2497 key_event->wVirtualScanCode, key_state, &translated, 0) == 1) {
2498 // Ignoring the modifier, we found a character.
2499 *ch = (CHAR)translated;
2500 return 1;
2501 }
2502 }
2503 }
2504
2505 // Just use whatever Windows told us originally.
2506 *ch = key_event->uChar.AsciiChar;
2507
2508 // If the character from Windows is NULL, return a size of zero.
2509 return (*ch == '\0') ? 0 : 1;
2510}
2511
2512// If a Ctrl key is pressed, lookup the character, ignoring the Ctrl key,
2513// but taking into account the shift key. This is because for a sequence like
2514// Ctrl-Alt-0, we want to find the character '0' and for Ctrl-Alt-Shift-0,
2515// we want to find the character ')'.
2516//
2517// Note that Windows doesn't seem to pass bKeyDown for Ctrl-Shift-NoAlt-0
2518// because it is the default key-sequence to switch the input language.
2519// This is configurable in the Region and Language control panel.
2520static __inline__ size_t _get_non_control_char(char* const ch,
2521 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
2522 return _get_char_ignoring_modifier(ch, key_event, control_key_state,
2523 VK_CONTROL);
2524}
2525
2526// Get without Alt.
2527static __inline__ size_t _get_non_alt_char(char* const ch,
2528 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
2529 return _get_char_ignoring_modifier(ch, key_event, control_key_state,
2530 VK_MENU);
2531}
2532
2533// Ignore the control key, find the character from Windows, and apply any
2534// Control key mappings (for example, Ctrl-2 is a NULL character). Writes to
2535// *pch and returns number of bytes written.
2536static size_t _get_control_character(char* const pch,
2537 const KEY_EVENT_RECORD* const key_event, const DWORD control_key_state) {
2538 const size_t len = _get_non_control_char(pch, key_event,
2539 control_key_state);
2540
2541 if ((len == 1) && _is_ctrl_pressed(control_key_state)) {
2542 char ch = *pch;
2543 switch (ch) {
2544 case '2':
2545 case '@':
2546 case '`':
2547 ch = '\0';
2548 break;
2549 case '3':
2550 case '[':
2551 case '{':
2552 ch = '\x1b';
2553 break;
2554 case '4':
2555 case '\\':
2556 case '|':
2557 ch = '\x1c';
2558 break;
2559 case '5':
2560 case ']':
2561 case '}':
2562 ch = '\x1d';
2563 break;
2564 case '6':
2565 case '^':
2566 case '~':
2567 ch = '\x1e';
2568 break;
2569 case '7':
2570 case '-':
2571 case '_':
2572 ch = '\x1f';
2573 break;
2574 case '8':
2575 ch = '\x7f';
2576 break;
2577 case '/':
2578 if (!_is_alt_pressed(control_key_state)) {
2579 ch = '\x1f';
2580 }
2581 break;
2582 case '?':
2583 if (!_is_alt_pressed(control_key_state)) {
2584 ch = '\x7f';
2585 }
2586 break;
2587 }
2588 *pch = ch;
2589 }
2590
2591 return len;
2592}
2593
2594static DWORD _normalize_altgr_control_key_state(
2595 const KEY_EVENT_RECORD* const key_event) {
2596 DWORD control_key_state = key_event->dwControlKeyState;
2597
2598 // If we're in an AltGr situation where the AltGr key is down (depending on
2599 // the keyboard layout, that might be the physical right alt key which
2600 // produces a control_key_state where Right-Alt and Left-Ctrl are down) or
2601 // AltGr-equivalent keys are down (any Ctrl key + any Alt key), and we have
2602 // a character (which indicates that there was an AltGr mapping), then act
2603 // as if alt and control are not really down for the purposes of modifiers.
2604 // This makes it so that if the user with, say, a German keyboard layout
2605 // presses AltGr-] (which we see as Right-Alt + Left-Ctrl + key), we just
2606 // output the key and we don't see the Alt and Ctrl keys.
2607 if (_is_ctrl_pressed(control_key_state) &&
2608 _is_alt_pressed(control_key_state)
2609 && (key_event->uChar.AsciiChar != '\0')) {
2610 // Try to remove as few bits as possible to improve our chances of
2611 // detecting combinations like Left-Alt + AltGr, Right-Ctrl + AltGr, or
2612 // Left-Alt + Right-Ctrl + AltGr.
2613 if ((control_key_state & RIGHT_ALT_PRESSED) != 0) {
2614 // Remove Right-Alt.
2615 control_key_state &= ~RIGHT_ALT_PRESSED;
2616 // If uChar is set, a Ctrl key is pressed, and Right-Alt is
2617 // pressed, Left-Ctrl is almost always set, except if the user
2618 // presses Right-Ctrl, then AltGr (in that specific order) for
2619 // whatever reason. At any rate, make sure the bit is not set.
2620 control_key_state &= ~LEFT_CTRL_PRESSED;
2621 } else if ((control_key_state & LEFT_ALT_PRESSED) != 0) {
2622 // Remove Left-Alt.
2623 control_key_state &= ~LEFT_ALT_PRESSED;
2624 // Whichever Ctrl key is down, remove it from the state. We only
2625 // remove one key, to improve our chances of detecting the
2626 // corner-case of Left-Ctrl + Left-Alt + Right-Ctrl.
2627 if ((control_key_state & LEFT_CTRL_PRESSED) != 0) {
2628 // Remove Left-Ctrl.
2629 control_key_state &= ~LEFT_CTRL_PRESSED;
2630 } else if ((control_key_state & RIGHT_CTRL_PRESSED) != 0) {
2631 // Remove Right-Ctrl.
2632 control_key_state &= ~RIGHT_CTRL_PRESSED;
2633 }
2634 }
2635
2636 // Note that this logic isn't 100% perfect because Windows doesn't
2637 // allow us to detect all combinations because a physical AltGr key
2638 // press shows up as two bits, plus some combinations are ambiguous
2639 // about what is actually physically pressed.
2640 }
2641
2642 return control_key_state;
2643}
2644
2645// If NumLock is on and Shift is pressed, SHIFT_PRESSED is not set in
2646// dwControlKeyState for the following keypad keys: period, 0-9. If we detect
2647// this scenario, set the SHIFT_PRESSED bit so we can add modifiers
2648// appropriately.
2649static DWORD _normalize_keypad_control_key_state(const WORD vk,
2650 const DWORD control_key_state) {
2651 if (!_is_numlock_on(control_key_state)) {
2652 return control_key_state;
2653 }
2654 if (!_is_enhanced_key(control_key_state)) {
2655 switch (vk) {
2656 case VK_INSERT: // 0
2657 case VK_DELETE: // .
2658 case VK_END: // 1
2659 case VK_DOWN: // 2
2660 case VK_NEXT: // 3
2661 case VK_LEFT: // 4
2662 case VK_CLEAR: // 5
2663 case VK_RIGHT: // 6
2664 case VK_HOME: // 7
2665 case VK_UP: // 8
2666 case VK_PRIOR: // 9
2667 return control_key_state | SHIFT_PRESSED;
2668 }
2669 }
2670
2671 return control_key_state;
2672}
2673
2674static const char* _get_keypad_sequence(const DWORD control_key_state,
2675 const char* const normal, const char* const shifted) {
2676 if (_is_shift_pressed(control_key_state)) {
2677 // Shift is pressed and NumLock is off
2678 return shifted;
2679 } else {
2680 // Shift is not pressed and NumLock is off, or,
2681 // Shift is pressed and NumLock is on, in which case we want the
2682 // NumLock and Shift to neutralize each other, thus, we want the normal
2683 // sequence.
2684 return normal;
2685 }
2686 // If Shift is not pressed and NumLock is on, a different virtual key code
2687 // is returned by Windows, which can be taken care of by a different case
2688 // statement in _console_read().
2689}
2690
2691// Write sequence to buf and return the number of bytes written.
2692static size_t _get_modifier_sequence(char* const buf, const WORD vk,
2693 DWORD control_key_state, const char* const normal) {
2694 // Copy the base sequence into buf.
2695 const size_t len = strlen(normal);
2696 memcpy(buf, normal, len);
2697
2698 int code = 0;
2699
2700 control_key_state = _normalize_keypad_control_key_state(vk,
2701 control_key_state);
2702
2703 if (_is_shift_pressed(control_key_state)) {
2704 code |= 0x1;
2705 }
2706 if (_is_alt_pressed(control_key_state)) { // any alt key pressed
2707 code |= 0x2;
2708 }
2709 if (_is_ctrl_pressed(control_key_state)) { // any control key pressed
2710 code |= 0x4;
2711 }
2712 // If some modifier was held down, then we need to insert the modifier code
2713 if (code != 0) {
2714 if (len == 0) {
2715 // Should be impossible because caller should pass a string of
2716 // non-zero length.
2717 return 0;
2718 }
2719 size_t index = len - 1;
2720 const char lastChar = buf[index];
2721 if (lastChar != '~') {
2722 buf[index++] = '1';
2723 }
2724 buf[index++] = ';'; // modifier separator
2725 // 2 = shift, 3 = alt, 4 = shift & alt, 5 = control,
2726 // 6 = shift & control, 7 = alt & control, 8 = shift & alt & control
2727 buf[index++] = '1' + code;
2728 buf[index++] = lastChar; // move ~ (or other last char) to the end
2729 return index;
2730 }
2731 return len;
2732}
2733
2734// Write sequence to buf and return the number of bytes written.
2735static size_t _get_modifier_keypad_sequence(char* const buf, const WORD vk,
2736 const DWORD control_key_state, const char* const normal,
2737 const char shifted) {
2738 if (_is_shift_pressed(control_key_state)) {
2739 // Shift is pressed and NumLock is off
2740 if (shifted != '\0') {
2741 buf[0] = shifted;
2742 return sizeof(buf[0]);
2743 } else {
2744 return 0;
2745 }
2746 } else {
2747 // Shift is not pressed and NumLock is off, or,
2748 // Shift is pressed and NumLock is on, in which case we want the
2749 // NumLock and Shift to neutralize each other, thus, we want the normal
2750 // sequence.
2751 return _get_modifier_sequence(buf, vk, control_key_state, normal);
2752 }
2753 // If Shift is not pressed and NumLock is on, a different virtual key code
2754 // is returned by Windows, which can be taken care of by a different case
2755 // statement in _console_read().
2756}
2757
2758// The decimal key on the keypad produces a '.' for U.S. English and a ',' for
2759// Standard German. Figure this out at runtime so we know what to output for
2760// Shift-VK_DELETE.
2761static char _get_decimal_char() {
2762 return (char)MapVirtualKeyA(VK_DECIMAL, MAPVK_VK_TO_CHAR);
2763}
2764
2765// Prefix the len bytes in buf with the escape character, and then return the
2766// new buffer length.
2767size_t _escape_prefix(char* const buf, const size_t len) {
2768 // If nothing to prefix, don't do anything. We might be called with
2769 // len == 0, if alt was held down with a dead key which produced nothing.
2770 if (len == 0) {
2771 return 0;
2772 }
2773
2774 memmove(&buf[1], buf, len);
2775 buf[0] = '\x1b';
2776 return len + 1;
2777}
2778
2779// Writes to buffer buf (of length len), returning number of bytes written or
2780// -1 on error. Never returns zero because Win32 consoles are never 'closed'
2781// (as far as I can tell).
2782static int _console_read(const HANDLE console, void* buf, size_t len) {
2783 for (;;) {
2784 KEY_EVENT_RECORD* const key_event = _get_key_event_record(console);
2785 if (key_event == NULL) {
2786 return -1;
2787 }
2788
2789 const WORD vk = key_event->wVirtualKeyCode;
2790 const CHAR ch = key_event->uChar.AsciiChar;
2791 const DWORD control_key_state = _normalize_altgr_control_key_state(
2792 key_event);
2793
2794 // The following emulation code should write the output sequence to
2795 // either seqstr or to seqbuf and seqbuflen.
2796 const char* seqstr = NULL; // NULL terminated C-string
2797 // Enough space for max sequence string below, plus modifiers and/or
2798 // escape prefix.
2799 char seqbuf[16];
2800 size_t seqbuflen = 0; // Space used in seqbuf.
2801
2802#define MATCH(vk, normal) \
2803 case (vk): \
2804 { \
2805 seqstr = (normal); \
2806 } \
2807 break;
2808
2809 // Modifier keys should affect the output sequence.
2810#define MATCH_MODIFIER(vk, normal) \
2811 case (vk): \
2812 { \
2813 seqbuflen = _get_modifier_sequence(seqbuf, (vk), \
2814 control_key_state, (normal)); \
2815 } \
2816 break;
2817
2818 // The shift key should affect the output sequence.
2819#define MATCH_KEYPAD(vk, normal, shifted) \
2820 case (vk): \
2821 { \
2822 seqstr = _get_keypad_sequence(control_key_state, (normal), \
2823 (shifted)); \
2824 } \
2825 break;
2826
2827 // The shift key and other modifier keys should affect the output
2828 // sequence.
2829#define MATCH_MODIFIER_KEYPAD(vk, normal, shifted) \
2830 case (vk): \
2831 { \
2832 seqbuflen = _get_modifier_keypad_sequence(seqbuf, (vk), \
2833 control_key_state, (normal), (shifted)); \
2834 } \
2835 break;
2836
2837#define ESC "\x1b"
2838#define CSI ESC "["
2839#define SS3 ESC "O"
2840
2841 // Only support normal mode, not application mode.
2842
2843 // Enhanced keys:
2844 // * 6-pack: insert, delete, home, end, page up, page down
2845 // * cursor keys: up, down, right, left
2846 // * keypad: divide, enter
2847 // * Undocumented: VK_PAUSE (Ctrl-NumLock), VK_SNAPSHOT,
2848 // VK_CANCEL (Ctrl-Pause/Break), VK_NUMLOCK
2849 if (_is_enhanced_key(control_key_state)) {
2850 switch (vk) {
2851 case VK_RETURN: // Enter key on keypad
2852 if (_is_ctrl_pressed(control_key_state)) {
2853 seqstr = "\n";
2854 } else {
2855 seqstr = "\r";
2856 }
2857 break;
2858
2859 MATCH_MODIFIER(VK_PRIOR, CSI "5~"); // Page Up
2860 MATCH_MODIFIER(VK_NEXT, CSI "6~"); // Page Down
2861
2862 // gnome-terminal currently sends SS3 "F" and SS3 "H", but that
2863 // will be fixed soon to match xterm which sends CSI "F" and
2864 // CSI "H". https://bugzilla.redhat.com/show_bug.cgi?id=1119764
2865 MATCH(VK_END, CSI "F");
2866 MATCH(VK_HOME, CSI "H");
2867
2868 MATCH_MODIFIER(VK_LEFT, CSI "D");
2869 MATCH_MODIFIER(VK_UP, CSI "A");
2870 MATCH_MODIFIER(VK_RIGHT, CSI "C");
2871 MATCH_MODIFIER(VK_DOWN, CSI "B");
2872
2873 MATCH_MODIFIER(VK_INSERT, CSI "2~");
2874 MATCH_MODIFIER(VK_DELETE, CSI "3~");
2875
2876 MATCH(VK_DIVIDE, "/");
2877 }
2878 } else { // Non-enhanced keys:
2879 switch (vk) {
2880 case VK_BACK: // backspace
2881 if (_is_alt_pressed(control_key_state)) {
2882 seqstr = ESC "\x7f";
2883 } else {
2884 seqstr = "\x7f";
2885 }
2886 break;
2887
2888 case VK_TAB:
2889 if (_is_shift_pressed(control_key_state)) {
2890 seqstr = CSI "Z";
2891 } else {
2892 seqstr = "\t";
2893 }
2894 break;
2895
2896 // Number 5 key in keypad when NumLock is off, or if NumLock is
2897 // on and Shift is down.
2898 MATCH_KEYPAD(VK_CLEAR, CSI "E", "5");
2899
2900 case VK_RETURN: // Enter key on main keyboard
2901 if (_is_alt_pressed(control_key_state)) {
2902 seqstr = ESC "\n";
2903 } else if (_is_ctrl_pressed(control_key_state)) {
2904 seqstr = "\n";
2905 } else {
2906 seqstr = "\r";
2907 }
2908 break;
2909
2910 // VK_ESCAPE: Don't do any special handling. The OS uses many
2911 // of the sequences with Escape and many of the remaining
2912 // sequences don't produce bKeyDown messages, only !bKeyDown
2913 // for whatever reason.
2914
2915 case VK_SPACE:
2916 if (_is_alt_pressed(control_key_state)) {
2917 seqstr = ESC " ";
2918 } else if (_is_ctrl_pressed(control_key_state)) {
2919 seqbuf[0] = '\0'; // NULL char
2920 seqbuflen = 1;
2921 } else {
2922 seqstr = " ";
2923 }
2924 break;
2925
2926 MATCH_MODIFIER_KEYPAD(VK_PRIOR, CSI "5~", '9'); // Page Up
2927 MATCH_MODIFIER_KEYPAD(VK_NEXT, CSI "6~", '3'); // Page Down
2928
2929 MATCH_KEYPAD(VK_END, CSI "4~", "1");
2930 MATCH_KEYPAD(VK_HOME, CSI "1~", "7");
2931
2932 MATCH_MODIFIER_KEYPAD(VK_LEFT, CSI "D", '4');
2933 MATCH_MODIFIER_KEYPAD(VK_UP, CSI "A", '8');
2934 MATCH_MODIFIER_KEYPAD(VK_RIGHT, CSI "C", '6');
2935 MATCH_MODIFIER_KEYPAD(VK_DOWN, CSI "B", '2');
2936
2937 MATCH_MODIFIER_KEYPAD(VK_INSERT, CSI "2~", '0');
2938 MATCH_MODIFIER_KEYPAD(VK_DELETE, CSI "3~",
2939 _get_decimal_char());
2940
2941 case 0x30: // 0
2942 case 0x31: // 1
2943 case 0x39: // 9
2944 case VK_OEM_1: // ;:
2945 case VK_OEM_PLUS: // =+
2946 case VK_OEM_COMMA: // ,<
2947 case VK_OEM_PERIOD: // .>
2948 case VK_OEM_7: // '"
2949 case VK_OEM_102: // depends on keyboard, could be <> or \|
2950 case VK_OEM_2: // /?
2951 case VK_OEM_3: // `~
2952 case VK_OEM_4: // [{
2953 case VK_OEM_5: // \|
2954 case VK_OEM_6: // ]}
2955 {
2956 seqbuflen = _get_control_character(seqbuf, key_event,
2957 control_key_state);
2958
2959 if (_is_alt_pressed(control_key_state)) {
2960 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
2961 }
2962 }
2963 break;
2964
2965 case 0x32: // 2
2966 case 0x36: // 6
2967 case VK_OEM_MINUS: // -_
2968 {
2969 seqbuflen = _get_control_character(seqbuf, key_event,
2970 control_key_state);
2971
2972 // If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
2973 // prefix with escape.
2974 if (_is_alt_pressed(control_key_state) &&
2975 !(_is_ctrl_pressed(control_key_state) &&
2976 !_is_shift_pressed(control_key_state))) {
2977 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
2978 }
2979 }
2980 break;
2981
2982 case 0x33: // 3
2983 case 0x34: // 4
2984 case 0x35: // 5
2985 case 0x37: // 7
2986 case 0x38: // 8
2987 {
2988 seqbuflen = _get_control_character(seqbuf, key_event,
2989 control_key_state);
2990
2991 // If Alt is pressed and it isn't Ctrl-Alt-ShiftUp, then
2992 // prefix with escape.
2993 if (_is_alt_pressed(control_key_state) &&
2994 !(_is_ctrl_pressed(control_key_state) &&
2995 !_is_shift_pressed(control_key_state))) {
2996 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
2997 }
2998 }
2999 break;
3000
3001 case 0x41: // a
3002 case 0x42: // b
3003 case 0x43: // c
3004 case 0x44: // d
3005 case 0x45: // e
3006 case 0x46: // f
3007 case 0x47: // g
3008 case 0x48: // h
3009 case 0x49: // i
3010 case 0x4a: // j
3011 case 0x4b: // k
3012 case 0x4c: // l
3013 case 0x4d: // m
3014 case 0x4e: // n
3015 case 0x4f: // o
3016 case 0x50: // p
3017 case 0x51: // q
3018 case 0x52: // r
3019 case 0x53: // s
3020 case 0x54: // t
3021 case 0x55: // u
3022 case 0x56: // v
3023 case 0x57: // w
3024 case 0x58: // x
3025 case 0x59: // y
3026 case 0x5a: // z
3027 {
3028 seqbuflen = _get_non_alt_char(seqbuf, key_event,
3029 control_key_state);
3030
3031 // If Alt is pressed, then prefix with escape.
3032 if (_is_alt_pressed(control_key_state)) {
3033 seqbuflen = _escape_prefix(seqbuf, seqbuflen);
3034 }
3035 }
3036 break;
3037
3038 // These virtual key codes are generated by the keys on the
3039 // keypad *when NumLock is on* and *Shift is up*.
3040 MATCH(VK_NUMPAD0, "0");
3041 MATCH(VK_NUMPAD1, "1");
3042 MATCH(VK_NUMPAD2, "2");
3043 MATCH(VK_NUMPAD3, "3");
3044 MATCH(VK_NUMPAD4, "4");
3045 MATCH(VK_NUMPAD5, "5");
3046 MATCH(VK_NUMPAD6, "6");
3047 MATCH(VK_NUMPAD7, "7");
3048 MATCH(VK_NUMPAD8, "8");
3049 MATCH(VK_NUMPAD9, "9");
3050
3051 MATCH(VK_MULTIPLY, "*");
3052 MATCH(VK_ADD, "+");
3053 MATCH(VK_SUBTRACT, "-");
3054 // VK_DECIMAL is generated by the . key on the keypad *when
3055 // NumLock is on* and *Shift is up* and the sequence is not
3056 // Ctrl-Alt-NoShift-. (which causes Ctrl-Alt-Del and the
3057 // Windows Security screen to come up).
3058 case VK_DECIMAL:
3059 // U.S. English uses '.', Germany German uses ','.
3060 seqbuflen = _get_non_control_char(seqbuf, key_event,
3061 control_key_state);
3062 break;
3063
3064 MATCH_MODIFIER(VK_F1, SS3 "P");
3065 MATCH_MODIFIER(VK_F2, SS3 "Q");
3066 MATCH_MODIFIER(VK_F3, SS3 "R");
3067 MATCH_MODIFIER(VK_F4, SS3 "S");
3068 MATCH_MODIFIER(VK_F5, CSI "15~");
3069 MATCH_MODIFIER(VK_F6, CSI "17~");
3070 MATCH_MODIFIER(VK_F7, CSI "18~");
3071 MATCH_MODIFIER(VK_F8, CSI "19~");
3072 MATCH_MODIFIER(VK_F9, CSI "20~");
3073 MATCH_MODIFIER(VK_F10, CSI "21~");
3074 MATCH_MODIFIER(VK_F11, CSI "23~");
3075 MATCH_MODIFIER(VK_F12, CSI "24~");
3076
3077 MATCH_MODIFIER(VK_F13, CSI "25~");
3078 MATCH_MODIFIER(VK_F14, CSI "26~");
3079 MATCH_MODIFIER(VK_F15, CSI "28~");
3080 MATCH_MODIFIER(VK_F16, CSI "29~");
3081 MATCH_MODIFIER(VK_F17, CSI "31~");
3082 MATCH_MODIFIER(VK_F18, CSI "32~");
3083 MATCH_MODIFIER(VK_F19, CSI "33~");
3084 MATCH_MODIFIER(VK_F20, CSI "34~");
3085
3086 // MATCH_MODIFIER(VK_F21, ???);
3087 // MATCH_MODIFIER(VK_F22, ???);
3088 // MATCH_MODIFIER(VK_F23, ???);
3089 // MATCH_MODIFIER(VK_F24, ???);
3090 }
3091 }
3092
3093#undef MATCH
3094#undef MATCH_MODIFIER
3095#undef MATCH_KEYPAD
3096#undef MATCH_MODIFIER_KEYPAD
3097#undef ESC
3098#undef CSI
3099#undef SS3
3100
3101 const char* out;
3102 size_t outlen;
3103
3104 // Check for output in any of:
3105 // * seqstr is set (and strlen can be used to determine the length).
3106 // * seqbuf and seqbuflen are set
3107 // Fallback to ch from Windows.
3108 if (seqstr != NULL) {
3109 out = seqstr;
3110 outlen = strlen(seqstr);
3111 } else if (seqbuflen > 0) {
3112 out = seqbuf;
3113 outlen = seqbuflen;
3114 } else if (ch != '\0') {
3115 // Use whatever Windows told us it is.
3116 seqbuf[0] = ch;
3117 seqbuflen = 1;
3118 out = seqbuf;
3119 outlen = seqbuflen;
3120 } else {
3121 // No special handling for the virtual key code and Windows isn't
3122 // telling us a character code, then we don't know how to translate
3123 // the key press.
3124 //
3125 // Consume the input and 'continue' to cause us to get a new key
3126 // event.
Yabin Cui7a3f8d62015-09-02 17:44:28 -07003127 D("_console_read: unknown virtual key code: %d, enhanced: %s",
Spencer Low50184062015-03-01 15:06:21 -08003128 vk, _is_enhanced_key(control_key_state) ? "true" : "false");
3129 key_event->wRepeatCount = 0;
3130 continue;
3131 }
3132
3133 int bytesRead = 0;
3134
3135 // put output wRepeatCount times into buf/len
3136 while (key_event->wRepeatCount > 0) {
3137 if (len >= outlen) {
3138 // Write to buf/len
3139 memcpy(buf, out, outlen);
3140 buf = (void*)((char*)buf + outlen);
3141 len -= outlen;
3142 bytesRead += outlen;
3143
3144 // consume the input
3145 --key_event->wRepeatCount;
3146 } else {
3147 // Not enough space, so just leave it in _win32_input_record
3148 // for a subsequent retrieval.
3149 if (bytesRead == 0) {
3150 // We didn't write anything because there wasn't enough
3151 // space to even write one sequence. This should never
3152 // happen if the caller uses sensible buffer sizes
3153 // (i.e. >= maximum sequence length which is probably a
3154 // few bytes long).
3155 D("_console_read: no buffer space to write one sequence; "
3156 "buffer: %ld, sequence: %ld\n", (long)len,
3157 (long)outlen);
3158 errno = ENOMEM;
3159 return -1;
3160 } else {
3161 // Stop trying to write to buf/len, just return whatever
3162 // we wrote so far.
3163 break;
3164 }
3165 }
3166 }
3167
3168 return bytesRead;
3169 }
3170}
3171
3172static DWORD _old_console_mode; // previous GetConsoleMode() result
3173static HANDLE _console_handle; // when set, console mode should be restored
3174
3175void stdin_raw_init(const int fd) {
3176 if (STDIN_FILENO == fd) {
3177 const HANDLE in = GetStdHandle(STD_INPUT_HANDLE);
3178 if ((in == INVALID_HANDLE_VALUE) || (in == NULL)) {
3179 return;
3180 }
3181
3182 if (GetFileType(in) != FILE_TYPE_CHAR) {
3183 // stdin might be a file or pipe.
3184 return;
3185 }
3186
3187 if (!GetConsoleMode(in, &_old_console_mode)) {
3188 // If GetConsoleMode() fails, stdin is probably is not a console.
3189 return;
3190 }
3191
3192 // Disable ENABLE_PROCESSED_INPUT so that Ctrl-C is read instead of
3193 // calling the process Ctrl-C routine (configured by
3194 // SetConsoleCtrlHandler()).
3195 // Disable ENABLE_LINE_INPUT so that input is immediately sent.
3196 // Disable ENABLE_ECHO_INPUT to disable local echo. Disabling this
3197 // flag also seems necessary to have proper line-ending processing.
3198 if (!SetConsoleMode(in, _old_console_mode & ~(ENABLE_PROCESSED_INPUT |
3199 ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))) {
3200 // This really should not fail.
Yabin Cui7a3f8d62015-09-02 17:44:28 -07003201 D("stdin_raw_init: SetConsoleMode() failed: %s",
Spencer Low8df90322015-08-02 18:50:17 -07003202 SystemErrorCodeToString(GetLastError()).c_str());
Spencer Low50184062015-03-01 15:06:21 -08003203 }
3204
3205 // Once this is set, it means that stdin has been configured for
3206 // reading from and that the old console mode should be restored later.
3207 _console_handle = in;
3208
3209 // Note that we don't need to configure C Runtime line-ending
3210 // translation because _console_read() does not call the C Runtime to
3211 // read from the console.
3212 }
3213}
3214
3215void stdin_raw_restore(const int fd) {
3216 if (STDIN_FILENO == fd) {
3217 if (_console_handle != NULL) {
3218 const HANDLE in = _console_handle;
3219 _console_handle = NULL; // clear state
3220
3221 if (!SetConsoleMode(in, _old_console_mode)) {
3222 // This really should not fail.
Yabin Cui7a3f8d62015-09-02 17:44:28 -07003223 D("stdin_raw_restore: SetConsoleMode() failed: %s",
Spencer Low8df90322015-08-02 18:50:17 -07003224 SystemErrorCodeToString(GetLastError()).c_str());
Spencer Low50184062015-03-01 15:06:21 -08003225 }
3226 }
3227 }
3228}
3229
Spencer Low6ac5d7d2015-05-22 20:09:06 -07003230// Called by 'adb shell' and 'adb exec-in' to read from stdin.
Spencer Low50184062015-03-01 15:06:21 -08003231int unix_read(int fd, void* buf, size_t len) {
3232 if ((fd == STDIN_FILENO) && (_console_handle != NULL)) {
3233 // If it is a request to read from stdin, and stdin_raw_init() has been
3234 // called, and it successfully configured the console, then read from
3235 // the console using Win32 console APIs and partially emulate a unix
3236 // terminal.
3237 return _console_read(_console_handle, buf, len);
3238 } else {
3239 // Just call into C Runtime which can read from pipes/files and which
Spencer Low6ac5d7d2015-05-22 20:09:06 -07003240 // can do LF/CR translation (which is overridable with _setmode()).
3241 // Undefine the macro that is set in sysdeps.h which bans calls to
3242 // plain read() in favor of unix_read() or adb_read().
3243#pragma push_macro("read")
Spencer Low50184062015-03-01 15:06:21 -08003244#undef read
3245 return read(fd, buf, len);
Spencer Low6ac5d7d2015-05-22 20:09:06 -07003246#pragma pop_macro("read")
Spencer Low50184062015-03-01 15:06:21 -08003247 }
3248}
Spencer Lowcf4ff642015-05-11 01:08:48 -07003249
3250/**************************************************************************/
3251/**************************************************************************/
3252/***** *****/
3253/***** Unicode support *****/
3254/***** *****/
3255/**************************************************************************/
3256/**************************************************************************/
3257
3258// This implements support for using files with Unicode filenames and for
3259// outputting Unicode text to a Win32 console window. This is inspired from
3260// http://utf8everywhere.org/.
3261//
3262// Background
3263// ----------
3264//
3265// On POSIX systems, to deal with files with Unicode filenames, just pass UTF-8
3266// filenames to APIs such as open(). This works because filenames are largely
3267// opaque 'cookies' (perhaps excluding path separators).
3268//
3269// On Windows, the native file APIs such as CreateFileW() take 2-byte wchar_t
3270// UTF-16 strings. There is an API, CreateFileA() that takes 1-byte char
3271// strings, but the strings are in the ANSI codepage and not UTF-8. (The
3272// CreateFile() API is really just a macro that adds the W/A based on whether
3273// the UNICODE preprocessor symbol is defined).
3274//
3275// Options
3276// -------
3277//
3278// Thus, to write a portable program, there are a few options:
3279//
3280// 1. Write the program with wchar_t filenames (wchar_t path[256];).
3281// For Windows, just call CreateFileW(). For POSIX, write a wrapper openW()
3282// that takes a wchar_t string, converts it to UTF-8 and then calls the real
3283// open() API.
3284//
3285// 2. Write the program with a TCHAR typedef that is 2 bytes on Windows and
3286// 1 byte on POSIX. Make T-* wrappers for various OS APIs and call those,
3287// potentially touching a lot of code.
3288//
3289// 3. Write the program with a 1-byte char filenames (char path[256];) that are
3290// UTF-8. For POSIX, just call open(). For Windows, write a wrapper that
3291// takes a UTF-8 string, converts it to UTF-16 and then calls the real OS
3292// or C Runtime API.
3293//
3294// The Choice
3295// ----------
3296//
3297// The code below chooses option 3, the UTF-8 everywhere strategy. It
3298// introduces narrow() which converts UTF-16 to UTF-8. This is used by the
3299// NarrowArgs helper class that is used to convert wmain() args into UTF-8
3300// args that are passed to main() at the beginning of program startup. We also
3301// introduce widen() which converts from UTF-8 to UTF-16. This is used to
3302// implement wrappers below that call UTF-16 OS and C Runtime APIs.
3303//
3304// Unicode console output
3305// ----------------------
3306//
3307// The way to output Unicode to a Win32 console window is to call
3308// WriteConsoleW() with UTF-16 text. (The user must also choose a proper font
Spencer Lowe347c1d2015-08-02 18:13:54 -07003309// such as Lucida Console or Consolas, and in the case of East Asian languages
3310// (such as Chinese, Japanese, Korean), the user must go to the Control Panel
3311// and change the "system locale" to Chinese, etc., which allows a Chinese, etc.
3312// font to be used in console windows.)
Spencer Lowcf4ff642015-05-11 01:08:48 -07003313//
3314// The problem is getting the C Runtime to make fprintf and related APIs call
3315// WriteConsoleW() under the covers. The C Runtime API, _setmode() sounds
3316// promising, but the various modes have issues:
3317//
3318// 1. _setmode(_O_TEXT) (the default) does not use WriteConsoleW() so UTF-8 and
3319// UTF-16 do not display properly.
3320// 2. _setmode(_O_BINARY) does not use WriteConsoleW() and the text comes out
3321// totally wrong.
3322// 3. _setmode(_O_U8TEXT) seems to cause the C Runtime _invalid_parameter
3323// handler to be called (upon a later I/O call), aborting the process.
3324// 4. _setmode(_O_U16TEXT) and _setmode(_O_WTEXT) cause non-wide printf/fprintf
3325// to output nothing.
3326//
3327// So the only solution is to write our own adb_fprintf() that converts UTF-8
3328// to UTF-16 and then calls WriteConsoleW().
3329
3330
3331// Function prototype because attributes cannot be placed on func definitions.
3332static void _widen_fatal(const char *fmt, ...)
3333 __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 1, 2)));
3334
3335// A version of fatal() that does not call adb_(v)fprintf(), so it can be
3336// called from those functions.
3337static void _widen_fatal(const char *fmt, ...) {
3338 va_list ap;
3339 va_start(ap, fmt);
3340 // If (v)fprintf are macros that point to adb_(v)fprintf, when random adb
3341 // code calls (v)fprintf, it may end up calling adb_(v)fprintf, which then
3342 // calls _widen_fatal(). So then how does _widen_fatal() output a error?
3343 // By directly calling real C Runtime APIs that don't properly output
3344 // Unicode, but will be able to get a comprehendible message out. To do
3345 // this, make sure we don't call (v)fprintf macros by undefining them.
3346#pragma push_macro("fprintf")
3347#pragma push_macro("vfprintf")
3348#undef fprintf
3349#undef vfprintf
3350 fprintf(stderr, "error: ");
3351 vfprintf(stderr, fmt, ap);
3352 fprintf(stderr, "\n");
3353#pragma pop_macro("vfprintf")
3354#pragma pop_macro("fprintf")
3355 va_end(ap);
3356 exit(-1);
3357}
3358
3359// TODO: Consider implementing widen() and narrow() out of std::wstring_convert
3360// once libcxx is supported on Windows. Or, consider libutils/Unicode.cpp.
3361
3362// Convert from UTF-8 to UTF-16. A size of -1 specifies a NULL terminated
3363// string. Any other size specifies the number of chars to convert, excluding
3364// any NULL terminator (if you're passing an explicit size, you probably don't
3365// have a NULL terminated string in the first place).
3366std::wstring widen(const char* utf8, const int size) {
Spencer Lowe347c1d2015-08-02 18:13:54 -07003367 // Note: Do not call SystemErrorCodeToString() from widen() because
3368 // SystemErrorCodeToString() calls narrow() which may call fatal() which
3369 // calls adb_vfprintf() which calls widen(), potentially causing infinite
3370 // recursion.
Spencer Lowcf4ff642015-05-11 01:08:48 -07003371 const int chars_to_convert = MultiByteToWideChar(CP_UTF8, 0, utf8, size,
3372 NULL, 0);
3373 if (chars_to_convert <= 0) {
3374 // UTF-8 to UTF-16 should be lossless, so we don't expect this to fail.
3375 _widen_fatal("MultiByteToWideChar failed counting: %d, "
3376 "GetLastError: %lu", chars_to_convert, GetLastError());
3377 }
3378
3379 std::wstring utf16;
3380 size_t chars_to_allocate = chars_to_convert;
3381 if (size == -1) {
3382 // chars_to_convert includes a NULL terminator, so subtract space
3383 // for that because resize() includes that itself.
3384 --chars_to_allocate;
3385 }
3386 utf16.resize(chars_to_allocate);
3387
3388 // This uses &string[0] to get write-access to the entire string buffer
3389 // which may be assuming that the chars are all contiguous, but it seems
3390 // to work and saves us the hassle of using a temporary
3391 // std::vector<wchar_t>.
3392 const int result = MultiByteToWideChar(CP_UTF8, 0, utf8, size, &utf16[0],
3393 chars_to_convert);
3394 if (result != chars_to_convert) {
3395 // UTF-8 to UTF-16 should be lossless, so we don't expect this to fail.
3396 _widen_fatal("MultiByteToWideChar failed conversion: %d, "
3397 "GetLastError: %lu", result, GetLastError());
3398 }
3399
3400 // If a size was passed in (size != -1), then the string is NULL terminated
3401 // by a NULL char that was written by std::string::resize(). If size == -1,
3402 // then MultiByteToWideChar() read a NULL terminator from the original
3403 // string and converted it to a NULL UTF-16 char in the output.
3404
3405 return utf16;
3406}
3407
3408// Convert a NULL terminated string from UTF-8 to UTF-16.
3409std::wstring widen(const char* utf8) {
3410 // Pass -1 to let widen() determine the string length.
3411 return widen(utf8, -1);
3412}
3413
3414// Convert from UTF-8 to UTF-16.
3415std::wstring widen(const std::string& utf8) {
3416 return widen(utf8.c_str(), utf8.length());
3417}
3418
3419// Convert from UTF-16 to UTF-8.
3420std::string narrow(const std::wstring& utf16) {
3421 return narrow(utf16.c_str());
3422}
3423
3424// Convert from UTF-16 to UTF-8.
3425std::string narrow(const wchar_t* utf16) {
Spencer Lowe347c1d2015-08-02 18:13:54 -07003426 // Note: Do not call SystemErrorCodeToString() from narrow() because
Elliott Hughesbfa7c7d2015-08-03 16:26:13 -07003427 // SystemErrorCodeToString() calls narrow() and we don't want potential
Spencer Lowe347c1d2015-08-02 18:13:54 -07003428 // infinite recursion.
Spencer Lowcf4ff642015-05-11 01:08:48 -07003429 const int chars_required = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL,
3430 0, NULL, NULL);
3431 if (chars_required <= 0) {
3432 // UTF-16 to UTF-8 should be lossless, so we don't expect this to fail.
Spencer Lowe347c1d2015-08-02 18:13:54 -07003433 fatal("WideCharToMultiByte failed counting: %d, GetLastError: %lu",
Spencer Lowcf4ff642015-05-11 01:08:48 -07003434 chars_required, GetLastError());
3435 }
3436
3437 std::string utf8;
3438 // Subtract space for the NULL terminator because resize() includes
3439 // that itself. Note that this could potentially throw a std::bad_alloc
3440 // exception.
3441 utf8.resize(chars_required - 1);
3442
3443 // This uses &string[0] to get write-access to the entire string buffer
3444 // which may be assuming that the chars are all contiguous, but it seems
3445 // to work and saves us the hassle of using a temporary
3446 // std::vector<char>.
3447 const int result = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, &utf8[0],
3448 chars_required, NULL, NULL);
3449 if (result != chars_required) {
3450 // UTF-16 to UTF-8 should be lossless, so we don't expect this to fail.
Spencer Lowe347c1d2015-08-02 18:13:54 -07003451 fatal("WideCharToMultiByte failed conversion: %d, GetLastError: %lu",
Spencer Lowcf4ff642015-05-11 01:08:48 -07003452 result, GetLastError());
3453 }
3454
3455 return utf8;
3456}
3457
3458// Constructor for helper class to convert wmain() UTF-16 args to UTF-8 to
3459// be passed to main().
3460NarrowArgs::NarrowArgs(const int argc, wchar_t** const argv) {
3461 narrow_args = new char*[argc + 1];
3462
3463 for (int i = 0; i < argc; ++i) {
3464 narrow_args[i] = strdup(narrow(argv[i]).c_str());
3465 }
3466 narrow_args[argc] = nullptr; // terminate
3467}
3468
3469NarrowArgs::~NarrowArgs() {
3470 if (narrow_args != nullptr) {
3471 for (char** argp = narrow_args; *argp != nullptr; ++argp) {
3472 free(*argp);
3473 }
3474 delete[] narrow_args;
3475 narrow_args = nullptr;
3476 }
3477}
3478
3479int unix_open(const char* path, int options, ...) {
3480 if ((options & O_CREAT) == 0) {
3481 return _wopen(widen(path).c_str(), options);
3482 } else {
3483 int mode;
3484 va_list args;
3485 va_start(args, options);
3486 mode = va_arg(args, int);
3487 va_end(args);
3488 return _wopen(widen(path).c_str(), options, mode);
3489 }
3490}
3491
3492// Version of stat() that takes a UTF-8 path.
3493int adb_stat(const char* f, struct adb_stat* s) {
3494#pragma push_macro("wstat")
3495// This definition of wstat seems to be missing from <sys/stat.h>.
3496#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
3497#ifdef _USE_32BIT_TIME_T
3498#define wstat _wstat32i64
3499#else
3500#define wstat _wstat64
3501#endif
3502#else
3503// <sys/stat.h> has a function prototype for wstat() that should be available.
3504#endif
3505
3506 return wstat(widen(f).c_str(), s);
3507
3508#pragma pop_macro("wstat")
3509}
3510
3511// Version of opendir() that takes a UTF-8 path.
3512DIR* adb_opendir(const char* name) {
3513 // Just cast _WDIR* to DIR*. This doesn't work if the caller reads any of
3514 // the fields, but right now all the callers treat the structure as
3515 // opaque.
3516 return reinterpret_cast<DIR*>(_wopendir(widen(name).c_str()));
3517}
3518
3519// Version of readdir() that returns UTF-8 paths.
3520struct dirent* adb_readdir(DIR* dir) {
3521 _WDIR* const wdir = reinterpret_cast<_WDIR*>(dir);
3522 struct _wdirent* const went = _wreaddir(wdir);
3523 if (went == nullptr) {
3524 return nullptr;
3525 }
3526 // Convert from UTF-16 to UTF-8.
3527 const std::string name_utf8(narrow(went->d_name));
3528
3529 // Cast the _wdirent* to dirent* and overwrite the d_name field (which has
3530 // space for UTF-16 wchar_t's) with UTF-8 char's.
3531 struct dirent* ent = reinterpret_cast<struct dirent*>(went);
3532
3533 if (name_utf8.length() + 1 > sizeof(went->d_name)) {
3534 // Name too big to fit in existing buffer.
3535 errno = ENOMEM;
3536 return nullptr;
3537 }
3538
3539 // Note that sizeof(_wdirent::d_name) is bigger than sizeof(dirent::d_name)
3540 // because _wdirent contains wchar_t instead of char. So even if name_utf8
3541 // can fit in _wdirent::d_name, the resulting dirent::d_name field may be
3542 // bigger than the caller expects because they expect a dirent structure
3543 // which has a smaller d_name field. Ignore this since the caller should be
3544 // resilient.
3545
3546 // Rewrite the UTF-16 d_name field to UTF-8.
3547 strcpy(ent->d_name, name_utf8.c_str());
3548
3549 return ent;
3550}
3551
3552// Version of closedir() to go with our version of adb_opendir().
3553int adb_closedir(DIR* dir) {
3554 return _wclosedir(reinterpret_cast<_WDIR*>(dir));
3555}
3556
3557// Version of unlink() that takes a UTF-8 path.
3558int adb_unlink(const char* path) {
3559 const std::wstring wpath(widen(path));
3560
3561 int rc = _wunlink(wpath.c_str());
3562
3563 if (rc == -1 && errno == EACCES) {
3564 /* unlink returns EACCES when the file is read-only, so we first */
3565 /* try to make it writable, then unlink again... */
3566 rc = _wchmod(wpath.c_str(), _S_IREAD | _S_IWRITE);
3567 if (rc == 0)
3568 rc = _wunlink(wpath.c_str());
3569 }
3570 return rc;
3571}
3572
3573// Version of mkdir() that takes a UTF-8 path.
3574int adb_mkdir(const std::string& path, int mode) {
3575 return _wmkdir(widen(path.c_str()).c_str());
3576}
3577
3578// Version of utime() that takes a UTF-8 path.
3579int adb_utime(const char* path, struct utimbuf* u) {
3580 static_assert(sizeof(struct utimbuf) == sizeof(struct _utimbuf),
3581 "utimbuf and _utimbuf should be the same size because they both "
3582 "contain the same types, namely time_t");
3583 return _wutime(widen(path).c_str(), reinterpret_cast<struct _utimbuf*>(u));
3584}
3585
3586// Version of chmod() that takes a UTF-8 path.
3587int adb_chmod(const char* path, int mode) {
3588 return _wchmod(widen(path).c_str(), mode);
3589}
3590
3591// Internal function to get a Win32 console HANDLE from a C Runtime FILE*.
3592static HANDLE _get_console_handle(FILE* const stream) {
3593 // Get a C Runtime file descriptor number from the FILE* structure.
3594 const int fd = fileno(stream);
3595 if (fd < 0) {
3596 return NULL;
3597 }
3598
3599 // If it is not a "character device", it is probably a file and not a
3600 // console. Do this check early because it is probably cheap. Still do more
3601 // checks after this since there are devices that pass this test, but are
3602 // not a console, such as NUL, the Windows /dev/null equivalent (I think).
3603 if (!isatty(fd)) {
3604 return NULL;
3605 }
3606
3607 // Given a C Runtime file descriptor number, get the underlying OS
3608 // file handle.
3609 const intptr_t osfh = _get_osfhandle(fd);
3610 if (osfh == -1) {
3611 return NULL;
3612 }
3613
3614 const HANDLE h = reinterpret_cast<const HANDLE>(osfh);
3615
3616 DWORD old_mode = 0;
3617 if (!GetConsoleMode(h, &old_mode)) {
3618 return NULL;
3619 }
3620
3621 // If GetConsoleMode() was successful, assume this is a console.
3622 return h;
3623}
3624
3625// Internal helper function to write UTF-8 bytes to a console. Returns -1
3626// on error.
3627static int _console_write_utf8(const char* buf, size_t size, FILE* stream,
3628 HANDLE console) {
3629 // Convert from UTF-8 to UTF-16.
3630 // This could throw std::bad_alloc.
3631 const std::wstring output(widen(buf, size));
3632
3633 // Note that this does not do \n => \r\n translation because that
3634 // doesn't seem necessary for the Windows console. For the Windows
3635 // console \r moves to the beginning of the line and \n moves to a new
3636 // line.
3637
3638 // Flush any stream buffering so that our output is afterwards which
3639 // makes sense because our call is afterwards.
3640 (void)fflush(stream);
3641
3642 // Write UTF-16 to the console.
3643 DWORD written = 0;
3644 if (!WriteConsoleW(console, output.c_str(), output.length(), &written,
3645 NULL)) {
3646 errno = EIO;
3647 return -1;
3648 }
3649
3650 // This is the number of UTF-16 chars written, which might be different
3651 // than the number of UTF-8 chars passed in. It doesn't seem practical to
3652 // get this count correct.
3653 return written;
3654}
3655
3656// Function prototype because attributes cannot be placed on func definitions.
3657static int _console_vfprintf(const HANDLE console, FILE* stream,
3658 const char *format, va_list ap)
3659 __attribute__((__format__(ADB_FORMAT_ARCHETYPE, 3, 0)));
3660
3661// Internal function to format a UTF-8 string and write it to a Win32 console.
3662// Returns -1 on error.
3663static int _console_vfprintf(const HANDLE console, FILE* stream,
3664 const char *format, va_list ap) {
3665 std::string output_utf8;
3666
3667 // Format the string.
3668 // This could throw std::bad_alloc.
3669 android::base::StringAppendV(&output_utf8, format, ap);
3670
3671 return _console_write_utf8(output_utf8.c_str(), output_utf8.length(),
3672 stream, console);
3673}
3674
3675// Version of vfprintf() that takes UTF-8 and can write Unicode to a
3676// Windows console.
3677int adb_vfprintf(FILE *stream, const char *format, va_list ap) {
3678 const HANDLE console = _get_console_handle(stream);
3679
3680 // If there is an associated Win32 console, write to it specially,
3681 // otherwise defer to the regular C Runtime, passing it UTF-8.
3682 if (console != NULL) {
3683 return _console_vfprintf(console, stream, format, ap);
3684 } else {
3685 // If vfprintf is a macro, undefine it, so we can call the real
3686 // C Runtime API.
3687#pragma push_macro("vfprintf")
3688#undef vfprintf
3689 return vfprintf(stream, format, ap);
3690#pragma pop_macro("vfprintf")
3691 }
3692}
3693
3694// Version of fprintf() that takes UTF-8 and can write Unicode to a
3695// Windows console.
3696int adb_fprintf(FILE *stream, const char *format, ...) {
3697 va_list ap;
3698 va_start(ap, format);
3699 const int result = adb_vfprintf(stream, format, ap);
3700 va_end(ap);
3701
3702 return result;
3703}
3704
3705// Version of printf() that takes UTF-8 and can write Unicode to a
3706// Windows console.
3707int adb_printf(const char *format, ...) {
3708 va_list ap;
3709 va_start(ap, format);
3710 const int result = adb_vfprintf(stdout, format, ap);
3711 va_end(ap);
3712
3713 return result;
3714}
3715
3716// Version of fputs() that takes UTF-8 and can write Unicode to a
3717// Windows console.
3718int adb_fputs(const char* buf, FILE* stream) {
3719 // adb_fprintf returns -1 on error, which is conveniently the same as EOF
3720 // which fputs (and hence adb_fputs) should return on error.
3721 return adb_fprintf(stream, "%s", buf);
3722}
3723
3724// Version of fputc() that takes UTF-8 and can write Unicode to a
3725// Windows console.
3726int adb_fputc(int ch, FILE* stream) {
3727 const int result = adb_fprintf(stream, "%c", ch);
3728 if (result <= 0) {
3729 // If there was an error, or if nothing was printed (which should be an
3730 // error), return an error, which fprintf signifies with EOF.
3731 return EOF;
3732 }
3733 // For success, fputc returns the char, cast to unsigned char, then to int.
3734 return static_cast<unsigned char>(ch);
3735}
3736
3737// Internal function to write UTF-8 to a Win32 console. Returns the number of
3738// items (of length size) written. On error, returns a short item count or 0.
3739static size_t _console_fwrite(const void* ptr, size_t size, size_t nmemb,
3740 FILE* stream, HANDLE console) {
3741 // TODO: Note that a Unicode character could be several UTF-8 bytes. But
3742 // if we're passed only some of the bytes of a character (for example, from
3743 // the network socket for adb shell), we won't be able to convert the char
3744 // to a complete UTF-16 char (or surrogate pair), so the output won't look
3745 // right.
3746 //
3747 // To fix this, see libutils/Unicode.cpp for hints on decoding UTF-8.
3748 //
3749 // For now we ignore this problem because the alternative is that we'd have
3750 // to parse UTF-8 and buffer things up (doable). At least this is better
3751 // than what we had before -- always incorrect multi-byte UTF-8 output.
3752 int result = _console_write_utf8(reinterpret_cast<const char*>(ptr),
3753 size * nmemb, stream, console);
3754 if (result == -1) {
3755 return 0;
3756 }
3757 return result / size;
3758}
3759
3760// Version of fwrite() that takes UTF-8 and can write Unicode to a
3761// Windows console.
3762size_t adb_fwrite(const void* ptr, size_t size, size_t nmemb, FILE* stream) {
3763 const HANDLE console = _get_console_handle(stream);
3764
3765 // If there is an associated Win32 console, write to it specially,
3766 // otherwise defer to the regular C Runtime, passing it UTF-8.
3767 if (console != NULL) {
3768 return _console_fwrite(ptr, size, nmemb, stream, console);
3769 } else {
3770 // If fwrite is a macro, undefine it, so we can call the real
3771 // C Runtime API.
3772#pragma push_macro("fwrite")
3773#undef fwrite
3774 return fwrite(ptr, size, nmemb, stream);
3775#pragma pop_macro("fwrite")
3776 }
3777}
3778
3779// Version of fopen() that takes a UTF-8 filename and can access a file with
3780// a Unicode filename.
3781FILE* adb_fopen(const char* f, const char* m) {
3782 return _wfopen(widen(f).c_str(), widen(m).c_str());
3783}
3784
Spencer Lowe6ae5732015-09-08 17:13:04 -07003785// Return a lowercase version of the argument. Uses C Runtime tolower() on
3786// each byte which is not UTF-8 aware, and theoretically uses the current C
3787// Runtime locale (which in practice is not changed, so this becomes a ASCII
3788// conversion).
3789static std::string ToLower(const std::string& anycase) {
3790 // copy string
3791 std::string str(anycase);
3792 // transform the copy
3793 std::transform(str.begin(), str.end(), str.begin(), tolower);
3794 return str;
3795}
3796
3797extern "C" int main(int argc, char** argv);
3798
3799// Link with -municode to cause this wmain() to be used as the program
3800// entrypoint. It will convert the args from UTF-16 to UTF-8 and call the
3801// regular main() with UTF-8 args.
3802extern "C" int wmain(int argc, wchar_t **argv) {
3803 // Convert args from UTF-16 to UTF-8 and pass that to main().
3804 NarrowArgs narrow_args(argc, argv);
3805 return main(argc, narrow_args.data());
3806}
3807
Spencer Lowcf4ff642015-05-11 01:08:48 -07003808// Shadow UTF-8 environment variable name/value pairs that are created from
3809// _wenviron the first time that adb_getenv() is called. Note that this is not
Spencer Lowe347c1d2015-08-02 18:13:54 -07003810// currently updated if putenv, setenv, unsetenv are called. Note that no
3811// thread synchronization is done, but we're called early enough in
3812// single-threaded startup that things work ok.
Spencer Lowcf4ff642015-05-11 01:08:48 -07003813static std::unordered_map<std::string, char*> g_environ_utf8;
3814
3815// Make sure that shadow UTF-8 environment variables are setup.
3816static void _ensure_env_setup() {
3817 // If some name/value pairs exist, then we've already done the setup below.
3818 if (g_environ_utf8.size() != 0) {
3819 return;
3820 }
3821
Spencer Lowe6ae5732015-09-08 17:13:04 -07003822 if (_wenviron == nullptr) {
3823 // If _wenviron is null, then -municode probably wasn't used. That
3824 // linker flag will cause the entry point to setup _wenviron. It will
3825 // also require an implementation of wmain() (which we provide above).
3826 fatal("_wenviron is not set, did you link with -municode?");
3827 }
3828
Spencer Lowcf4ff642015-05-11 01:08:48 -07003829 // Read name/value pairs from UTF-16 _wenviron and write new name/value
3830 // pairs to UTF-8 g_environ_utf8. Note that it probably does not make sense
3831 // to use the D() macro here because that tracing only works if the
3832 // ADB_TRACE environment variable is setup, but that env var can't be read
3833 // until this code completes.
3834 for (wchar_t** env = _wenviron; *env != nullptr; ++env) {
3835 wchar_t* const equal = wcschr(*env, L'=');
3836 if (equal == nullptr) {
3837 // Malformed environment variable with no equal sign. Shouldn't
3838 // really happen, but we should be resilient to this.
3839 continue;
3840 }
3841
Spencer Lowe6ae5732015-09-08 17:13:04 -07003842 // Store lowercase name so that we can do case-insensitive searches.
3843 const std::string name_utf8(ToLower(narrow(
3844 std::wstring(*env, equal - *env))));
Spencer Lowcf4ff642015-05-11 01:08:48 -07003845 char* const value_utf8 = strdup(narrow(equal + 1).c_str());
3846
Spencer Lowe6ae5732015-09-08 17:13:04 -07003847 // Don't overwrite a previus env var with the same name. In reality,
3848 // the system probably won't let two env vars with the same name exist
3849 // in _wenviron.
3850 g_environ_utf8.insert({name_utf8, value_utf8});
Spencer Lowcf4ff642015-05-11 01:08:48 -07003851 }
3852}
3853
3854// Version of getenv() that takes a UTF-8 environment variable name and
Spencer Lowe6ae5732015-09-08 17:13:04 -07003855// retrieves a UTF-8 value. Case-insensitive to match getenv() on Windows.
Spencer Lowcf4ff642015-05-11 01:08:48 -07003856char* adb_getenv(const char* name) {
3857 _ensure_env_setup();
3858
Spencer Lowe6ae5732015-09-08 17:13:04 -07003859 // Case-insensitive search by searching for lowercase name in a map of
3860 // lowercase names.
3861 const auto it = g_environ_utf8.find(ToLower(std::string(name)));
Spencer Lowcf4ff642015-05-11 01:08:48 -07003862 if (it == g_environ_utf8.end()) {
3863 return nullptr;
3864 }
3865
3866 return it->second;
3867}
3868
3869// Version of getcwd() that returns the current working directory in UTF-8.
3870char* adb_getcwd(char* buf, int size) {
3871 wchar_t* wbuf = _wgetcwd(nullptr, 0);
3872 if (wbuf == nullptr) {
3873 return nullptr;
3874 }
3875
3876 const std::string buf_utf8(narrow(wbuf));
3877 free(wbuf);
3878 wbuf = nullptr;
3879
3880 // If size was specified, make sure all the chars will fit.
3881 if (size != 0) {
3882 if (size < static_cast<int>(buf_utf8.length() + 1)) {
3883 errno = ERANGE;
3884 return nullptr;
3885 }
3886 }
3887
3888 // If buf was not specified, allocate storage.
3889 if (buf == nullptr) {
3890 if (size == 0) {
3891 size = buf_utf8.length() + 1;
3892 }
3893 buf = reinterpret_cast<char*>(malloc(size));
3894 if (buf == nullptr) {
3895 return nullptr;
3896 }
3897 }
3898
3899 // Destination buffer was allocated with enough space, or we've already
3900 // checked an existing buffer size for enough space.
3901 strcpy(buf, buf_utf8.c_str());
3902
3903 return buf;
3904}