diff options
-rw-r--r-- | xine_input_vdr.c | 231 |
1 files changed, 145 insertions, 86 deletions
diff --git a/xine_input_vdr.c b/xine_input_vdr.c index 80594ce1..7ed846ef 100644 --- a/xine_input_vdr.c +++ b/xine_input_vdr.c @@ -4,7 +4,7 @@ * See the main source file 'xineliboutput.c' for copyright information and * how to reach the author. * - * $Id: xine_input_vdr.c,v 1.233 2009-02-25 12:40:39 phintuka Exp $ + * $Id: xine_input_vdr.c,v 1.234 2009-02-25 14:27:57 phintuka Exp $ * */ @@ -218,7 +218,6 @@ static void SetupLogLevel(void) #define KILOBYTE(x) (1024 * (x)) typedef struct udp_data_s udp_data_t; -typedef struct ts_data_s ts_data_t; /* plugin class */ typedef struct vdr_input_class_s { @@ -708,7 +707,16 @@ static void create_timeout_time(struct timespec *abstime, int timeout_ms) abstime->tv_nsec = now.tv_usec * 1000; } -static int io_select_rd (int fd) +/**************************** socket I/O *********************************/ + +/* + * io_select_rd() + * + * - poll socket for read + * - timeouts in 500 ms + * - returns XIO_* + */ +static int io_select_rd (int fd) { fd_set fdset, eset; int ret; @@ -721,7 +729,7 @@ static int io_select_rd (int fd) FD_ZERO (&eset); FD_SET (fd, &fdset); FD_SET (fd, &eset); - + select_timeout.tv_sec = 0; select_timeout.tv_usec = 500*1000; /* 500 ms */ errno = 0; @@ -730,189 +738,240 @@ static int io_select_rd (int fd) if (ret == 0) return XIO_TIMEOUT; if (ret < 0) { - if(errno == EINTR || errno == EAGAIN) + if (errno == EINTR || errno == EAGAIN) return XIO_TIMEOUT; return XIO_ERROR; } - if(FD_ISSET(fd,&eset)) + + if (FD_ISSET(fd, &eset)) return XIO_ERROR; - if(FD_ISSET(fd,&fdset)) + if (FD_ISSET(fd, &fdset)) return XIO_READY; return XIO_TIMEOUT; } -static void write_control_data(vdr_input_plugin_t *this, const void *str, size_t len) +/* + * write_control_data() + * + * - write len bytes to control socket. + * - returns number of bytes written, < 0 on error. + * + * NOTE: caller must hold fd_control lock ! + */ +static ssize_t write_control_data(vdr_input_plugin_t *this, const void *str, size_t len) { - size_t ret; - while(len>0) { + size_t ret, result = len; - if(!this->control_running) { + while (len > 0) { + + if (!this->control_running) { LOGERR("write_control aborted"); - return; + return -1; } -#if 1 + /* poll the socket */ fd_set fdset, eset; struct timeval select_timeout; FD_ZERO (&fdset); FD_ZERO (&eset); FD_SET (this->fd_control, &fdset); - FD_SET (this->fd_control, &eset); + FD_SET (this->fd_control, &eset); select_timeout.tv_sec = 0; select_timeout.tv_usec = 500*1000; /* 500 ms */ errno = 0; - if(1 != select (this->fd_control + 1, NULL, &fdset, &eset, &select_timeout) || - !FD_ISSET(this->fd_control, &fdset) || - FD_ISSET(this->fd_control, &eset)) { + if (1 != select (this->fd_control + 1, NULL, &fdset, &eset, &select_timeout) || + !FD_ISSET(this->fd_control, &fdset) || + FD_ISSET(this->fd_control, &eset)) { LOGERR("write_control failed (poll timeout or error)"); this->control_running = 0; - return; + return -1; } -#endif - if(!this->control_running) { + if (!this->control_running) { LOGERR("write_control aborted"); - return; + return -1; } errno = 0; - ret = write(this->fd_control, str, len); + ret = write (this->fd_control, str, len); - if(ret <= 0) { - if(ret == 0) { - LOGMSG("write_control: disconnected"); - } else if(errno == EAGAIN) { - LOGERR("write_control failed: EAGAIN"); - continue; - } else if(errno == EINTR) { - LOGERR("write_control failed: EINTR"); - pthread_testcancel(); + if (ret <= 0) { + if (ret == 0) { + LOGMSG("write_control: disconnected"); + } else if (errno == EAGAIN) { + LOGERR("write_control failed: EAGAIN"); + continue; + } else if (errno == EINTR) { + LOGERR("write_control failed: EINTR"); + pthread_testcancel(); continue; } else { - LOGERR("write_control failed"); + LOGERR("write_control failed"); } this->control_running = 0; - return; + return -1; } len -= ret; str += ret; } + + return result; } -static void write_control(vdr_input_plugin_t *this, const char *str) +/* + * write_control() + * + * - write null-terminated string to control socket. + * - returns number of bytes written, < 0 on error + * + * NOTE: caller should NOT hold fd_control lock ! + */ +static ssize_t write_control(vdr_input_plugin_t *this, const char *str) { - size_t len = strlen(str); + ssize_t ret = -1; mutex_lock_cancellable (&this->fd_control_lock); - write_control_data(this, str, len); + ret = write_control_data(this, str, strlen(str)); mutex_unlock_cancellable (&this->fd_control_lock); + return ret; } -static void printf_control(vdr_input_plugin_t *this, const char *fmt, ...) +/* + * printf_control() + * + * - returns number of bytes written, < 0 on error + * + * NOTE: caller should NOT hold fd_control lock ! + */ +static ssize_t printf_control(vdr_input_plugin_t *this, const char *fmt, ...) { va_list argp; - char buf[512]; + char buf[512]; + ssize_t result; va_start(argp, fmt); vsnprintf(buf, sizeof(buf), fmt, argp); buf[sizeof(buf)-1] = 0; - write_control(this, buf); + result = write_control(this, buf); + va_end(argp); + + return result; } -static int readline_control(vdr_input_plugin_t *this, char *buf, int maxlen, - int timeout) +/* + * readline_control() + * + * - read CR/LF terminated string from control socket + * - remove trailing CR/LF + * - returns > 0 : length of string + * = 0 : timeout + * < 0 : error + */ +static ssize_t readline_control(vdr_input_plugin_t *this, char *buf, size_t maxlen, int timeout) { - int num_bytes = 0, total_bytes = 0, err; + int poll_result; + ssize_t read_result; + size_t total_bytes = 0; *buf = 0; - while(total_bytes < maxlen-1 ) { + while (total_bytes < maxlen - 1) { - if(!this->control_running && timeout<0) + if (!this->control_running && timeout < 0) return -1; pthread_testcancel(); - err = io_select_rd(this->fd_control); + poll_result = io_select_rd(this->fd_control); pthread_testcancel(); - if(!this->control_running && timeout<0) + if (!this->control_running && timeout < 0) return -1; - if(err == XIO_TIMEOUT) { - if(timeout==0) - return 0; - if(timeout>0) - timeout--; + if (poll_result == XIO_TIMEOUT) { + if (timeout == 0) + return 0; + if (timeout > 0) + timeout--; continue; } - if(err == XIO_ABORTED) { - LOGERR("readline_control: XIO_ABORTED at [%d]", num_bytes); + if (poll_result == XIO_ABORTED) { + LOGERR("readline_control: XIO_ABORTED at [%u]", (uint)total_bytes); continue; } - if(err != XIO_READY /* == XIO_ERROR */) { - LOGERR("readline_control: poll error at [%d]", num_bytes); + if (poll_result != XIO_READY /* == XIO_ERROR */) { + LOGERR("readline_control: poll error at [%u]", (uint)total_bytes); return -1; } errno = 0; - num_bytes = read (this->fd_control, buf + total_bytes, 1); + read_result = read (this->fd_control, buf + total_bytes, 1); pthread_testcancel(); - if(!this->control_running && timeout<0) + if (!this->control_running && timeout < 0) return -1; - if (num_bytes <= 0) { - if(num_bytes==0) - LOGERR("Control stream disconnected"); + if (read_result <= 0) { + if (read_result == 0) + LOGERR("Control stream disconnected"); else - LOGERR("readline_control: read error at [%d]", num_bytes); - if(num_bytes < 0 && (errno == EINTR || errno==EAGAIN)) - continue; + LOGERR("readline_control: read error at [%u]", (uint)total_bytes); + if (read_result < 0 && (errno == EINTR || errno == EAGAIN)) + continue; return -1; } - - if(buf[total_bytes]) { - if(buf[total_bytes] == '\r') { - buf[total_bytes] = 0; - } else if(buf[total_bytes] == '\n') { - buf[total_bytes] = 0; - break; + + if (buf[total_bytes]) { + if (buf[total_bytes] == '\r') { + buf[total_bytes] = 0; + } else if (buf[total_bytes] == '\n') { + buf[total_bytes] = 0; + break; } else { - total_bytes ++; - buf[total_bytes] = 0; + total_bytes ++; + buf[total_bytes] = 0; } } - TRACE("readline_control: %d bytes ... %s\n", - total_bytes, buf); + TRACE("readline_control: %d bytes ... %s\n", len, buf); } - TRACE("readline_control: %d bytes (max %d)\n", total_bytes, maxlen); + TRACE("readline_control: %d bytes (max %d)\n", len, maxlen); return total_bytes; } - -static int read_control(vdr_input_plugin_t *this, uint8_t *buf, int len) +/* + * read_control() + * + * - read len bytes from control socket + * - returns < 0 on error + */ +static ssize_t read_control(vdr_input_plugin_t *this, uint8_t *buf, size_t len) { - int num_bytes, total_bytes = 0, err; + int poll_result; + ssize_t num_bytes; + size_t total_bytes = 0; + + while (total_bytes < len) { + + if (!this->control_running) + return -1; - while(total_bytes < len) { pthread_testcancel(); - err = io_select_rd(this->fd_control); + poll_result = io_select_rd(this->fd_control); pthread_testcancel(); - if(!this->control_running) + if (!this->control_running) return -1; - if(err == XIO_TIMEOUT) { + if (poll_result == XIO_TIMEOUT) { continue; } - if(err == XIO_ABORTED) { + if (poll_result == XIO_ABORTED) { LOGERR("read_control: XIO_ABORTED"); continue; } - if(err == XIO_ERROR) { + if (poll_result == XIO_ERROR) { LOGERR("read_control: poll error"); return -1; } @@ -922,8 +981,8 @@ static int read_control(vdr_input_plugin_t *this, uint8_t *buf, int len) pthread_testcancel(); if (num_bytes <= 0) { - if(this->control_running && num_bytes<0) - LOGERR("read_control read() error"); + if (this->control_running && num_bytes < 0) + LOGERR("read_control read() error"); return -1; } total_bytes += num_bytes; |