Commit 3d865a7a authored by Jean-Paul Saman's avatar Jean-Paul Saman

dvbinfo: MSG_CMSG_CLOEXEC if a flag for recvmsg and not recv.

MSG_CMSG_CLOEXEC is a flag for recvmsg and not recv. Thus rewrite
{udp,tcp}_open to create sockets with SOCK_CLOEXEC. If SOCK_CLOEXEC is not
available, FD_CLOEXEC is set instead.
parent 30f89686
/***************************************************************************** /*****************************************************************************
* tcp.c: network socket abstractions * tcp.c: network socket abstractions
***************************************************************************** *****************************************************************************
* Copyright (C) 2010-2011 M2X BV * Copyright (C) 2010-2013 M2X BV
* *
* Authors: Jean-Paul Saman <jpsaman@videolan.org> * Authors: Jean-Paul Saman <jpsaman@videolan.org>
* *
...@@ -50,9 +50,32 @@ ...@@ -50,9 +50,32 @@
# include <arpa/inet.h> # include <arpa/inet.h>
#endif #endif
#ifndef SOCK_CLOEXEC
# include <fcntl.h>
#endif
#include "tcp.h" #include "tcp.h"
#ifdef HAVE_SYS_SOCKET_H #ifdef HAVE_SYS_SOCKET_H
#ifndef SOCK_CLOEXEC
# include <stdbool.h>
static bool set_fdsocketclosexec(int s)
{
int flags = fcntl(s, F_GETFD);
if (flags != -1)
{
if (fcntl(s, F_SETFD, flags | FD_CLOEXEC) != -1)
{
return true;
}
}
perror("tcp socket error");
return false;
}
#endif
int tcp_close(int fd) int tcp_close(int fd)
{ {
int result = 0; int result = 0;
...@@ -98,13 +121,25 @@ int tcp_open(const char *ipaddress, int port) ...@@ -98,13 +121,25 @@ int tcp_open(const char *ipaddress, int port)
for (struct addrinfo *ptr = addr; ptr != NULL; ptr = ptr->ai_next ) for (struct addrinfo *ptr = addr; ptr != NULL; ptr = ptr->ai_next )
{ {
s_ctl = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); int sflags = 0;
#ifdef SOCK_CLOEXEC
sflags = SOCK_CLOEXEC;
#endif
s_ctl = socket(ptr->ai_family, ptr->ai_socktype | sflags, ptr->ai_protocol);
if (s_ctl <= 0) if (s_ctl <= 0)
{ {
perror("tcp socket error"); perror("tcp socket error");
continue; continue;
} }
#ifndef SOCK_CLOEXEC
if (!set_fdsocketclosexec(s_ctl))
{
close(s_ctl);
continue;
}
#endif
setsockopt (s_ctl, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof (int)); setsockopt (s_ctl, SOL_SOCKET, SO_REUSEADDR, &(int){ 1 }, sizeof (int));
result = connect( s_ctl, ptr->ai_addr, ptr->ai_addrlen ); result = connect( s_ctl, ptr->ai_addr, ptr->ai_addrlen );
...@@ -126,7 +161,7 @@ ssize_t tcp_read(int fd, void *buf, size_t count) ...@@ -126,7 +161,7 @@ ssize_t tcp_read(int fd, void *buf, size_t count)
{ {
ssize_t err; ssize_t err;
again: again:
err = recv(fd, buf, count, MSG_CMSG_CLOEXEC | MSG_WAITALL); err = recv(fd, buf, count, MSG_WAITALL);
if (err < 0) if (err < 0)
{ {
switch(errno) switch(errno)
...@@ -148,4 +183,3 @@ again: ...@@ -148,4 +183,3 @@ again:
return err; return err;
} }
#endif #endif
/***************************************************************************** /*****************************************************************************
* udp.c: network socket abstractions * udp.c: network socket abstractions
***************************************************************************** *****************************************************************************
* Copyright (C) 2010-2011 M2X BV * Copyright (C) 2010-2013 M2X BV
* *
* Authors: Jean-Paul Saman <jpsaman@videolan.org> * Authors: Jean-Paul Saman <jpsaman@videolan.org>
* *
...@@ -57,6 +57,10 @@ ...@@ -57,6 +57,10 @@
# define IPPROTO_IPV6 41 /* IANA */ # define IPPROTO_IPV6 41 /* IANA */
#endif #endif
#ifndef SOCK_CLOEXEC
# include <fcntl.h>
#endif
#include <assert.h> #include <assert.h>
#include "udp.h" #include "udp.h"
...@@ -176,6 +180,23 @@ static bool is_ipv6(const char *ipaddress) ...@@ -176,6 +180,23 @@ static bool is_ipv6(const char *ipaddress)
return (strchr(ipaddress, ':') != NULL); return (strchr(ipaddress, ':') != NULL);
} }
#ifndef SOCK_CLOEXEC
static bool set_fdsocketclosexec(int s)
{
int flags = fcntl(s, F_GETFD);
if (flags != -1)
{
if (fcntl(s, F_SETFD, flags | FD_CLOEXEC) != -1)
{
return true;
}
}
perror("udp socket error");
return false;
}
#endif
int udp_close(int fd) int udp_close(int fd)
{ {
int result = 0; int result = 0;
...@@ -221,13 +242,25 @@ int udp_open(const char *interface, const char *ipaddress, int port) ...@@ -221,13 +242,25 @@ int udp_open(const char *interface, const char *ipaddress, int port)
for (struct addrinfo *ptr = addr; ptr != NULL; ptr = ptr->ai_next ) for (struct addrinfo *ptr = addr; ptr != NULL; ptr = ptr->ai_next )
{ {
s_ctl = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); int sflags = 0;
#ifdef SOCK_CLOEXEC
sflags = SOCK_CLOEXEC;
#endif
s_ctl = socket(ptr->ai_family, ptr->ai_socktype | sflags, ptr->ai_protocol);
if (s_ctl <= 0) if (s_ctl <= 0)
{ {
perror("udp socket error"); perror("udp socket error");
continue; continue;
} }
#ifndef SOCK_CLOEXEC
if (!set_fdsocketclosexec(s_ctl))
{
close(s_ctl);
continue;
}
#endif
/* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s) /* Increase the receive buffer size to 1/2MB (8Mb/s during 1/2s)
* to avoid packet loss caused in case of scheduling hiccups */ * to avoid packet loss caused in case of scheduling hiccups */
setsockopt (s_ctl, SOL_SOCKET, SO_RCVBUF, setsockopt (s_ctl, SOL_SOCKET, SO_RCVBUF,
...@@ -267,7 +300,7 @@ ssize_t udp_read(int fd, void *buf, size_t count) ...@@ -267,7 +300,7 @@ ssize_t udp_read(int fd, void *buf, size_t count)
{ {
ssize_t err; ssize_t err;
again: again:
err = recv(fd, buf, count, MSG_CMSG_CLOEXEC); err = recv(fd, buf, count, 0);
if (err < 0) if (err < 0)
{ {
switch(errno) switch(errno)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment