1/* 2 * Copyright (C) 2007 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/* this file contains system-dependent definitions used by ADB 18 * they're related to threads, sockets and file descriptors 19 */ 20#ifndef _ADB_SYSDEPS_H 21#define _ADB_SYSDEPS_H 22 23#ifdef __CYGWIN__ 24# undef _WIN32 25#endif 26 27/* 28 * TEMP_FAILURE_RETRY is defined by some, but not all, versions of 29 * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's 30 * not already defined, then define it here. 31 */ 32#ifndef TEMP_FAILURE_RETRY 33/* Used to retry syscalls that can return EINTR. */ 34#define TEMP_FAILURE_RETRY(exp) ({ \ 35 typeof (exp) _rc; \ 36 do { \ 37 _rc = (exp); \ 38 } while (_rc == -1 && errno == EINTR); \ 39 _rc; }) 40#endif 41 42#ifdef _WIN32 43 44#include <ctype.h> 45#include <direct.h> 46#include <errno.h> 47#include <fcntl.h> 48#include <io.h> 49#include <process.h> 50#include <sys/stat.h> 51#include <winsock2.h> 52#include <windows.h> 53#include <ws2tcpip.h> 54 55#include "fdevent.h" 56 57#define OS_PATH_SEPARATOR '\\' 58#define OS_PATH_SEPARATOR_STR "\\" 59#define ENV_PATH_SEPARATOR_STR ";" 60 61typedef CRITICAL_SECTION adb_mutex_t; 62 63#define ADB_MUTEX_DEFINE(x) adb_mutex_t x 64 65/* declare all mutexes */ 66/* For win32, adb_sysdeps_init() will do the mutex runtime initialization. */ 67#define ADB_MUTEX(x) extern adb_mutex_t x; 68#include "mutex_list.h" 69 70extern void adb_sysdeps_init(void); 71 72static __inline__ void adb_mutex_lock( adb_mutex_t* lock ) 73{ 74 EnterCriticalSection( lock ); 75} 76 77static __inline__ void adb_mutex_unlock( adb_mutex_t* lock ) 78{ 79 LeaveCriticalSection( lock ); 80} 81 82typedef struct { unsigned tid; } adb_thread_t; 83 84typedef void* (*adb_thread_func_t)(void* arg); 85 86typedef void (*win_thread_func_t)(void* arg); 87 88static __inline__ int adb_thread_create( adb_thread_t *thread, adb_thread_func_t func, void* arg) 89{ 90 thread->tid = _beginthread( (win_thread_func_t)func, 0, arg ); 91 if (thread->tid == (unsigned)-1L) { 92 return -1; 93 } 94 return 0; 95} 96 97static __inline__ unsigned long adb_thread_id() 98{ 99 return GetCurrentThreadId(); 100} 101 102static __inline__ void close_on_exec(int fd) 103{ 104 /* nothing really */ 105} 106 107#define lstat stat /* no symlinks on Win32 */ 108 109#define S_ISLNK(m) 0 /* no symlinks on Win32 */ 110 111static __inline__ int adb_unlink(const char* path) 112{ 113 int rc = unlink(path); 114 115 if (rc == -1 && errno == EACCES) { 116 /* unlink returns EACCES when the file is read-only, so we first */ 117 /* try to make it writable, then unlink again... */ 118 rc = chmod(path, _S_IREAD|_S_IWRITE ); 119 if (rc == 0) 120 rc = unlink(path); 121 } 122 return rc; 123} 124#undef unlink 125#define unlink ___xxx_unlink 126 127static __inline__ int adb_mkdir(const char* path, int mode) 128{ 129 return _mkdir(path); 130} 131#undef mkdir 132#define mkdir ___xxx_mkdir 133 134extern int adb_open(const char* path, int options); 135extern int adb_creat(const char* path, int mode); 136extern int adb_read(int fd, void* buf, int len); 137extern int adb_write(int fd, const void* buf, int len); 138extern int adb_lseek(int fd, int pos, int where); 139extern int adb_shutdown(int fd); 140extern int adb_close(int fd); 141 142static __inline__ int unix_close(int fd) 143{ 144 return close(fd); 145} 146#undef close 147#define close ____xxx_close 148 149extern int unix_read(int fd, void* buf, size_t len); 150 151#undef read 152#define read ___xxx_read 153 154static __inline__ int unix_write(int fd, const void* buf, size_t len) 155{ 156 return write(fd, buf, len); 157} 158#undef write 159#define write ___xxx_write 160 161static __inline__ int adb_open_mode(const char* path, int options, int mode) 162{ 163 return adb_open(path, options); 164} 165 166static __inline__ int unix_open(const char* path, int options,...) 167{ 168 if ((options & O_CREAT) == 0) 169 { 170 return open(path, options); 171 } 172 else 173 { 174 int mode; 175 va_list args; 176 va_start( args, options ); 177 mode = va_arg( args, int ); 178 va_end( args ); 179 return open(path, options, mode); 180 } 181} 182#define open ___xxx_unix_open 183 184 185/* normally provided by <cutils/misc.h> */ 186extern void* load_file(const char* pathname, unsigned* psize); 187 188/* normally provided by <cutils/sockets.h> */ 189extern int socket_loopback_client(int port, int type); 190extern int socket_network_client(const char *host, int port, int type); 191extern int socket_network_client_timeout(const char *host, int port, int type, 192 int timeout); 193extern int socket_loopback_server(int port, int type); 194extern int socket_inaddr_any_server(int port, int type); 195 196/* normally provided by "fdevent.h" */ 197 198#define FDE_READ 0x0001 199#define FDE_WRITE 0x0002 200#define FDE_ERROR 0x0004 201#define FDE_DONT_CLOSE 0x0080 202 203typedef void (*fd_func)(int fd, unsigned events, void *userdata); 204 205fdevent *fdevent_create(int fd, fd_func func, void *arg); 206void fdevent_destroy(fdevent *fde); 207void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg); 208void fdevent_remove(fdevent *item); 209void fdevent_set(fdevent *fde, unsigned events); 210void fdevent_add(fdevent *fde, unsigned events); 211void fdevent_del(fdevent *fde, unsigned events); 212void fdevent_loop(); 213 214static __inline__ void adb_sleep_ms( int mseconds ) 215{ 216 Sleep( mseconds ); 217} 218 219extern int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen); 220 221#undef accept 222#define accept ___xxx_accept 223 224extern int adb_setsockopt(int fd, int level, int optname, const void* optval, socklen_t optlen); 225 226#undef setsockopt 227#define setsockopt ___xxx_setsockopt 228 229static __inline__ int adb_socket_setbufsize( int fd, int bufsize ) 230{ 231 int opt = bufsize; 232 return adb_setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void*)&opt, sizeof(opt)); 233} 234 235static __inline__ void disable_tcp_nagle( int fd ) 236{ 237 int on = 1; 238 adb_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (const void*)&on, sizeof(on)); 239} 240 241extern int adb_socketpair( int sv[2] ); 242 243static __inline__ char* adb_dirstart( const char* path ) 244{ 245 char* p = strchr(path, '/'); 246 char* p2 = strchr(path, '\\'); 247 248 if ( !p ) 249 p = p2; 250 else if ( p2 && p2 > p ) 251 p = p2; 252 253 return p; 254} 255 256static __inline__ char* adb_dirstop( const char* path ) 257{ 258 char* p = strrchr(path, '/'); 259 char* p2 = strrchr(path, '\\'); 260 261 if ( !p ) 262 p = p2; 263 else if ( p2 && p2 > p ) 264 p = p2; 265 266 return p; 267} 268 269static __inline__ int adb_is_absolute_host_path( const char* path ) 270{ 271 return isalpha(path[0]) && path[1] == ':' && path[2] == '\\'; 272} 273 274#else /* !_WIN32 a.k.a. Unix */ 275 276#include "fdevent.h" 277#include <cutils/sockets.h> 278#include <cutils/misc.h> 279#include <signal.h> 280#include <sys/wait.h> 281#include <sys/stat.h> 282#include <fcntl.h> 283 284#include <pthread.h> 285#include <unistd.h> 286#include <fcntl.h> 287#include <stdarg.h> 288#include <netinet/in.h> 289#include <netinet/tcp.h> 290#include <string.h> 291#include <unistd.h> 292 293#define OS_PATH_SEPARATOR '/' 294#define OS_PATH_SEPARATOR_STR "/" 295#define ENV_PATH_SEPARATOR_STR ":" 296 297typedef pthread_mutex_t adb_mutex_t; 298 299#define ADB_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER 300#define adb_mutex_init pthread_mutex_init 301#define adb_mutex_lock pthread_mutex_lock 302#define adb_mutex_unlock pthread_mutex_unlock 303#define adb_mutex_destroy pthread_mutex_destroy 304 305#define ADB_MUTEX_DEFINE(m) adb_mutex_t m = PTHREAD_MUTEX_INITIALIZER 306 307#define adb_cond_t pthread_cond_t 308#define adb_cond_init pthread_cond_init 309#define adb_cond_wait pthread_cond_wait 310#define adb_cond_broadcast pthread_cond_broadcast 311#define adb_cond_signal pthread_cond_signal 312#define adb_cond_destroy pthread_cond_destroy 313 314/* declare all mutexes */ 315#define ADB_MUTEX(x) extern adb_mutex_t x; 316#include "mutex_list.h" 317 318static __inline__ void close_on_exec(int fd) 319{ 320 fcntl( fd, F_SETFD, FD_CLOEXEC ); 321} 322 323static __inline__ int unix_open(const char* path, int options,...) 324{ 325 if ((options & O_CREAT) == 0) 326 { 327 return TEMP_FAILURE_RETRY( open(path, options) ); 328 } 329 else 330 { 331 int mode; 332 va_list args; 333 va_start( args, options ); 334 mode = va_arg( args, int ); 335 va_end( args ); 336 return TEMP_FAILURE_RETRY( open( path, options, mode ) ); 337 } 338} 339 340static __inline__ int adb_open_mode( const char* pathname, int options, int mode ) 341{ 342 return TEMP_FAILURE_RETRY( open( pathname, options, mode ) ); 343} 344 345 346static __inline__ int adb_open( const char* pathname, int options ) 347{ 348 int fd = TEMP_FAILURE_RETRY( open( pathname, options ) ); 349 if (fd < 0) 350 return -1; 351 close_on_exec( fd ); 352 return fd; 353} 354#undef open 355#define open ___xxx_open 356 357static __inline__ int adb_shutdown(int fd) 358{ 359 return shutdown(fd, SHUT_RDWR); 360} 361#undef shutdown 362#define shutdown ____xxx_shutdown 363 364static __inline__ int adb_close(int fd) 365{ 366 return close(fd); 367} 368#undef close 369#define close ____xxx_close 370 371 372static __inline__ int adb_read(int fd, void* buf, size_t len) 373{ 374 return TEMP_FAILURE_RETRY( read( fd, buf, len ) ); 375} 376 377#undef read 378#define read ___xxx_read 379 380static __inline__ int adb_write(int fd, const void* buf, size_t len) 381{ 382 return TEMP_FAILURE_RETRY( write( fd, buf, len ) ); 383} 384#undef write 385#define write ___xxx_write 386 387static __inline__ int adb_lseek(int fd, int pos, int where) 388{ 389 return lseek(fd, pos, where); 390} 391#undef lseek 392#define lseek ___xxx_lseek 393 394static __inline__ int adb_unlink(const char* path) 395{ 396 return unlink(path); 397} 398#undef unlink 399#define unlink ___xxx_unlink 400 401static __inline__ int adb_creat(const char* path, int mode) 402{ 403 int fd = TEMP_FAILURE_RETRY( creat( path, mode ) ); 404 405 if ( fd < 0 ) 406 return -1; 407 408 close_on_exec(fd); 409 return fd; 410} 411#undef creat 412#define creat ___xxx_creat 413 414static __inline__ int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen) 415{ 416 int fd; 417 418 fd = TEMP_FAILURE_RETRY( accept( serverfd, addr, addrlen ) ); 419 if (fd >= 0) 420 close_on_exec(fd); 421 422 return fd; 423} 424 425#undef accept 426#define accept ___xxx_accept 427 428#define unix_read adb_read 429#define unix_write adb_write 430#define unix_close adb_close 431 432typedef pthread_t adb_thread_t; 433 434typedef void* (*adb_thread_func_t)( void* arg ); 435 436static __inline__ int adb_thread_create( adb_thread_t *pthread, adb_thread_func_t start, void* arg ) 437{ 438 pthread_attr_t attr; 439 440 pthread_attr_init (&attr); 441 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); 442 443 return pthread_create( pthread, &attr, start, arg ); 444} 445 446static __inline__ int adb_socket_setbufsize( int fd, int bufsize ) 447{ 448 int opt = bufsize; 449 return setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)); 450} 451 452static __inline__ void disable_tcp_nagle(int fd) 453{ 454 int on = 1; 455 setsockopt( fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on) ); 456} 457 458static __inline__ int adb_setsockopt( int fd, int level, int optname, const void* optval, socklen_t optlen ) 459{ 460 return setsockopt( fd, level, optname, optval, optlen ); 461} 462 463#undef setsockopt 464#define setsockopt ___xxx_setsockopt 465 466static __inline__ int unix_socketpair( int d, int type, int protocol, int sv[2] ) 467{ 468 return socketpair( d, type, protocol, sv ); 469} 470 471static __inline__ int adb_socketpair( int sv[2] ) 472{ 473 int rc; 474 475 rc = unix_socketpair( AF_UNIX, SOCK_STREAM, 0, sv ); 476 if (rc < 0) 477 return -1; 478 479 close_on_exec( sv[0] ); 480 close_on_exec( sv[1] ); 481 return 0; 482} 483 484#undef socketpair 485#define socketpair ___xxx_socketpair 486 487static __inline__ void adb_sleep_ms( int mseconds ) 488{ 489 usleep( mseconds*1000 ); 490} 491 492static __inline__ int adb_mkdir(const char* path, int mode) 493{ 494 return mkdir(path, mode); 495} 496#undef mkdir 497#define mkdir ___xxx_mkdir 498 499static __inline__ void adb_sysdeps_init(void) 500{ 501} 502 503static __inline__ char* adb_dirstart(const char* path) 504{ 505 return strchr(path, '/'); 506} 507 508static __inline__ char* adb_dirstop(const char* path) 509{ 510 return strrchr(path, '/'); 511} 512 513static __inline__ int adb_is_absolute_host_path( const char* path ) 514{ 515 return path[0] == '/'; 516} 517 518static __inline__ unsigned long adb_thread_id() 519{ 520 return (unsigned long)pthread_self(); 521} 522 523#endif /* !_WIN32 */ 524 525#endif /* _ADB_SYSDEPS_H */ 526