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
61 typedef 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
70 extern void adb_sysdeps_init(void);
71
adb_mutex_lock(adb_mutex_t * lock)72 static __inline__ void adb_mutex_lock( adb_mutex_t* lock )
73 {
74 EnterCriticalSection( lock );
75 }
76
adb_mutex_unlock(adb_mutex_t * lock)77 static __inline__ void adb_mutex_unlock( adb_mutex_t* lock )
78 {
79 LeaveCriticalSection( lock );
80 }
81
82 typedef struct { unsigned tid; } adb_thread_t;
83
84 typedef void* (*adb_thread_func_t)(void* arg);
85
86 typedef void (*win_thread_func_t)(void* arg);
87
adb_thread_create(adb_thread_t * thread,adb_thread_func_t func,void * arg)88 static __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
adb_thread_id()97 static __inline__ unsigned long adb_thread_id()
98 {
99 return GetCurrentThreadId();
100 }
101
close_on_exec(int fd)102 static __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
adb_unlink(const char * path)111 static __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
adb_mkdir(const char * path,int mode)127 static __inline__ int adb_mkdir(const char* path, int mode)
128 {
129 return _mkdir(path);
130 }
131 #undef mkdir
132 #define mkdir ___xxx_mkdir
133
134 extern int adb_open(const char* path, int options);
135 extern int adb_creat(const char* path, int mode);
136 extern int adb_read(int fd, void* buf, int len);
137 extern int adb_write(int fd, const void* buf, int len);
138 extern int adb_lseek(int fd, int pos, int where);
139 extern int adb_shutdown(int fd);
140 extern int adb_close(int fd);
141
unix_close(int fd)142 static __inline__ int unix_close(int fd)
143 {
144 return close(fd);
145 }
146 #undef close
147 #define close ____xxx_close
148
149 extern int unix_read(int fd, void* buf, size_t len);
150
151 #undef read
152 #define read ___xxx_read
153
unix_write(int fd,const void * buf,size_t len)154 static __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
adb_open_mode(const char * path,int options,int mode)161 static __inline__ int adb_open_mode(const char* path, int options, int mode)
162 {
163 return adb_open(path, options);
164 }
165
unix_open(const char * path,int options,...)166 static __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> */
186 extern void* load_file(const char* pathname, unsigned* psize);
187
188 /* normally provided by <cutils/sockets.h> */
189 extern int socket_loopback_client(int port, int type);
190 extern int socket_network_client(const char *host, int port, int type);
191 extern int socket_network_client_timeout(const char *host, int port, int type,
192 int timeout);
193 extern int socket_loopback_server(int port, int type);
194 extern 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
203 typedef void (*fd_func)(int fd, unsigned events, void *userdata);
204
205 fdevent *fdevent_create(int fd, fd_func func, void *arg);
206 void fdevent_destroy(fdevent *fde);
207 void fdevent_install(fdevent *fde, int fd, fd_func func, void *arg);
208 void fdevent_remove(fdevent *item);
209 void fdevent_set(fdevent *fde, unsigned events);
210 void fdevent_add(fdevent *fde, unsigned events);
211 void fdevent_del(fdevent *fde, unsigned events);
212 void fdevent_loop();
213
adb_sleep_ms(int mseconds)214 static __inline__ void adb_sleep_ms( int mseconds )
215 {
216 Sleep( mseconds );
217 }
218
219 extern int adb_socket_accept(int serverfd, struct sockaddr* addr, socklen_t *addrlen);
220
221 #undef accept
222 #define accept ___xxx_accept
223
224 extern 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
adb_socket_setbufsize(int fd,int bufsize)229 static __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
disable_tcp_nagle(int fd)235 static __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
241 extern int adb_socketpair( int sv[2] );
242
adb_dirstart(const char * path)243 static __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
adb_dirstop(const char * path)256 static __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
adb_is_absolute_host_path(const char * path)269 static __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
297 typedef 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
close_on_exec(int fd)318 static __inline__ void close_on_exec(int fd)
319 {
320 fcntl( fd, F_SETFD, FD_CLOEXEC );
321 }
322
unix_open(const char * path,int options,...)323 static __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
adb_open_mode(const char * pathname,int options,int mode)340 static __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
adb_open(const char * pathname,int options)346 static __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
adb_shutdown(int fd)357 static __inline__ int adb_shutdown(int fd)
358 {
359 return shutdown(fd, SHUT_RDWR);
360 }
361 #undef shutdown
362 #define shutdown ____xxx_shutdown
363
adb_close(int fd)364 static __inline__ int adb_close(int fd)
365 {
366 return close(fd);
367 }
368 #undef close
369 #define close ____xxx_close
370
371
adb_read(int fd,void * buf,size_t len)372 static __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
adb_write(int fd,const void * buf,size_t len)380 static __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
adb_lseek(int fd,int pos,int where)387 static __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
adb_unlink(const char * path)394 static __inline__ int adb_unlink(const char* path)
395 {
396 return unlink(path);
397 }
398 #undef unlink
399 #define unlink ___xxx_unlink
400
adb_creat(const char * path,int mode)401 static __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
adb_socket_accept(int serverfd,struct sockaddr * addr,socklen_t * addrlen)414 static __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
432 typedef pthread_t adb_thread_t;
433
434 typedef void* (*adb_thread_func_t)( void* arg );
435
adb_thread_create(adb_thread_t * pthread,adb_thread_func_t start,void * arg)436 static __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
adb_socket_setbufsize(int fd,int bufsize)446 static __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
disable_tcp_nagle(int fd)452 static __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
adb_setsockopt(int fd,int level,int optname,const void * optval,socklen_t optlen)458 static __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
unix_socketpair(int d,int type,int protocol,int sv[2])466 static __inline__ int unix_socketpair( int d, int type, int protocol, int sv[2] )
467 {
468 return socketpair( d, type, protocol, sv );
469 }
470
adb_socketpair(int sv[2])471 static __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
adb_sleep_ms(int mseconds)487 static __inline__ void adb_sleep_ms( int mseconds )
488 {
489 usleep( mseconds*1000 );
490 }
491
adb_mkdir(const char * path,int mode)492 static __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
adb_sysdeps_init(void)499 static __inline__ void adb_sysdeps_init(void)
500 {
501 }
502
adb_dirstart(const char * path)503 static __inline__ char* adb_dirstart(const char* path)
504 {
505 return strchr(path, '/');
506 }
507
adb_dirstop(const char * path)508 static __inline__ char* adb_dirstop(const char* path)
509 {
510 return strrchr(path, '/');
511 }
512
adb_is_absolute_host_path(const char * path)513 static __inline__ int adb_is_absolute_host_path( const char* path )
514 {
515 return path[0] == '/';
516 }
517
adb_thread_id()518 static __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