Modified netcam code to use 'select' on recv instead of SO_RECVTIMEO.
Also removed the 'timeout' argument from the routine netcam_recv (since
it wasn't used anywhere).
This commit is contained in:
BillBrack
2006-04-16 02:45:32 +00:00
parent ea0d819030
commit dffe9105da
3 changed files with 17 additions and 41 deletions

View File

@@ -653,18 +653,9 @@ static int netcam_connect(netcam_context_ptr netcam, struct timeval *timeout)
if (timeout)
netcam->timeout = *timeout;
if ((setsockopt(netcam->sock, SOL_SOCKET, SO_RCVTIMEO,
&netcam->timeout, sizeof(netcam->timeout))) < 0) {
motion_log(LOG_ERR, 1, "setsockopt() failed");
netcam_disconnect(netcam);
return -1;
}
/*
* Unfortunately, the SO_RCVTIMEO does not affect the 'connect'
* call, so we need to be quite a bit more clever. We want to
* use netcam->timeout, so we set the socket non-blocking and
* then use a 'select' system call to control the timeout.
* We set the socket non-blocking and then use a 'select'
* system call to control the timeout.
*/
if ((saveflags = fcntl(netcam->sock, F_GETFL, 0)) < 0) {
@@ -687,14 +678,6 @@ static int netcam_connect(netcam_context_ptr netcam, struct timeval *timeout)
sizeof(server));
back_err = errno; /* save the errno from connect */
/* Restore the normal socket flags */
if (fcntl(netcam->sock, F_SETFL, saveflags) < 0) {
motion_log(LOG_ERR, 1, "fcntl(3) on socket");
close(netcam->sock);
netcam->sock = -1;
return -1;
}
/* If the connect failed with anything except EINPROGRESS, error */
if ((ret < 0) && (back_err != EINPROGRESS)) {
motion_log(LOG_ERR, 1, "connect() failed (%d)", back_err);
@@ -981,8 +964,7 @@ static int netcam_read_html_jpeg(netcam_context_ptr netcam)
retval = netcam_recv(netcam, netcam->response->buffer +
netcam->response->buffer_left,
sizeof(netcam->response->buffer) -
netcam->response->buffer_left,
NULL);
netcam->response->buffer_left);
if (retval <= 0) { /* this is a fatal error */
motion_log(LOG_ERR, 1, "recv() fail after boundary string");
@@ -1520,33 +1502,27 @@ static int netcam_setup_ftp(netcam_context_ptr netcam, struct url_t *url) {
* netcam Pointer to a netcam context
* buffptr Pointer to the receive buffer
* buffsize Length of the buffer
* timeout Pointer to struct timeval (NULL for no change)
*
* Returns:
* If successful, the length of the message received, otherwise the
* error reply from the system call.
*
*/
ssize_t netcam_recv(netcam_context_ptr netcam, void *buffptr, size_t buffsize,
struct timeval *timeout) {
ssize_t netcam_recv(netcam_context_ptr netcam, void *buffptr, size_t buffsize) {
ssize_t retval;
fd_set fd_r;
struct timeval selecttime;
if (timeout) {
if ((timeout->tv_sec != netcam->timeout.tv_sec) ||
(timeout->tv_usec != netcam->timeout.tv_usec)) {
if ((setsockopt(netcam->sock, SOL_SOCKET,
SO_RCVTIMEO, timeout, sizeof(*timeout))) < 0) {
motion_log(LOG_ERR, 1, "setsockopt() in netcam_recv failed");
}
}
netcam->timeout = *timeout;
FD_ZERO(&fd_r);
FD_SET(netcam->sock, &fd_r);
selecttime = netcam->timeout;
retval = select(FD_SETSIZE, &fd_r, NULL, NULL, &selecttime);
if (retval == 0) { /* 0 means timeout */
return -1;
}
do {
retval = recv(netcam->sock, buffptr, buffsize, 0);
} while ((retval < 0) && ((errno == EINTR) || (errno == EAGAIN)));
return retval;
return recv(netcam->sock, buffptr, buffsize, 0);
}
/**

View File

@@ -235,6 +235,6 @@ void netcam_get_dimensions (struct netcam_context *);
int netcam_start (struct context *);
int netcam_next (struct context *, unsigned char *);
void netcam_cleanup (struct netcam_context *, int);
ssize_t netcam_recv(netcam_context_ptr, void *, size_t, struct timeval *);
ssize_t netcam_recv(netcam_context_ptr, void *, size_t);
#endif

View File

@@ -274,7 +274,7 @@ void rbuf_initialize(netcam_context_ptr netcam)
int rbuf_read_bufferful(netcam_context_ptr netcam)
{
return netcam_recv(netcam, netcam->response->buffer,
sizeof (netcam->response->buffer), 0);
sizeof (netcam->response->buffer));
}
/* Like rbuf_readchar(), only don't move the buffer position. */
@@ -285,7 +285,7 @@ int rbuf_peek(netcam_context_ptr netcam, char *store)
netcam->response->buffer_pos = netcam->response->buffer;
netcam->response->buffer_left = 0;
res = netcam_recv (netcam, netcam->response->buffer,
sizeof (netcam->response->buffer), NULL);
sizeof (netcam->response->buffer));
if (res <= 0)
return res;