Re: [PATCH] build failure on Debian kfreebsd
Jean-Paul Saman <[email protected]>
| Newsgroups | gmane.comp.video.videolan.libdvbpsi.devel |
|---|---|
| Message-ID | <CAK9US3B8XoPFxWhMu8rAxHiug9=bBZ16_D6u1L6K8NJ7Md3=7g@mail.gmail.com> |
On Mon, Aug 19, 2013 at 11:38 AM, Alessio Treglia <[email protected]>wrote: > Hi there, > > libdvbpsi failed to build on Debian kfreebsd in the past. > Sebastian Ramacher worked on a patch to fix such issue, the description > follows: > 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. > > You find the patch attached, thanks for considering. > Cheers, > Thanks for sending in this patch. I reviewed and modified the patch and attached it here for double checking by you. Kind regards, Jean-Paul Saman. > -- > Alessio Treglia | www.alessiotreglia.com > Debian Developer | [email protected] > Ubuntu Core Developer | [email protected] > 0416 0004 A827 6E40 BB98 90FB E8A4 8AE5 311D 765A > > _______________________________________________ > libdvbpsi-devel mailing list > [email protected] > https://mailman.videolan.org/listinfo/libdvbpsi-devel > > _______________________________________________ libdvbpsi-devel mailing list [email protected] https://mailman.videolan.org/listinfo/libdvbpsi-devel
0001-dvbinfo-MSG_CMSG_CLOEXEC-if-a-flag-for-recvmsg-and-n.patch
(application/octet-stream, 4.2 KB)
From a11c80a216314cee4a26904ba7d7314a9dbe145a Mon Sep 17 00:00:00 2001 From: Jean-Paul Saman <[email protected]> Date: Mon, 19 Aug 2013 14:19:21 +0200 Subject: [PATCH] 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. --- examples/dvbinfo/tcp.c | 39 ++++++++++++++++++++++++++++++++++++--- examples/dvbinfo/udp.c | 37 +++++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 5 deletions(-) diff --git a/examples/dvbinfo/tcp.c b/examples/dvbinfo/tcp.c index db3ad2b..31048e6 100644 --- a/examples/dvbinfo/tcp.c +++ b/examples/dvbinfo/tcp.c @@ -50,9 +50,31 @@ # include <arpa/inet.h> #endif +#ifndef SOCK_CLOEXEC +# include <fcntl.h> +#endif + #include "tcp.h" #ifdef HAVE_SYS_SOCKET_H + +#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("tcp socket error"); + return false; +} +#endif + int tcp_close(int fd) { int result = 0; @@ -98,13 +120,25 @@ int tcp_open(const char *ipaddress, int port) 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) { perror("tcp socket error"); 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)); result = connect( s_ctl, ptr->ai_addr, ptr->ai_addrlen ); @@ -126,7 +160,7 @@ ssize_t tcp_read(int fd, void *buf, size_t count) { ssize_t err; again: - err = recv(fd, buf, count, MSG_CMSG_CLOEXEC | MSG_WAITALL); + err = recv(fd, buf, count, MSG_WAITALL); if (err < 0) { switch(errno) @@ -148,4 +182,3 @@ again: return err; } #endif - diff --git a/examples/dvbinfo/udp.c b/examples/dvbinfo/udp.c index e2832f2..4e7067f 100644 --- a/examples/dvbinfo/udp.c +++ b/examples/dvbinfo/udp.c @@ -57,6 +57,10 @@ # define IPPROTO_IPV6 41 /* IANA */ #endif +#ifndef SOCK_CLOEXEC +# include <fcntl.h> +#endif + #include <assert.h> #include "udp.h" @@ -176,6 +180,23 @@ static bool is_ipv6(const char *ipaddress) 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 result = 0; @@ -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 ) { - 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) { perror("udp socket error"); 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) * to avoid packet loss caused in case of scheduling hiccups */ setsockopt (s_ctl, SOL_SOCKET, SO_RCVBUF, @@ -267,7 +300,7 @@ ssize_t udp_read(int fd, void *buf, size_t count) { ssize_t err; again: - err = recv(fd, buf, count, MSG_CMSG_CLOEXEC); + err = recv(fd, buf, count, 0); if (err < 0) { switch(errno) -- 1.8.1.4