mirror of
https://github.com/rofafor/vdr-plugin-iptv.git
synced 2023-10-10 13:37:03 +02:00
Added FreeBSD support (Thanks to Jürgen Lock).
This commit is contained in:
parent
547306b67c
commit
75d17b289b
4
HISTORY
4
HISTORY
@ -177,3 +177,7 @@ VDR Plugin 'iptv' Revision History
|
|||||||
|
|
||||||
- Optimized reading from UDP sockets.
|
- Optimized reading from UDP sockets.
|
||||||
- Fixed ProvidesChannel method.
|
- Fixed ProvidesChannel method.
|
||||||
|
|
||||||
|
2012-07-10: Version 1.0.1
|
||||||
|
|
||||||
|
- Added FreeBSD support (Thanks to Jürgen Lock).
|
||||||
|
12
Makefile
12
Makefile
@ -5,9 +5,15 @@
|
|||||||
# Debugging on/off
|
# Debugging on/off
|
||||||
#IPTV_DEBUG = 1
|
#IPTV_DEBUG = 1
|
||||||
|
|
||||||
|
# Default shell for EXT protocol
|
||||||
|
#IPTV_EXTSHELL = /bin/bash
|
||||||
|
|
||||||
# Strip debug symbols? Set eg. to /bin/true if not
|
# Strip debug symbols? Set eg. to /bin/true if not
|
||||||
STRIP = strip
|
STRIP = strip
|
||||||
|
|
||||||
|
# Install command
|
||||||
|
INSTALL = cp --remove-destination
|
||||||
|
|
||||||
# The official name of this plugin.
|
# The official name of this plugin.
|
||||||
# This name will be used in the '-P...' option of VDR to load the plugin.
|
# This name will be used in the '-P...' option of VDR to load the plugin.
|
||||||
# By default the main source file also carries this name.
|
# By default the main source file also carries this name.
|
||||||
@ -60,6 +66,10 @@ ifdef IPTV_DEBUG
|
|||||||
DEFINES += -DDEBUG
|
DEFINES += -DDEBUG
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef IPTV_EXTSHELL
|
||||||
|
DEFINES += -DEXTSHELL='"$(IPTV_EXTSHELL)"'
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq ($(strip $(GITTAG)),)
|
ifneq ($(strip $(GITTAG)),)
|
||||||
DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'
|
DEFINES += -DGITVERSION='"-GIT-$(GITTAG)"'
|
||||||
endif
|
endif
|
||||||
@ -123,7 +133,7 @@ libvdr-$(PLUGIN).so: $(OBJS)
|
|||||||
ifndef IPTV_DEBUG
|
ifndef IPTV_DEBUG
|
||||||
@$(STRIP) $@
|
@$(STRIP) $@
|
||||||
endif
|
endif
|
||||||
@cp --remove-destination $@ $(LIBDIR)/$@.$(APIVERSION)
|
@$(INSTALL) $@ $(LIBDIR)/$@.$(APIVERSION)
|
||||||
|
|
||||||
dist: $(I18Npo) clean
|
dist: $(I18Npo) clean
|
||||||
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
@-rm -rf $(TMPDIR)/$(ARCHIVE)
|
||||||
|
3
common.h
3
common.h
@ -42,7 +42,8 @@
|
|||||||
do { \
|
do { \
|
||||||
if (exp) { \
|
if (exp) { \
|
||||||
char tmp[64]; \
|
char tmp[64]; \
|
||||||
error(errstr": %s", strerror_r(errno, tmp, sizeof(tmp))); \
|
strerror_r(errno, tmp, sizeof(tmp)); \
|
||||||
|
error(errstr": %s", tmp); \
|
||||||
func; \
|
func; \
|
||||||
ret; \
|
ret; \
|
||||||
} \
|
} \
|
||||||
|
2
iptv.c
2
iptv.c
@ -21,7 +21,7 @@
|
|||||||
#define GITVERSION ""
|
#define GITVERSION ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char VERSION[] = "1.0.0" GITVERSION;
|
const char VERSION[] = "1.0.1" GITVERSION;
|
||||||
static const char DESCRIPTION[] = trNOOP("Experience the IPTV");
|
static const char DESCRIPTION[] = trNOOP("Experience the IPTV");
|
||||||
|
|
||||||
class cPluginIptv : public cPlugin {
|
class cPluginIptv : public cPlugin {
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "protocolext.h"
|
#include "protocolext.h"
|
||||||
|
|
||||||
|
#ifndef EXTSHELL
|
||||||
|
#define EXTSHELL "/bin/bash"
|
||||||
|
#endif
|
||||||
|
|
||||||
cIptvProtocolExt::cIptvProtocolExt()
|
cIptvProtocolExt::cIptvProtocolExt()
|
||||||
: pid(-1),
|
: pid(-1),
|
||||||
scriptFile(""),
|
scriptFile(""),
|
||||||
@ -56,7 +60,9 @@ void cIptvProtocolExt::ExecuteScript(void)
|
|||||||
// Execute the external script
|
// Execute the external script
|
||||||
cString cmd = cString::sprintf("%s %d %d", *scriptFile, scriptParameter, streamPort);
|
cString cmd = cString::sprintf("%s %d %d", *scriptFile, scriptParameter, streamPort);
|
||||||
debug("cIptvProtocolExt::ExecuteScript(child): %s\n", *cmd);
|
debug("cIptvProtocolExt::ExecuteScript(child): %s\n", *cmd);
|
||||||
if (execl("/bin/bash", "sh", "-c", *cmd, (char *)NULL) == -1) {
|
// Create a new session for a process group
|
||||||
|
ERROR_IF_RET(setsid() == -1, "setsid()", _exit(-1));
|
||||||
|
if (execl(EXTSHELL, "sh", "-c", *cmd, (char *)NULL) == -1) {
|
||||||
error("Script execution failed: %s", *cmd);
|
error("Script execution failed: %s", *cmd);
|
||||||
_exit(-1);
|
_exit(-1);
|
||||||
}
|
}
|
||||||
@ -75,27 +81,36 @@ void cIptvProtocolExt::TerminateScript(void)
|
|||||||
if (pid > 0) {
|
if (pid > 0) {
|
||||||
const unsigned int timeoutms = 100;
|
const unsigned int timeoutms = 100;
|
||||||
unsigned int waitms = 0;
|
unsigned int waitms = 0;
|
||||||
siginfo_t waitStatus;
|
|
||||||
bool waitOver = false;
|
bool waitOver = false;
|
||||||
// signal and wait for termination
|
// Signal and wait for termination
|
||||||
int retval = kill(pid, SIGINT);
|
int retval = killpg(pid, SIGINT);
|
||||||
ERROR_IF_RET(retval < 0, "kill()", waitOver = true);
|
ERROR_IF_RET(retval < 0, "kill()", waitOver = true);
|
||||||
while (!waitOver) {
|
while (!waitOver) {
|
||||||
retval = 0;
|
retval = 0;
|
||||||
waitms += timeoutms;
|
waitms += timeoutms;
|
||||||
if ((waitms % 2000) == 0) {
|
if ((waitms % 2000) == 0) {
|
||||||
error("Script '%s' won't terminate - killing it!", *scriptFile);
|
error("Script '%s' won't terminate - killing it!", *scriptFile);
|
||||||
kill(pid, SIGKILL);
|
killpg(pid, SIGKILL);
|
||||||
}
|
}
|
||||||
// Clear wait status to make sure child exit status is accessible
|
// Clear wait status to make sure child exit status is accessible
|
||||||
|
// and wait for child termination
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
int waitStatus = 0;
|
||||||
|
retval = waitpid(pid, &waitStatus, WNOHANG);
|
||||||
|
#else // __FreeBSD__
|
||||||
|
siginfo_t waitStatus;
|
||||||
memset(&waitStatus, '\0', sizeof(waitStatus));
|
memset(&waitStatus, '\0', sizeof(waitStatus));
|
||||||
// Wait for child termination
|
|
||||||
retval = waitid(P_PID, pid, &waitStatus, (WNOHANG | WEXITED));
|
retval = waitid(P_PID, pid, &waitStatus, (WNOHANG | WEXITED));
|
||||||
|
#endif // __FreeBSD__
|
||||||
ERROR_IF_RET(retval < 0, "waitid()", waitOver = true);
|
ERROR_IF_RET(retval < 0, "waitid()", waitOver = true);
|
||||||
// These are the acceptable conditions under which child exit is
|
// These are the acceptable conditions under which child exit is
|
||||||
// regarded as successful
|
// regarded as successful
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
if (retval > 0 && (WIFEXITED(waitStatus) || WIFSIGNALED(waitStatus))) {
|
||||||
|
#else // __FreeBSD__
|
||||||
if (!retval && waitStatus.si_pid && (waitStatus.si_pid == pid) &&
|
if (!retval && waitStatus.si_pid && (waitStatus.si_pid == pid) &&
|
||||||
((waitStatus.si_code == CLD_EXITED) || (waitStatus.si_code == CLD_KILLED))) {
|
((waitStatus.si_code == CLD_EXITED) || (waitStatus.si_code == CLD_KILLED))) {
|
||||||
|
#endif // __FreeBSD__
|
||||||
debug("Child (%d) exited as expected\n", pid);
|
debug("Child (%d) exited as expected\n", pid);
|
||||||
waitOver = true;
|
waitOver = true;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,9 @@
|
|||||||
#ifndef __IPTV_SECTIONFILTER_H
|
#ifndef __IPTV_SECTIONFILTER_H
|
||||||
#define __IPTV_SECTIONFILTER_H
|
#define __IPTV_SECTIONFILTER_H
|
||||||
|
|
||||||
|
#ifdef __FreeBSD__
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#endif // __FreeBSD__
|
||||||
#include <vdr/device.h>
|
#include <vdr/device.h>
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
6
socket.c
6
socket.c
@ -57,9 +57,11 @@ bool cIptvSocket::OpenSocket(const int Port, const bool isUdp)
|
|||||||
// Allow multiple sockets to use the same PORT number
|
// Allow multiple sockets to use the same PORT number
|
||||||
ERROR_IF_FUNC(setsockopt(socketDesc, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0, "setsockopt(SO_REUSEADDR)",
|
ERROR_IF_FUNC(setsockopt(socketDesc, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0, "setsockopt(SO_REUSEADDR)",
|
||||||
CloseSocket(), return false);
|
CloseSocket(), return false);
|
||||||
|
#ifndef __FreeBSD__
|
||||||
// Allow packet information to be fetched
|
// Allow packet information to be fetched
|
||||||
ERROR_IF_FUNC(setsockopt(socketDesc, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0, "setsockopt(IP_PKTINFO)",
|
ERROR_IF_FUNC(setsockopt(socketDesc, SOL_IP, IP_PKTINFO, &yes, sizeof(yes)) < 0, "setsockopt(IP_PKTINFO)",
|
||||||
CloseSocket(), return false);
|
CloseSocket(), return false);
|
||||||
|
#endif // __FreeBSD__
|
||||||
// Bind socket
|
// Bind socket
|
||||||
memset(&sockAddr, '\0', sizeof(sockAddr));
|
memset(&sockAddr, '\0', sizeof(sockAddr));
|
||||||
sockAddr.sin_family = AF_INET;
|
sockAddr.sin_family = AF_INET;
|
||||||
@ -180,11 +182,13 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
|
#ifndef __FreeBSD__
|
||||||
// Process auxiliary received data and validate source address
|
// Process auxiliary received data and validate source address
|
||||||
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
|
for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg != NULL; cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
|
||||||
if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
|
if ((cmsg->cmsg_level == SOL_IP) && (cmsg->cmsg_type == IP_PKTINFO)) {
|
||||||
struct in_pktinfo *i = (struct in_pktinfo *)CMSG_DATA(cmsg);
|
struct in_pktinfo *i = (struct in_pktinfo *)CMSG_DATA(cmsg);
|
||||||
if ((i->ipi_addr.s_addr == streamAddr) || (INADDR_ANY == streamAddr)) {
|
if ((i->ipi_addr.s_addr == streamAddr) || (INADDR_ANY == streamAddr)) {
|
||||||
|
#endif // __FreeBSD__
|
||||||
if (BufferAddr[0] == TS_SYNC_BYTE)
|
if (BufferAddr[0] == TS_SYNC_BYTE)
|
||||||
return len;
|
return len;
|
||||||
else if (len > 3) {
|
else if (len > 3) {
|
||||||
@ -215,9 +219,11 @@ int cIptvUdpSocket::Read(unsigned char* BufferAddr, unsigned int BufferLen)
|
|||||||
return (len - headerlen);
|
return (len - headerlen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef __FreeBSD__
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // __FreeBSD__
|
||||||
}
|
}
|
||||||
} while (len > 0);
|
} while (len > 0);
|
||||||
ERROR_IF_RET(len < 0 && errno != EAGAIN, "recvmsg()", return -1);
|
ERROR_IF_RET(len < 0 && errno != EAGAIN, "recvmsg()", return -1);
|
||||||
|
Loading…
Reference in New Issue
Block a user