Changeset 5843:62465e3791bc in roaraudio


Ignore:
Timestamp:
01/07/13 05:43:06 (11 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

Added support for +fork on win32 (Closes: #337)

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • ChangeLog

    r5837 r5843  
    1010          ABOUT, HELP and PREFERENCES. 
    1111        * Avoid %llX on win32 (Closes: #271) 
     12        * Added support for +fork on win32 (Closes: #337) 
    1213 
    1314v. 1.0beta8 - Mon Dec 10 2012 12:42 CET 
  • libroar/basic.c

    r5841 r5843  
    3636#include "libroar.h" 
    3737 
    38 static int _start_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { 
    39 #if !defined(ROAR_TARGET_WIN32) && !defined(ROAR_TARGET_MICROCONTROLLER) 
    40  enum { 
    41   NORMAL = 0, 
    42   SYSTEM = 1 
    43  } mode = NORMAL; 
     38enum mode { 
     39 NORMAL = 0, 
     40 SYSTEM = 1 
     41}; 
     42 
     43static int _connect_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout); 
     44 
     45int __get_daemonimage(const char ** daemonimage, enum mode * mode, const char * server) { 
     46 *daemonimage = NULL; 
     47 *mode = NORMAL; 
     48 
     49 if ( !!strncmp(server, "+fork", 5) ) { 
     50  roar_err_set(ROAR_ERROR_INVAL); 
     51  return -1; 
     52 } 
     53 
     54 server += 5; 
     55 
     56 if ( server[0] == '=' ) { 
     57  server++; 
     58 
     59  if ( server[0] == 0 ) { 
     60   // no special case, we just ignore it. 
     61  } else if ( server[0] == 'd' && server[1] == ':' ) { 
     62   server += 2; 
     63   *daemonimage = server; 
     64   *mode = NORMAL; 
     65  } else if ( server[0] == '!' ) { 
     66   server += 1; 
     67   *daemonimage = server; 
     68   *mode = SYSTEM; 
     69  } else { 
     70   roar_err_set(ROAR_ERROR_ILLSEQ); 
     71   return -1; 
     72  } 
     73 } 
     74 
     75 if ( *daemonimage == NULL ) 
     76  *daemonimage = roar_libroar_get_config()->daemonimage; 
     77 
     78 // we keep this step to be compatible with older versions. 
     79 if ( *daemonimage == NULL || **daemonimage == 0 ) { 
     80  *daemonimage = roar_env_get("ROAR_DAEMONIMAGE"); 
     81  if ( *daemonimage != NULL ) { 
     82   ROAR_WARN("__get_daemonimage(*): Usage of $ROAR_DAEMONIMAGE is obsolete. Use ROAR_OPTIONS=daemonimage:..."); 
     83  } 
     84 } 
     85 
     86 if ( *daemonimage == NULL || **daemonimage == 0 ) 
     87  *daemonimage = roar_libroar_get_path_static("bin-default-daemonimage"); 
     88 
     89 return 0; 
     90} 
     91 
     92#if defined(ROAR_TARGET_WIN32) 
     93#define NUM_TRIES 16 
     94static int _start_server_win32(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { 
     95 enum mode mode = NORMAL; 
     96 const char * daemonimage = NULL; 
     97 char buf[64]; 
     98 int port; 
     99 size_t i; 
     100 int fh; 
     101 int ret; 
     102 
     103 if ( __get_daemonimage(&daemonimage, &mode, server) == -1 ) 
     104  return -1; 
     105 
     106 if ( mode != NORMAL ) { 
     107  roar_err_set(ROAR_ERROR_NOSYS); 
     108  return -1; 
     109 } 
     110 
     111 for (i = 0; i < NUM_TRIES; i++) { 
     112  port = roar_random_uint16(); 
     113  if ( port < 1 ) 
     114   continue; 
     115 
     116  fh = roar_socket_connect(ROAR_SOCKET_TYPE_TCP, "localhost", port); 
     117  if ( fh == -1 ) 
     118   break; 
     119 
     120  closesocket(fh); 
     121 } 
     122 
     123 if ( i == NUM_TRIES ) { 
     124  roar_err_set(ROAR_ERROR_LOOP); 
     125  return -1; 
     126 } 
     127 
     128 // port is the port to use. It seems to be 'free'. 
     129 
     130#if defined(_P_DETACH) 
     131#define MODE _P_DETACH 
     132#elif defined(_P_NOWAIT) 
     133#define MODE _P_NOWAIT 
     134#else 
     135#define MODE _P_NOWAITO 
     136#endif 
     137 
     138 snprintf(buf, sizeof(buf), "%i", port); 
     139 // TODO: FIXME: check for error here: 
     140 _spawnlp(MODE, daemonimage, daemonimage, "--tcp", "--bind", "localhost", "--port", buf, (const char*)NULL); 
     141 
     142 snprintf(buf, sizeof(buf), "localhost:%i", port); 
     143 
     144 // give the daemon some time to come up: 
     145 roar_usleep(25000); 
     146 
     147 ret = -1; 
     148 for (i = 0; ret == -1 && i < NUM_TRIES; i++) { 
     149  ret = _connect_server(con, buf, type, flags, timeout); 
     150  if ( ret == -1 && i < NUM_TRIES ) 
     151   roar_sleep(1); 
     152 } 
     153 
     154 if ( ret == -1 ) 
     155  return -1; 
     156 
     157 con->flags |= ROAR_CON_FLAGS_TERMINATE; 
     158 
     159 return 0; 
     160} 
     161#elif !defined(ROAR_TARGET_MICROCONTROLLER) 
     162static int _start_server_posix(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { 
     163 enum mode mode = NORMAL; 
    44164 const char * daemonimage = NULL; 
    45165 int socks[2]; 
     
    48168 size_t len; 
    49169 
    50  if ( !strncmp(server, "+fork=", 6) ) { 
    51   server += 6; 
    52   if ( server[0] == 0 ) { 
    53    // no special case, we just ignore it. 
    54   } else if ( server[0] == 'd' && server[1] == ':' ) { 
    55    server += 2; 
    56    daemonimage = server; 
    57   } else if ( server[0] == '!' ) { 
    58    server += 1; 
    59    daemonimage = server; 
    60    mode = SYSTEM; 
    61   } else { 
    62    roar_err_set(ROAR_ERROR_ILLSEQ); 
    63    return -1; 
    64   } 
    65  } 
    66  
    67  if ( daemonimage == NULL ) 
    68   daemonimage = roar_libroar_get_config()->daemonimage; 
    69  
    70  // we keep this step to be compatible with older versions. 
    71  if ( daemonimage == NULL || *daemonimage == 0 ) { 
    72   daemonimage = roar_env_get("ROAR_DAEMONIMAGE"); 
    73   if ( daemonimage != NULL ) { 
    74    ROAR_WARN("_start_server(*): Usage of $ROAR_DAEMONIMAGE is obsolete. Use ROAR_OPTIONS=daemonimage:..."); 
    75   } 
    76  } 
    77  
    78  if ( daemonimage == NULL || *daemonimage == 0 ) 
    79   daemonimage = roar_libroar_get_path_static("bin-default-daemonimage"); 
     170 if ( __get_daemonimage(&daemonimage, &mode, server) == -1 ) 
     171  return -1; 
    80172 
    81173 len = roar_mm_strlen(daemonimage) + 9; // 9 = '+fork=' + 'X:' + '\0' 
     
    135227 
    136228 return -1; 
     229} 
     230#endif 
     231 
     232static int _start_server(struct roar_connection * con, const char * server, int type, int flags, uint_least32_t timeout) { 
     233#if defined(ROAR_TARGET_WIN32) 
     234 return _start_server_win32(con, server, type, flags, timeout); 
     235#elif !defined(ROAR_TARGET_MICROCONTROLLER) 
     236 return _start_server_posix(con, server, type, flags, timeout); 
    137237#else 
    138  ROAR_ERR("_start_server(*): There is no UNIX Domain Socket support in win32, download a real OS."); 
     238 ROAR_ERR("_start_server(*): There is no UNIX Domain Socket, download a real OS."); 
     239 roar_err_set(ROAR_ERROR_NOSYS); 
    139240 return -1; 
    140241#endif 
     
    610711  if ( roar_terminate(con, 1) == -1 ) { 
    611712   ROAR_WARN("roar_connectionunref(con=%p{.server_name='%s'}): Can not terminate server as requested.", con, con->server_name); 
     713   if ( roar_terminate(con, 0) == -1 ) { 
     714    ROAR_ERR("roar_connectionunref(con=%p{.server_name='%s'}): Can not exit server. BAD.", con, con->server_name); 
     715   } 
    612716  } 
    613717 } 
Note: See TracChangeset for help on using the changeset viewer.