1
0
mirror of https://github.com/VDR4Arch/vdr.git synced 2023-10-10 13:36:52 +02:00

Pipe to Dolby Digital replay command closes all unused file descriptors to avoid crashing when OSD is on

This commit is contained in:
Klaus Schmidinger 2001-09-15 13:00:58 +02:00
parent 37754870e0
commit 7913b00daa
5 changed files with 134 additions and 11 deletions

View File

@ -106,7 +106,7 @@ Stefan Huelswitt <huels@iname.com>
Ulrich Röder <dynamite@efr-net.de> Ulrich Röder <dynamite@efr-net.de>
for pointing out that there are channels that have a symbol rate higher than for pointing out that there are channels that have a symbol rate higher than
27500. 27500
Helmut Schächner <schaechner@yahoo.com> Helmut Schächner <schaechner@yahoo.com>
for his support in keeping the Premiere World channels up to date in 'channels.conf' for his support in keeping the Premiere World channels up to date in 'channels.conf'
@ -135,3 +135,7 @@ Werner Fink <werner@suse.de>
Rolf Hakenes <hakenes@hippomi.de> Rolf Hakenes <hakenes@hippomi.de>
for providing 'libdtv' and adapting the EIT mechanisms to it for providing 'libdtv' and adapting the EIT mechanisms to it
Andreas Vitting <Andreas@huji.de>
for providing code that closes all unused file descriptors in the child
process of a pipe (used in cPipe)

View File

@ -716,7 +716,7 @@ Video Disk Recorder Revision History
That way every recording will store the actual summary data at the time of That way every recording will store the actual summary data at the time of
the recording. the recording.
2001-09-14: Version 0.95 2001-09-15: Version 0.95
- Fixed behaviour in case the shutdown didn't take place (there were many - Fixed behaviour in case the shutdown didn't take place (there were many
"next timer event at..." messages in that case). "next timer event at..." messages in that case).
@ -742,3 +742,6 @@ Video Disk Recorder Revision History
- Changed the size of all input buffers used to parse config files or receive - Changed the size of all input buffers used to parse config files or receive
SVDRP commands to the same value of 10KB. This allows long strings to be SVDRP commands to the same value of 10KB. This allows long strings to be
used in the 'summary' field of a timer, for instance. used in the 'summary' field of a timer, for instance.
- The pipe to the Dolby Digital replay command (option '-a') now closes all
unused file descriptors in the child process to avoid crashing when the
OSD is used (thanks to Andreas Vitting).

View File

@ -7,7 +7,7 @@
* DVD support initially written by Andreas Schultz <aschultz@warp10.net> * DVD support initially written by Andreas Schultz <aschultz@warp10.net>
* based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si> * based on dvdplayer-0.5 by Matjaz Thaler <matjaz.thaler@guest.arnes.si>
* *
* $Id: dvbapi.c 1.118 2001/09/15 10:42:35 kls Exp $ * $Id: dvbapi.c 1.119 2001/09/15 12:45:19 kls Exp $
*/ */
//#define DVDDEBUG 1 //#define DVDDEBUG 1
@ -693,7 +693,7 @@ protected:
static int Speeds[]; static int Speeds[];
cDvbApi *dvbApi; cDvbApi *dvbApi;
int videoDev, audioDev; int videoDev, audioDev;
FILE *dolbyDev; cPipe dolbyDev;
int blockInput, blockOutput; int blockInput, blockOutput;
ePlayModes playMode; ePlayModes playMode;
ePlayDirs playDir; ePlayDirs playDir;
@ -733,7 +733,6 @@ cPlayBuffer::cPlayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev)
dvbApi = DvbApi; dvbApi = DvbApi;
videoDev = VideoDev; videoDev = VideoDev;
audioDev = AudioDev; audioDev = AudioDev;
dolbyDev = NULL;
blockInput = blockOutput = false; blockInput = blockOutput = false;
playMode = pmPlay; playMode = pmPlay;
playDir = pdForward; playDir = pdForward;
@ -743,16 +742,13 @@ cPlayBuffer::cPlayBuffer(cDvbApi *DvbApi, int VideoDev, int AudioDev)
canToggleAudioTrack = false; canToggleAudioTrack = false;
audioTrack = 0xC0; audioTrack = 0xC0;
if (cDvbApi::AudioCommand()) { if (cDvbApi::AudioCommand()) {
dolbyDev = popen(cDvbApi::AudioCommand(), "w"); if (!dolbyDev.Open(cDvbApi::AudioCommand(), "w"))
if (!dolbyDev)
esyslog(LOG_ERR, "ERROR: can't open pipe to audio command '%s'", cDvbApi::AudioCommand()); esyslog(LOG_ERR, "ERROR: can't open pipe to audio command '%s'", cDvbApi::AudioCommand());
} }
} }
cPlayBuffer::~cPlayBuffer() cPlayBuffer::~cPlayBuffer()
{ {
if (dolbyDev)
pclose(dolbyDev);
} }
void cPlayBuffer::Output(void) void cPlayBuffer::Output(void)

106
thread.c
View File

@ -4,12 +4,13 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: thread.c 1.11 2001/08/05 10:36:52 kls Exp $ * $Id: thread.c 1.12 2001/09/15 13:00:58 kls Exp $
*/ */
#include "thread.h" #include "thread.h"
#include <errno.h> #include <errno.h>
#include <signal.h> #include <signal.h>
#include <sys/resource.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <unistd.h> #include <unistd.h>
#include "tools.h" #include "tools.h"
@ -235,3 +236,106 @@ bool cThreadLock::Locked(void)
return locked; return locked;
} }
// --- cPipe -----------------------------------------------------------------
// cPipe::Open() and cPipe::Close() are based on code originally received from
// Andreas Vitting <Andreas@huji.de>
cPipe::cPipe(void)
{
pid = -1;
f = NULL;
}
cPipe::~cPipe()
{
Close();
}
bool cPipe::Open(const char *Command, const char *Mode)
{
int fd[2];
if (pipe(fd) < 0) {
LOG_ERROR;
return false;
}
if ((pid = fork()) < 0) { // fork failed
LOG_ERROR;
close(fd[0]);
close(fd[1]);
return false;
}
char *mode = "w";
int iopipe = 0;
if (pid > 0) { // parent process
if (strcmp(Mode, "r") == 0) {
mode = "r";
iopipe = 1;
}
close(fd[iopipe]);
f = fdopen(fd[1 - iopipe], mode);
if ((f = fdopen(fd[1 - iopipe], mode)) == NULL) {
LOG_ERROR;
close(fd[1 - iopipe]);
}
return f != NULL;
}
else { // child process
int iofd = STDOUT_FILENO;
if (strcmp(Mode, "w") == 0) {
mode = "r";
iopipe = 1;
iofd = STDIN_FILENO;
}
close(fd[iopipe]);
if (dup2(fd[1 - iopipe], iofd) == -1) { // now redirect
LOG_ERROR;
close(fd[1 - iopipe]);
_exit(-1);
}
else {
for (int i = STDERR_FILENO + 1; i < fd[1 - iopipe]; i++)
close(i); //close all dup'ed filedescriptors
if (execl("/bin/sh", "sh", "-c", Command, NULL) == -1) {
LOG_ERROR_STR(Command);
close(fd[1 - iopipe]);
_exit(-1);
}
}
_exit(0);
}
}
int cPipe::Close(void)
{
int ret = -1;
if (f) {
fclose(f);
f = NULL;
}
if (pid >= 0) {
int status = 0;
struct rusage ru;
int i = 5;
while (ret == -1 && i > 0) {
usleep(1000);
ret = wait4(pid, &status, WNOHANG, &ru);
i--;
}
if (!i) {
kill(pid, SIGKILL);
ret = -1;
}
else if (ret == -1 || !WIFEXITED(status))
ret = -1;
pid = -1;
}
return ret;
}

View File

@ -4,13 +4,14 @@
* See the main source file 'vdr.c' for copyright information and * See the main source file 'vdr.c' for copyright information and
* how to reach the author. * how to reach the author.
* *
* $Id: thread.h 1.8 2001/08/05 10:36:47 kls Exp $ * $Id: thread.h 1.9 2001/09/15 12:46:52 kls Exp $
*/ */
#ifndef __THREAD_H #ifndef __THREAD_H
#define __THREAD_H #define __THREAD_H
#include <pthread.h> #include <pthread.h>
#include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
class cMutex; class cMutex;
@ -88,4 +89,19 @@ public:
#define LOCK_THREAD cThreadLock ThreadLock(this) #define LOCK_THREAD cThreadLock ThreadLock(this)
// cPipe implements a pipe that closes all unnecessary file descriptors in
// the child process.
class cPipe {
private:
pid_t pid;
FILE *f;
public:
cPipe(void);
~cPipe();
operator FILE* () { return f; }
bool Open(const char *Command, const char *Mode);
int Close(void);
};
#endif //__THREAD_H #endif //__THREAD_H