source: roaraudio/libroar/vio.c @ 4962:925a3582a0b7

Last change on this file since 4962:925a3582a0b7 was 4876:06a2f29d0450, checked in by phi, 13 years ago

some updates to handle error values better with DSTR

File size: 20.2 KB
RevLine 
[590]1//vio.c:
2
[690]3/*
[4708]4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-2011
[690]5 *
6 *  This file is part of libroar a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroar is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
[3517]21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
[690]23 *
24 *  NOTE for everyone want's to change something and send patches:
25 *  read README and HACKING! There a addition information on
26 *  the license of this document you need to read before you send
27 *  any patches.
28 *
29 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
30 *  or libpulse*:
31 *  The libs libroaresd, libroararts and libroarpulse link this lib
32 *  and are therefore GPL. Because of this it may be illigal to use
33 *  them with any software that uses libesd, libartsc or libpulse*.
34 */
35
[590]36#include "libroar.h"
[3895]37
38#ifdef ROAR_HAVE_H_SYS_IOCTL
[3852]39#include <sys/ioctl.h>
[3895]40#endif
[590]41
[1474]42#ifdef ROAR_HAVE_IO_POSIX
43#define _CAN_OPERATE
44#endif
45
[591]46int roar_vio_init_calls (struct roar_vio_calls * calls) {
[1474]47#ifdef _CAN_OPERATE
[4873]48 if ( calls == NULL ) {
49  roar_err_set(ROAR_ERROR_FAULT);
[591]50  return -1;
[4873]51 }
[591]52
53 memset((void*)calls, 0, sizeof(struct roar_vio_calls));
54
[881]55/*
[597]56 calls->read  = (ssize_t (*)(int fd, void *buf, size_t count,      void * inst))read;
57 calls->write = (ssize_t (*)(int fd, void *buf, size_t count,      void * inst))write;
58 calls->lseek = (off_t   (*)(int fildes, off_t offset, int whence, void * inst))lseek;
[881]59*/
60
[1118]61 calls->read     = roar_vio_basic_read;
62 calls->write    = roar_vio_basic_write;
63 calls->lseek    = roar_vio_basic_lseek;
64 calls->nonblock = roar_vio_basic_nonblock;
65 calls->sync     = roar_vio_basic_sync;
[1505]66 calls->ctl      = roar_vio_basic_ctl;
[1241]67 calls->close    = roar_vio_basic_close;
[881]68
69 return 0;
[1474]70#else
71 return -1;
72#endif
[881]73}
74
75int roar_vio_set_inst (struct roar_vio_calls * vio, void * inst) {
[4873]76 if ( vio == NULL ) {
77  roar_err_set(ROAR_ERROR_FAULT);
[881]78  return -1;
[4873]79 }
[881]80
81 vio->inst = inst;
[591]82
83 return 0;
84}
85
[881]86int roar_vio_set_fh   (struct roar_vio_calls * vio, int fh) {
[989]87 return roar_vio_set_inst(vio, (void*)(ROAR_INSTINT)(fh + 1));
[881]88}
89
90int roar_vio_get_fh   (struct roar_vio_calls * vio) {
[4873]91 if ( vio == NULL ) {
92  roar_err_set(ROAR_ERROR_FAULT);
[881]93  return -1;
[4873]94 }
[881]95
[989]96 return ((int)(ROAR_INSTINT)vio->inst) - 1;
[881]97}
98
99
100ssize_t roar_vio_read (struct roar_vio_calls * vio, void *buf, size_t count) {
[4873]101 ssize_t ret;
102
[1319]103 ROAR_DBG("roar_vio_read(vio=%p, buf=%p, count=%u) = ?", vio, buf, (unsigned int)count);
104
[4873]105 if ( vio == NULL ) {
106  roar_err_set(ROAR_ERROR_FAULT);
[881]107  return -1;
[4873]108 }
[881]109
[4873]110 if ( vio->read == NULL ) {
111  roar_err_set(ROAR_ERROR_NOSYS);
[881]112  return -1;
[4873]113 }
[881]114
[4873]115 roar_err_clear_all();
116 ret = vio->read(vio, buf, count);
117 roar_err_update();
118
119 return ret;
[881]120}
121
122ssize_t roar_vio_write(struct roar_vio_calls * vio, void *buf, size_t count) {
[4873]123 ssize_t ret;
124
[3276]125 ROAR_DBG("roar_vio_write(vio=%p, buf=%p, count=%u) = ?", vio, buf, (unsigned int)count);
126
[4873]127 if ( vio == NULL ) {
128  roar_err_set(ROAR_ERROR_FAULT);
[881]129  return -1;
[4873]130 }
[881]131
[4873]132 if ( vio->write == NULL ) {
133  roar_err_set(ROAR_ERROR_NOSYS);
[881]134  return -1;
[4873]135 }
[881]136
[4873]137 roar_err_clear_all();
138 ret = vio->write(vio, buf, count);
139 roar_err_update();
140
141 return ret;
[881]142}
143
144off_t   roar_vio_lseek(struct roar_vio_calls * vio, off_t offset, int whence) {
[4873]145 off_t ret;
146
[3276]147 ROAR_DBG("roar_vio_lseek(vio=%p, offset=%u, whence=%i) = ?", vio, (unsigned int)offset, whence);
148
[4873]149 if ( vio == NULL ) {
150  roar_err_set(ROAR_ERROR_FAULT);
[881]151  return -1;
[4873]152 }
[881]153
[4873]154 if ( vio->lseek == NULL ) {
155  roar_err_set(ROAR_ERROR_NOSYS);
[881]156  return -1;
[4873]157 }
[881]158
[4873]159 roar_err_clear_all();
160 ret = vio->lseek(vio, offset, whence);
161 roar_err_update();
162
163 return ret;
[881]164}
165
[1118]166int     roar_vio_nonblock(struct roar_vio_calls * vio, int state) {
[4873]167 int ret;
168
[3276]169 ROAR_DBG("roar_vio_nonblock(vio=%p, state=%i) = ?", vio, state);
170
[4873]171 if ( vio == NULL ) {
172  roar_err_set(ROAR_ERROR_FAULT);
[1118]173  return -1;
[4873]174 }
[1118]175
[4873]176 if ( vio->nonblock == NULL ) {
177  roar_err_set(ROAR_ERROR_NOSYS);
[1118]178  return -1;
[4873]179 }
[1118]180
[4873]181 roar_err_clear_all();
182 ret = vio->nonblock(vio, state);
183 roar_err_update();
184
185 return ret;
[1118]186}
187
188int     roar_vio_sync    (struct roar_vio_calls * vio) {
[4873]189 int ret;
190
[3276]191 ROAR_DBG("roar_vio_sync(vio=%p) = ?", vio);
192
[4873]193 if ( vio == NULL ) {
194  roar_err_set(ROAR_ERROR_FAULT);
[1118]195  return -1;
[4873]196 }
[1118]197
[4873]198 if ( vio->sync == NULL ) {
199  roar_err_set(ROAR_ERROR_NOSYS);
[1118]200  return -1;
[4873]201 }
[1118]202
[4873]203 roar_err_clear_all();
204 ret = vio->sync(vio);
205 roar_err_update();
206
207 return ret;
[1118]208}
209
[1140]210int     roar_vio_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
[4873]211 int ret;
212
[3276]213 ROAR_DBG("roar_vio_ctl(vio=%p, cmd=%i, data=%p) = ?", vio, cmd, data);
214
[4873]215 if ( vio == NULL ) {
216  roar_err_set(ROAR_ERROR_FAULT);
[1140]217  return -1;
[4873]218 }
[1140]219
[1615]220 ROAR_DBG("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p): vio->ctl=%p", vio, cmd, data, vio->ctl);
221
[4831]222 switch (cmd) {
223  case ROAR_VIO_CTL_CONFLICTING_ID_0:
224  case ROAR_VIO_CTL_CONFLICTING_ID_1:
225    ROAR_ERR("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p): Your progam uses a VIO ctl call with a conflicting ID.", vio, cmd, data);
226    ROAR_ERR("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p): Please recompile your program to fix this. (No additional steps are required beside that.)", vio, cmd, data);
227    ROAR_DBG("roar_vio_ctl(vio=%p, cmd=0x%.8x, data=%p) = -1", vio, cmd, data);
[4873]228    roar_err_set(ROAR_ERROR_BADRQC);
[4831]229    return -1;
230   break;
231 }
232
[4873]233 if ( vio->ctl == NULL ) {
234  roar_err_set(ROAR_ERROR_NOSYS);
[1140]235  return -1;
[4873]236 }
[1140]237
[4873]238 roar_err_clear_all();
239 ret = vio->ctl(vio, cmd, data);
240 roar_err_update();
241
242 return ret;
[1140]243}
244
[1241]245int     roar_vio_close    (struct roar_vio_calls * vio) {
[4873]246 int ret;
247
[3276]248 ROAR_DBG("roar_vio_close(vio=%p) = ?", vio);
249
[4873]250 if ( vio == NULL ) {
251  roar_err_set(ROAR_ERROR_FAULT);
[1241]252  return -1;
[4873]253 }
[1241]254
[4873]255 if ( vio->close == NULL ) {
256  roar_err_set(ROAR_ERROR_NOSYS);
[1241]257  return -1;
[4873]258 }
[1241]259
[4873]260 roar_err_clear_all();
261 ret = vio->close(vio);
262 roar_err_update();
263
264 return ret;
[1241]265}
266
[3769]267// specal commands:
268int     roar_vio_accept  (struct roar_vio_calls * calls, struct roar_vio_calls * dst) {
[4873]269 if (dst == NULL || calls == NULL) {
270  roar_err_set(ROAR_ERROR_FAULT);
[3769]271  return -1;
[4873]272 }
[3769]273
274 return roar_vio_ctl(dst, ROAR_VIO_CTL_ACCEPT, calls);
275}
276
[3796]277int     roar_vio_shutdown(struct roar_vio_calls * vio,   int how) {
278 return roar_vio_ctl(vio, ROAR_VIO_CTL_SHUTDOWN, &how);
279}
280
[1252]281// converters:
282int     roar_vio_open_file     (struct roar_vio_calls * calls, char * filename, int flags, mode_t mode) {
[1474]283#ifdef _CAN_OPERATE
[1252]284 int fh;
285
[4873]286 roar_debug_warn_obsolete("roar_vio_open_file", "roar_vio_open_dstr", NULL);
287
288 if ( calls == NULL || filename == NULL ) {
289  roar_err_set(ROAR_ERROR_FAULT);
[1252]290  return -1;
[4873]291 }
[1252]292
[1762]293#ifdef ROAR_TARGET_WIN32
294 flags |= O_BINARY;
295#endif
296
[4873]297 roar_err_clear_all();
298 if ( (fh = open(filename, flags, mode)) == -1 ) {
[4876]299  ROAR_DBG("roar_vio_open_file(*): errno=%s", strerror(errno));
[4873]300  roar_err_update();
[4876]301  ROAR_DBG("roar_vio_open_file(*): errno=%s", strerror(errno));
[1252]302  return -1;
[4873]303 }
[1252]304
305 if ( roar_vio_open_fh(calls, fh) == -1 ) {
306  close(fh);
[4873]307  roar_err_update();
[1252]308  return -1;
309 }
310
[4873]311 roar_err_update();
[1252]312 return 0;
[1474]313#else
314 return -1;
315#endif
[1252]316}
317
318int     roar_vio_open_fh       (struct roar_vio_calls * calls, int fh) {
319 if ( calls == NULL )
320  return -1;
321
322 if ( roar_vio_init_calls(calls) == -1 )
323  return -1;
324
325 return roar_vio_set_fh(calls, fh);
326}
327
[1290]328int     roar_vio_open_fh_socket(struct roar_vio_calls * calls, int fh) {
329 if ( calls == NULL )
330  return -1;
331
[1666]332 if ( roar_vio_open_fh(calls, fh) == -1 )
333  return -1;
334
[1760]335#ifdef ROAR_TARGET_WIN32
336 calls->read     = roar_vio_winsock_read;
337 calls->write    = roar_vio_winsock_write;
338 calls->nonblock = roar_vio_winsock_nonblock;
339 calls->sync     = roar_vio_winsock_sync;
340 calls->ctl      = roar_vio_winsock_ctl;
341 calls->close    = roar_vio_winsock_close;
342#else
343 calls->sync     = roar_vio_null_sync;
344#endif
[1666]345
346 return 0;
[1290]347}
348
[1291]349int     roar_vio_open_socket   (struct roar_vio_calls * calls, char * host, int port) {
350 int fh;
351
352 if ( calls == NULL )
353  return -1;
354
355 if ( (fh = roar_socket_connect(host, port)) == -1 )
356  return -1;
357
358 return roar_vio_open_fh_socket(calls, fh);
359}
360
361int     roar_vio_open_socket_listen(struct roar_vio_calls * calls, int type, char * host, int port) {
362 int fh;
363
364 if ( calls == NULL )
365  return -1;
366
367 if ( (fh = roar_socket_listen(type, host, port)) == -1 )
368  return -1;
369
370 return roar_vio_open_fh_socket(calls, fh);
371}
372
[1275]373int     roar_vio_simple_stream (struct roar_vio_calls * calls, int rate, int channels, int bits, int codec,
374                                                               char * server, int dir, char * name) {
375 int fh;
376
377 if ( calls == NULL )
378  return -1;
379
[3860]380 roar_libroar_nowarn();
381 if ( (fh = roar_simple_stream(rate, channels, bits, codec, server, dir, name)) == -1 ) {
382  roar_libroar_warn();
[1275]383  return -1;
[3860]384 }
385 roar_libroar_warn();
[1275]386
[1290]387 return roar_vio_open_fh_socket(calls, fh);
[1275]388}
389
[2841]390int     roar_vio_simple_new_stream_obj (struct roar_vio_calls * calls,
391                                        struct roar_connection * con,
392                                        struct roar_stream * s,
393                                        int rate, int channels, int bits, int codec, int dir) {
[3859]394 struct roar_stream stream;
[2841]395 int fh;
396
[4692]397 ROAR_DBG("roar_vio_simple_new_stream_obj(*) = ?");
398
[2841]399 if ( calls == NULL )
400  return -1;
401
[3859]402 if ( s == NULL )
403  s = &stream;
404
[3860]405 roar_libroar_nowarn();
406 if ( (fh = roar_simple_new_stream_obj(con, s, rate, channels, bits, codec, dir)) == -1 ) {
407  roar_libroar_warn();
[4692]408  ROAR_DBG("roar_vio_simple_new_stream_obj(*) = -1");
[2841]409  return -1;
[3860]410 }
411 roar_libroar_warn();
[2841]412
[4692]413 ROAR_DBG("roar_vio_simple_new_stream_obj(*): fh=%i", fh);
414
[2841]415 return roar_vio_open_fh_socket(calls, fh);
416}
417
[886]418// VIOs:
[881]419
[886]420// basic
[881]421ssize_t roar_vio_basic_read (struct roar_vio_calls * vio, void *buf, size_t count) {
[1474]422#ifdef _CAN_OPERATE
[881]423 return read(roar_vio_get_fh(vio), buf, count);
[1474]424#else
425 return -1;
426#endif
[881]427}
428
429ssize_t roar_vio_basic_write(struct roar_vio_calls * vio, void *buf, size_t count) {
[1474]430#ifdef _CAN_OPERATE
[881]431 return write(roar_vio_get_fh(vio), buf, count);
[1474]432#else
433 return -1;
434#endif
[881]435}
436
437off_t   roar_vio_basic_lseek(struct roar_vio_calls * vio, off_t offset, int whence) {
[1474]438#ifdef _CAN_OPERATE
[881]439 return lseek(roar_vio_get_fh(vio), offset, whence);
[1474]440#else
441 return -1;
442#endif
[881]443}
444
[1118]445int     roar_vio_basic_nonblock(struct roar_vio_calls * vio, int state) {
446 if ( roar_socket_nonblock(roar_vio_get_fh(vio), state) == -1 )
447  return -1;
448
449 if ( state == ROAR_SOCKET_NONBLOCK )
450  return 0;
451
[1125]452 roar_vio_sync(vio);
453
454 return 0;
[1118]455}
456
457int     roar_vio_basic_sync    (struct roar_vio_calls * vio) {
[1397]458#ifdef ROAR_FDATASYNC
[1171]459 return ROAR_FDATASYNC(roar_vio_get_fh(vio));
[1397]460#else
461 return 0;
462#endif
[1118]463}
464
[1505]465int     roar_vio_basic_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
[3895]466#ifdef ROAR_HAVE_H_SYS_IOCTL
[3852]467 struct roar_vio_sysio_ioctl * sysioctl;
[3895]468#endif
[4718]469#if defined(ROAR_HAVE_GETSOCKOPT) || defined(ROAR_HAVE_SETSOCKOPT)
470 struct roar_vio_sysio_sockopt  * syssockopt;
471#endif
[3796]472 int tmp;
473 int s_r = 0, s_w = 0;
[4705]474#if defined(ROAR_HAVE_GETSOCKNAME) || defined(ROAR_HAVE_GETPEERNAME)
475 union {
476  struct sockaddr     sa;
477#if defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6)
478  struct sockaddr_in  in;
479#endif
480#ifdef ROAR_HAVE_UNIX
481  struct sockaddr_un  un;
482#endif
483#ifdef ROAR_HAVE_LIBDNET
484  struct sockaddr_dn  dn;
485#endif
486#ifdef ROAR_HAVE_IPV6
487  struct sockaddr_in6 in6;
488#endif
489#ifdef ROAR_HAVE_IPX
490  struct sockaddr_ipx ipx;
491#endif
492 } sockaddr;
493 socklen_t socklen;
494 struct roar_sockname * rsockname;
495#endif
[1505]496
497 if ( vio == NULL || cmd == -1 )
498  return -1;
499
[1615]500 ROAR_DBG("roar_vio_basic_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data);
501
[1505]502 switch (cmd) {
[3795]503  case ROAR_VIO_CTL_GET_NAME:
504    if ( data == NULL )
505     return -1;
506
507    *(char**)data = "basic";
508    return 0;
509   break;
[1505]510  case ROAR_VIO_CTL_GET_FH:
511  case ROAR_VIO_CTL_GET_READ_FH:
512  case ROAR_VIO_CTL_GET_WRITE_FH:
[3436]513  case ROAR_VIO_CTL_GET_SELECT_FH:
514  case ROAR_VIO_CTL_GET_SELECT_READ_FH:
515  case ROAR_VIO_CTL_GET_SELECT_WRITE_FH:
[1615]516    ROAR_DBG("roar_vio_basic_ctl(vio=%p, cmd=ROAR_VIO_CTL_GET_*FH(0x%.8x), data=%p) = 0 // fh=%i", vio, cmd, data, roar_vio_get_fh(vio));
[1505]517    *(int*)data = roar_vio_get_fh(vio);
518    return 0;
519   break;
[2054]520  case ROAR_VIO_CTL_SET_NOSYNC:
521    vio->sync = NULL;
522    return 0;
523   break;
[3769]524  case ROAR_VIO_CTL_ACCEPT:
[3898]525    tmp = ROAR_ACCEPT(roar_vio_get_fh(vio), NULL, 0);
[3796]526    if ( tmp == -1 )
[3769]527     return -1;
528
529    // most proably a socket.
[3796]530    if ( roar_vio_open_fh_socket(data, tmp) == -1 ) {
[3769]531#ifdef ROAR_TARGET_WIN32
[3796]532     closesocket(tmp);
[3769]533#else
[3796]534     close(tmp);
[3769]535#endif
536     return -1;
537    }
538
539    return 0;
540   break;
[3796]541  case ROAR_VIO_CTL_SHUTDOWN:
542    tmp = *(int*)data;
543
544    if ( tmp & ROAR_VIO_SHUTDOWN_READ ) {
545     s_r = 1;
546     tmp -= ROAR_VIO_SHUTDOWN_READ;
547    }
548
549    if ( tmp & ROAR_VIO_SHUTDOWN_WRITE ) {
550     s_w = 1;
551     tmp -= ROAR_VIO_SHUTDOWN_WRITE;
552    }
553
554    if ( tmp != 0 ) /* we currently only support R and W shutdowns */
555     return -1;
556
557    if ( s_r && s_w ) {
558     tmp = SHUT_RDWR;
559    } else if ( s_r ) {
560     tmp = SHUT_RD;
561    } else if ( s_w ) {
562     tmp = SHUT_WR;
563    } else {
564     return 0; // nothing to do.
565    }
566
[3858]567    return ROAR_SHUTDOWN(roar_vio_get_fh(vio), tmp);
[3796]568   break;
[4705]569#if defined(ROAR_HAVE_GETSOCKNAME) || defined(ROAR_HAVE_GETPEERNAME)
570  case ROAR_VIO_CTL_GET_SOCKNAME:
571  case ROAR_VIO_CTL_GET_PEERNAME:
572    if ( data == NULL )
573     return -1;
574
575    rsockname = data;
576
577    socklen = sizeof(sockaddr);
578
579    if ( cmd == ROAR_VIO_CTL_GET_SOCKNAME ) {
580#ifdef ROAR_HAVE_GETSOCKNAME
581     tmp = getsockname(roar_vio_get_fh(vio), &(sockaddr.sa), &socklen);
582#else
583     return -1;
584#endif
585    } else if ( cmd == ROAR_VIO_CTL_GET_PEERNAME ) {
586#ifdef ROAR_HAVE_GETPEERNAME
587     tmp = getpeername(roar_vio_get_fh(vio), &(sockaddr.sa), &socklen);
588#else
589     return -1;
590#endif
591    } else {
592     return -1;
593    }
594
595    if ( tmp == -1 )
596     return -1;
597
598    memset(rsockname, 0, sizeof(struct roar_sockname));
599
600    switch (sockaddr.sa.sa_family) {
[4730]601#if defined(AF_UNIX) && defined(ROAR_HAVE_UNIX)
[4705]602     case AF_UNIX:
603       rsockname->type = ROAR_SOCKET_TYPE_UNIX;
604       if ( sockaddr.un.sun_path[0] == 0 ) {
605        rsockname->addr = roar_mm_malloc(sizeof(sockaddr.un.sun_path));
606        if ( rsockname->addr == NULL )
607         return -1;
608        memcpy(rsockname->addr, sockaddr.un.sun_path, sizeof(sockaddr.un.sun_path));
609       } else {
610        rsockname->addr = roar_mm_strdup(sockaddr.un.sun_path);
611       }
612      break;
613#endif
[4730]614#if defined(AF_DECnet) && defined(ROAR_HAVE_LIBDNET)
[4705]615     case AF_DECnet:
616       rsockname->type = ROAR_SOCKET_TYPE_DECNET;
617
618       if ( sockaddr.dn.sdn_add.a_len != 2 )
619        return -1;
620
621       rsockname->addr = roar_mm_malloc(28);
622       if ( rsockname->addr == NULL )
623        return -1;
624
625       snprintf(rsockname->addr, 28, "%i.%i::",
626                 sockaddr.dn.sdn_add.a_addr[1] >> 2,
627                 sockaddr.dn.sdn_add.a_addr[0] + ((sockaddr.dn.sdn_add.a_addr[1] & 0x03) << 8));
628
629       rsockname->port = sockaddr.dn.sdn_objnum;
630       if ( sockaddr.dn.sdn_objnum == 0 ) {
631        tmp = strlen(rsockname->addr);
632        memcpy(rsockname->addr + tmp, sockaddr.dn.sdn_objname, sockaddr.dn.sdn_objnamel);
633        rsockname->addr[tmp + sockaddr.dn.sdn_objnamel] = 0;
634       }
635      break;
636#endif
[4730]637#if defined(AF_INET) && (defined(ROAR_HAVE_IPV4) || defined(ROAR_HAVE_IPV6))
[4705]638     case AF_INET:
639       rsockname->type = ROAR_SOCKET_TYPE_INET;
640       rsockname->port = ntohs(sockaddr.in.sin_port);
641       rsockname->addr = roar_mm_strdup(inet_ntoa(sockaddr.in.sin_addr));
642      break;
643#endif
[4730]644#if defined(AF_INET6) && defined(ROAR_HAVE_IPV6)
[4705]645     case AF_INET6:
646       rsockname->type = ROAR_SOCKET_TYPE_INET6;
647       rsockname->port = ntohs(sockaddr.in6.sin6_port);
648      break;
649#endif
650     default:
651       return -1;
652    }
653    return 0;
654#endif
655   break;
[3895]656#ifdef ROAR_HAVE_H_SYS_IOCTL
[3852]657  case ROAR_VIO_CTL_SYSIO_IOCTL:
658    sysioctl = data;
659    return ioctl(roar_vio_get_fh(vio), sysioctl->cmd, sysioctl->argp);
660   break;
[3895]661#endif
[4718]662#ifdef ROAR_HAVE_GETSOCKOPT
663  case ROAR_VIO_CTL_GET_SYSIO_SOCKOPT:
664    syssockopt = data;
665    return getsockopt(roar_vio_get_fh(vio), syssockopt->level, syssockopt->optname, syssockopt->optval, &(syssockopt->optlen));
666   break;
667#endif
668#ifdef ROAR_HAVE_SETSOCKOPT
669  case ROAR_VIO_CTL_SET_SYSIO_SOCKOPT:
670    syssockopt = data;
671    return setsockopt(roar_vio_get_fh(vio), syssockopt->level, syssockopt->optname, syssockopt->optval, syssockopt->optlen);
672   break;
673#endif
[1505]674 }
675
[4873]676 roar_err_set(ROAR_ERROR_BADRQC);
[1505]677 return -1;
678}
679
[1241]680int     roar_vio_basic_close    (struct roar_vio_calls * vio) {
[1474]681#ifdef _CAN_OPERATE
[1336]682 if ( roar_vio_get_fh(vio) != -1 )
683  return close(roar_vio_get_fh(vio));
684
685 return 0;
[1474]686#else
687 return -1;
688#endif
[1241]689}
690
[943]691// null
692ssize_t roar_vio_null_rw    (struct roar_vio_calls * vio, void *buf, size_t count) {
693 if ( vio == NULL || buf == NULL )
694  return -1;
695
696 return 0;
697}
698
[1665]699int     roar_vio_null_sync    (struct roar_vio_calls * vio) {
700 return 0;
701}
702
[886]703// pass
[1247]704int     roar_vio_open_pass    (struct roar_vio_calls * calls, struct roar_vio_calls * dst) {
705 if ( calls == NULL )
706  return -1;
707
708 memset((void*)calls, 0, sizeof(struct roar_vio_calls));
709
710 calls->read     = roar_vio_pass_read;
711 calls->write    = roar_vio_pass_write;
712 calls->lseek    = roar_vio_pass_lseek;
713 calls->nonblock = roar_vio_pass_nonblock;
714 calls->sync     = roar_vio_pass_sync;
[1615]715 calls->ctl      = roar_vio_pass_ctl;
[1247]716 calls->close    = roar_vio_pass_close;
717
718 calls->inst     = dst;
719
720 return 0;
721}
722
[886]723ssize_t roar_vio_pass_read (struct roar_vio_calls * vio, void *buf, size_t count) {
724 return roar_vio_read((struct roar_vio_calls *) vio->inst, buf, count);
725}
726
727ssize_t roar_vio_pass_write(struct roar_vio_calls * vio, void *buf, size_t count) {
728 return roar_vio_write((struct roar_vio_calls *) vio->inst, buf, count);
729}
730
731off_t   roar_vio_pass_lseek(struct roar_vio_calls * vio, off_t offset, int whence) {
732 return roar_vio_lseek((struct roar_vio_calls *) vio->inst, offset, whence);
733}
734
[1241]735int     roar_vio_pass_nonblock(struct roar_vio_calls * vio, int state) {
736 return roar_vio_nonblock((struct roar_vio_calls *) vio->inst, state);
737}
738
739int     roar_vio_pass_sync    (struct roar_vio_calls * vio) {
740 return roar_vio_sync((struct roar_vio_calls *) vio->inst);
741}
742
743int     roar_vio_pass_ctl     (struct roar_vio_calls * vio, int cmd, void * data) {
[1505]744 if (vio == NULL || cmd == -1)
745  return -1;
746
[1615]747 ROAR_DBG("roar_vio_pass_ctl(vio=%p, cmd=0x%.8x, data=%p) = ?", vio, cmd, data);
748
[1505]749 switch (cmd) {
[3795]750  case ROAR_VIO_CTL_GET_NAME:
751    if ( data == NULL )
752     return -1;
753
[4829]754    // dirty trick to get real name...
755    if ( vio->read == roar_vio_re_read ) {
756     *(char**)data = "re";
757    } else {
758     *(char**)data = "pass";
759    }
[3795]760    return 0;
761   break;
[1505]762  case ROAR_VIO_CTL_GET_NEXT:
763    *(struct roar_vio_calls **)data = vio->inst;
764    return 0;
765   break;
766  case ROAR_VIO_CTL_SET_NEXT:
767    vio->inst = *(struct roar_vio_calls **)data;
768    return 0;
769   break;
770 }
771
[1241]772 return roar_vio_ctl((struct roar_vio_calls *) vio->inst, cmd, data);
773}
774
775int     roar_vio_pass_close   (struct roar_vio_calls * vio) {
776 return roar_vio_close((struct roar_vio_calls *) vio->inst);
777}
778
[886]779
780// re
[1247]781int     roar_vio_open_re (struct roar_vio_calls * calls, struct roar_vio_calls * dst) {
782 if ( roar_vio_open_pass(calls, dst) == -1 )
783  return -1;
784
785 calls->read  = roar_vio_re_read;
786 calls->write = roar_vio_re_write;
787 calls->lseek = roar_vio_re_lseek;
788
789 return 0;
790}
[886]791ssize_t roar_vio_re_read (struct roar_vio_calls * vio, void *buf, size_t count) {
792  size_t len =  0;
793 ssize_t r   = -1;
794
795 if ( vio == NULL )
796  return -1;
797
798 if ( vio->inst == NULL )
799  return -1;
800
[4873]801 roar_err_clear_all();
[886]802
803 while ( (r = roar_vio_read((struct roar_vio_calls *) vio->inst, buf, count)) > 0 ) {
804  len   += r;
805  buf   += r;
806  count -= r;
807  if ( count == 0 )
808   break;
809 }
810
811 if ( len == 0 && r == -1 )
812  return -1;
813
814 return len;
815}
816
817ssize_t roar_vio_re_write(struct roar_vio_calls * vio, void *buf, size_t count) {
818  size_t len =  0;
819 ssize_t r   = -1;
820
821 if ( vio == NULL )
822  return -1;
823
824 if ( vio->inst == NULL )
825  return -1;
826
[4873]827 roar_err_clear_all();
[886]828
829 while ( (r = roar_vio_write((struct roar_vio_calls *) vio->inst, buf, count)) > 0 ) {
830  len   += r;
831  buf   += r;
832  count -= r;
833  if ( count == 0 )
834   break;
835 }
836
837 if ( len == 0 && r == -1 )
838  return -1;
839
840 return len;
841}
842
[1247]843// TODO: we should do a some more intelgent thing here.
[886]844off_t   roar_vio_re_lseek(struct roar_vio_calls * vio, off_t offset, int whence) {
845 return roar_vio_lseek((struct roar_vio_calls *) vio->inst, offset, whence);
846}
847
[590]848//ll
Note: See TracBrowser for help on using the repository browser.