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