Changeset 5377:72f1d48ff502 in roaraudio for libroar/vio_stream.c
- Timestamp:
- 12/23/11 22:09:58 (12 years ago)
- Branch:
- default
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
libroar/vio_stream.c
r5289 r5377 157 157 } 158 158 159 static int _roar_simple_new_stream_obj (struct roar_connection * con, struct roar_stream * s, uint32_t rate, uint32_t channels, uint32_t bits, uint32_t codec, int dir, int mixer) { 160 struct roar_libroar_config * config = roar_libroar_get_config(); 161 char file[80] = {0}; 162 int fh = -1, listen = -1; 163 static int count = 0; 164 int type = ROAR_SOCKET_TYPE_UNIX; 165 int port = 0; 166 #if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_LIBDNET) 167 int opt = 1; 168 #endif 169 #ifdef ROAR_HAVE_IPV4 170 struct sockaddr_in socket_addr; 171 socklen_t len = sizeof(struct sockaddr_in); 172 #else 173 struct sockaddr socket_addr; 174 socklen_t len = sizeof(struct sockaddr); 175 #endif 176 #ifdef ROAR_HAVE_SELECT 177 int confh; 178 fd_set fds; 179 struct timeval timeout = {10, 0}; 180 struct roar_message mes; 181 #endif 182 #ifdef ROAR_HAVE_UNIX 183 int socks[2]; // for socketpair() 184 #endif 185 186 // make valgrind happy 187 memset(&socket_addr, 0, sizeof(socket_addr)); 188 #ifdef ROAR_HAVE_SELECT 189 memset(&mes, 0, sizeof(mes)); 190 #endif 191 192 if ( config != NULL ) { 193 if ( config->workaround.workarounds & ROAR_LIBROAR_CONFIG_WAS_USE_EXECED ) { 194 return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); 195 } 196 } 197 198 #ifdef ROAR_HAVE_BSDSOCKETS 199 roar_libroar_nowarn(); 200 if ( getsockname(roar_get_connection_fh(con), (struct sockaddr *)&socket_addr, &len) == -1 ) { 201 roar_libroar_warn(); 202 return -1; 203 } 204 roar_libroar_warn(); 205 #else 206 return -1; 207 #endif 208 209 if ( len == 0 ) { 210 #ifdef ROAR_OS_OPENBSD 211 ROAR_WARN("roar_simple_new_stream_obj(*): Unknown address family: guess AF_UNIX because OS is OpenBSD"); 212 ((struct sockaddr*)&socket_addr)->sa_family = AF_UNIX; 213 #else 214 return -1; 215 #endif 216 } 217 218 switch (((struct sockaddr*)&socket_addr)->sa_family) { 219 #ifdef ROAR_HAVE_UNIX 220 case AF_UNIX: type = ROAR_SOCKET_TYPE_UNIX; break; 221 #endif 222 #ifdef ROAR_HAVE_IPV4 223 case AF_INET: type = ROAR_SOCKET_TYPE_INET; break; 224 #endif 225 #ifdef ROAR_HAVE_LIBDNET 226 case AF_DECnet: type = ROAR_SOCKET_TYPE_DECNET; break; 227 #endif 228 default: 229 return -1; 230 break; 231 } 232 233 if ( type == ROAR_SOCKET_TYPE_DECNET ) { 234 if ( roar_socket_get_local_nodename() ) { 235 snprintf(file, 24, "%s::roar$TMP%04x%02x", roar_socket_get_local_nodename(), getpid(), count++); 236 } else { 237 return -1; 238 } 239 #ifdef ROAR_HAVE_IPV4 240 } else { 241 strncpy(file, inet_ntoa(socket_addr.sin_addr), sizeof(file) - 1); 242 #endif 243 } 244 245 if ( type != ROAR_SOCKET_TYPE_UNIX ) { 246 if ( (listen = roar_socket_listen(type, file, port)) == -1 ) { 247 return -1; 248 } 249 } 250 251 if ( type == ROAR_SOCKET_TYPE_INET ) { 252 #ifdef ROAR_HAVE_IPV4 253 setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, (void*)&opt, sizeof(int)); 254 255 len = sizeof(struct sockaddr_in); 256 if ( getsockname(listen, (struct sockaddr *)&socket_addr, &len) == -1 ) { 257 return -1; 258 } 259 port = ROAR_NET2HOST16(socket_addr.sin_port); 260 ROAR_DBG("roar_simple_new_stream_obj(*): port=%i", port); 261 #else 262 return -1; 263 #endif 264 } else if ( type == ROAR_SOCKET_TYPE_DECNET ) { 265 #ifdef ROAR_HAVE_LIBDNET 266 setsockopt(listen, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)); 267 #else 268 return -1; 269 #endif 270 } 271 272 if ( roar_stream_new(s, rate, channels, bits, codec) == -1 ) { 273 return -1; 274 } 275 276 if ( roar_stream_connect(con, s, dir, mixer) == -1 ) { 277 return -1; 278 } 279 280 if ( type != ROAR_SOCKET_TYPE_UNIX ) { 281 #ifdef ROAR_HAVE_SELECT 282 if ( roar_stream_connect_to_ask(con, s, type, file, port) != -1 ) { 283 284 FD_ZERO(&fds); 285 FD_SET(listen, &fds); 286 287 confh = roar_get_connection_fh(con); 288 289 if ( confh != -1 ) { 290 FD_SET(confh, &fds); 291 } 292 293 if ( select((confh > listen ? confh : listen) + 1, &fds, NULL, NULL, &timeout) < 1 ) { 294 close(listen); 295 296 // we don't need to check the content as we know it failed... 297 if ( roar_recv_message(con, &mes, NULL) == -1 ) 298 return -1; 299 300 if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 ) 301 return -1; 302 303 return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); 304 } 305 306 if ( FD_ISSET(listen, &fds) ) { 307 if ( (fh = accept(listen, NULL, NULL)) != -1 ) { 308 /* errr, do we need we any error handling here? */ 309 } 310 311 if ( roar_recv_message(con, &mes, NULL) == -1 ) { 312 if ( fh != -1 ) 313 close(fh); 314 fh = -1; 315 } else if ( mes.cmd != ROAR_CMD_OK ) { 316 if ( fh != -1 ) 317 close(fh); 318 fh = -1; 319 } 320 } else { 321 // we don't need to check the content as we know it failed... 322 if ( roar_recv_message(con, &mes, NULL) == -1 ) { 323 close(listen); 324 return -1; 325 } 326 327 if ( mes.cmd != ROAR_CMD_OK ) { 328 close(listen); 329 if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 ) 330 return -1; 331 332 return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); 333 } else { // seems like we have a positive reply. So we retry the listen socket: 334 FD_ZERO(&fds); 335 FD_SET(listen, &fds); 336 timeout.tv_sec = 0; 337 timeout.tv_usec = 128000L; 338 fh = -1; 339 if ( select(listen + 1, &fds, NULL, NULL, &timeout) > 0 ) { 340 if ( (fh = accept(listen, NULL, NULL)) == -1 ) { 341 close(listen); 342 if ( roar_kick(con, ROAR_OT_STREAM, s->id) == -1 ) 343 return -1; 344 345 return roar_simple_new_stream_attachexeced_obj(con, s, rate, channels, bits, codec, dir, mixer); 346 } 347 } 348 } 349 } 350 } 351 352 close(listen); 353 #else 354 return -1; 355 #endif 356 } else { // this is type == ROAR_SOCKET_TYPE_UNIX 357 #ifdef ROAR_HAVE_UNIX 358 if ( socketpair(AF_UNIX, SOCK_STREAM, 0, socks) == -1 ) { 359 roar_kick(con, ROAR_OT_STREAM, s->id); // we do not need to check for errors 360 // as we return -1 in both whys 361 return -1; 362 } 363 364 if ( roar_stream_passfh(con, s, socks[0]) == -1 ) { 365 roar_kick(con, ROAR_OT_STREAM, s->id); // we do not need to check for errors 366 // as we return -1 anyway. 367 close(socks[0]); 368 close(socks[1]); 369 return -1; 370 } 371 372 close(socks[0]); 373 fh = socks[1]; 374 #else 375 roar_kick(con, ROAR_OT_STREAM, s->id); 376 return -1; 377 #endif 378 } 379 380 if ( fh != -1 ) { 381 if ( dir == ROAR_DIR_PLAY ) { 382 (void)ROAR_SHUTDOWN(fh, SHUT_RD); 383 } else if ( dir == ROAR_DIR_MONITOR || dir == ROAR_DIR_RECORD ) { 384 (void)ROAR_SHUTDOWN(fh, SHUT_WR); 385 } 386 } 387 388 s->fh = fh; 389 390 return fh; 391 } 392 159 393 int roar_vio_simple_new_stream_obj (struct roar_vio_calls * calls, 160 394 struct roar_connection * con, … … 175 409 s = &stream; 176 410 177 roar_libroar_nowarn(); 178 if ( (fh = roar_simple_new_stream_obj(con, s, rate, channels, bits, codec, dir, mixer)) == -1 ) { 179 roar_libroar_warn(); 411 if ( (fh = _roar_simple_new_stream_obj(con, s, rate, channels, bits, codec, dir, mixer)) == -1 ) { 180 412 ROAR_DBG("roar_vio_simple_new_stream_obj(*) = -1"); 181 413 return -1; 182 414 } 183 roar_libroar_warn();184 415 185 416 ROAR_DBG("roar_vio_simple_new_stream_obj(*): fh=%i", fh);
Note: See TracChangeset
for help on using the changeset viewer.