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