mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Switched to PES recording
This commit is contained in:
parent
c8a1be81af
commit
6b0658a977
9
HISTORY
9
HISTORY
@ -312,8 +312,15 @@ Video Disk Recorder Revision History
|
||||
an early state and may still cause some problems, but it appears to work nice
|
||||
already.
|
||||
|
||||
2000-12-01: Version 0.69
|
||||
2000-12-08: Version 0.70
|
||||
|
||||
- VDR now requires driver version 0.80 or higher.
|
||||
- Recordings are now saved in PES mode. Note that you now need to install the
|
||||
driver *WITHOUT* 'outstream=0'! This is the default when you 'make insmod' in
|
||||
the DVB/driver directory.
|
||||
Old recordings (in AV_PES mode) can still be replayed (as long as the driver
|
||||
still supports replaying AV_PES files). The only limitation with this is that
|
||||
in fast forward/back mode the picture may be slightly distorted.
|
||||
- The EPG data is now dumped into the file /video/epg.data every ten minutes.
|
||||
Use the Perl script 'epg2html.pl' to convert the raw EPG data into a simple
|
||||
HTML programme listing.
|
||||
|
12
INSTALL
12
INSTALL
@ -15,13 +15,11 @@ If you have the DVB driver source in a different location
|
||||
you will have to change the definition of DVBDIR in the
|
||||
Makefile.
|
||||
|
||||
This program requires the card driver version 0.71 or higher
|
||||
to work properly. Currently you need to load the dvb.o module with
|
||||
option outstream=0, so your insmod statement should read
|
||||
'insmod dvb.o outstream=0'. This is necessary because 'vdr' works
|
||||
with AV_PES data and will change once it has been modified to work
|
||||
directly with MPEG2. You also need to apply the patch 'dvb.c.071.diff'
|
||||
for the On Screen Display to work properly.
|
||||
This program requires the card driver version 0.80 or higher
|
||||
to work properly. You need to load the dvb.o module *without* option
|
||||
'outstream=0' (previous versions of VDR required this option to have
|
||||
the driver supply the data in AV_PES format; as of version 0.70 VDR
|
||||
works with PES format).
|
||||
|
||||
After extracting the package, change into the VDR directory
|
||||
and type 'make'. This should produce an executable file
|
||||
|
6
Makefile
6
Makefile
@ -4,7 +4,7 @@
|
||||
# See the main source file 'vdr.c' for copyright information and
|
||||
# how to reach the author.
|
||||
#
|
||||
# $Id: Makefile 1.16 2000/11/18 14:58:10 kls Exp $
|
||||
# $Id: Makefile 1.17 2000/12/03 15:24:20 kls Exp $
|
||||
|
||||
DVBDIR = ../DVB
|
||||
|
||||
@ -39,7 +39,7 @@ font: genfontfile fontfix.c fontosd.c
|
||||
config.o : config.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h remote.h svdrp.h thread.h tools.h
|
||||
dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h videodir.h
|
||||
dvbosd.o : dvbosd.c dvbosd.h font.h tools.h
|
||||
eit.o : eit.c eit.h thread.h tools.h
|
||||
eit.o : eit.c config.h dvbapi.h dvbosd.h eit.h font.h thread.h tools.h videodir.h
|
||||
font.o : font.c font.h fontfix.c fontosd.c tools.h
|
||||
i18n.o : i18n.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h thread.h tools.h
|
||||
interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h remote.h svdrp.h thread.h tools.h
|
||||
@ -48,7 +48,7 @@ osd.o : osd.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h os
|
||||
recording.o: recording.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h recording.h remote.h svdrp.h thread.h tools.h videodir.h
|
||||
remote.o : remote.c config.h dvbapi.h dvbosd.h eit.h font.h remote.h thread.h tools.h
|
||||
svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h
|
||||
thread.o : thread.c thread.h
|
||||
thread.o : thread.c thread.h tools.h
|
||||
tools.o : tools.c tools.h
|
||||
vdr.o : vdr.c config.h dvbapi.h dvbosd.h eit.h font.h i18n.h interface.h menu.h osd.h recording.h remote.h svdrp.h thread.h tools.h videodir.h
|
||||
videodir.o : videodir.c tools.h videodir.h
|
||||
|
4
config.h
4
config.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: config.h 1.34 2000/11/18 13:25:53 kls Exp $
|
||||
* $Id: config.h 1.35 2000/12/08 13:57:23 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
@ -18,7 +18,7 @@
|
||||
#include "eit.h"
|
||||
#include "tools.h"
|
||||
|
||||
#define VDRVERSION "0.68"
|
||||
#define VDRVERSION "0.70"
|
||||
|
||||
#define MaxBuffer 10000
|
||||
|
||||
|
22
dvbapi.h
22
dvbapi.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: dvbapi.h 1.26 2000/11/19 14:09:41 kls Exp $
|
||||
* $Id: dvbapi.h 1.27 2000/12/03 13:44:28 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __DVBAPI_H
|
||||
@ -42,6 +42,8 @@ public:
|
||||
bool Save(int Index);
|
||||
};
|
||||
|
||||
class cRecordBuffer;
|
||||
class cReplayBuffer;
|
||||
class cTransferBuffer;
|
||||
|
||||
class cDvbApi {
|
||||
@ -171,20 +173,10 @@ private:
|
||||
// Record/Replay facilities
|
||||
|
||||
private:
|
||||
enum { dvbStop = 1, // let's not have 0 as a command
|
||||
dvbPause,
|
||||
dvbPlay,
|
||||
dvbForward,
|
||||
dvbBackward,
|
||||
dvbSkip,
|
||||
dvbGetIndex,
|
||||
};
|
||||
pid_t pidRecord, pidReplay;
|
||||
int fromRecord, toRecord;
|
||||
int fromReplay, toReplay;
|
||||
cRecordBuffer *recordBuffer;
|
||||
cReplayBuffer *replayBuffer;
|
||||
int ca;
|
||||
int priority;
|
||||
void SetReplayMode(int Mode);
|
||||
protected:
|
||||
int Ca(void) { return ca; }
|
||||
// Returns the ca of the current recording session (0..MAXDVBAPI).
|
||||
@ -214,7 +206,7 @@ public:
|
||||
// If there is already a replay session active, it will be stopped
|
||||
// and the new file will be played back.
|
||||
// If provided Title will be used in the progress display.
|
||||
void Stop(void);
|
||||
void StopReplay(void);
|
||||
// Stops the current replay session (if any).
|
||||
void Pause(void);
|
||||
// Pauses the current replay session, or resumes a paused session.
|
||||
@ -229,7 +221,7 @@ public:
|
||||
// The sign of 'Seconds' determines the direction in which to skip.
|
||||
// Use a very large negative value to go all the way back to the
|
||||
// beginning of the recording.
|
||||
bool GetIndex(int *Current, int *Total = NULL);
|
||||
bool GetIndex(int &Current, int &Total);
|
||||
};
|
||||
|
||||
class cEITScanner {
|
||||
|
6
eit.c
6
eit.c
@ -13,7 +13,7 @@
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* $Id: eit.c 1.10 2000/11/25 12:51:06 kls Exp $
|
||||
* $Id: eit.c 1.11 2000/12/03 15:33:37 kls Exp $
|
||||
***************************************************************************/
|
||||
|
||||
#include "eit.h"
|
||||
@ -131,7 +131,7 @@ bool cMJD::SetSystemTime()
|
||||
isyslog(LOG_INFO, "System Time = %s (%ld)\n", ctime(&loctim), loctim);
|
||||
isyslog(LOG_INFO, "Local Time = %s (%ld)\n", ctime(&mjdtime), mjdtime);
|
||||
if (stime(&mjdtime) < 0)
|
||||
esyslog(LOG_ERR, "ERROR while setting system time: %s", strerror(errno));
|
||||
esyslog(LOG_ERR, "ERROR while setting system time: %m");
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1117,7 +1117,7 @@ cSIProcessor::~cSIProcessor()
|
||||
{
|
||||
if (fsvbi >= 0)
|
||||
{
|
||||
Stop();
|
||||
Cancel();
|
||||
ShutDownFilters();
|
||||
delete filters;
|
||||
if (!--numSIProcessors) // the last one deletes it
|
||||
|
6
menu.c
6
menu.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: menu.c 1.53 2000/11/26 16:15:30 kls Exp $
|
||||
* $Id: menu.c 1.54 2000/12/03 11:43:35 kls Exp $
|
||||
*/
|
||||
|
||||
#include "menu.h"
|
||||
@ -2009,7 +2009,7 @@ cReplayControl::cReplayControl(void)
|
||||
cReplayControl::~cReplayControl()
|
||||
{
|
||||
Hide();
|
||||
dvbApi->Stop();
|
||||
dvbApi->StopReplay();
|
||||
}
|
||||
|
||||
void cReplayControl::SetRecording(const char *FileName, const char *Title)
|
||||
@ -2060,7 +2060,7 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
|
||||
case kUp: dvbApi->Play(); break;
|
||||
case kDown: dvbApi->Pause(); break;
|
||||
case kBlue: Hide();
|
||||
dvbApi->Stop();
|
||||
dvbApi->StopReplay();
|
||||
return osEnd;
|
||||
case kLeft: dvbApi->Backward(); break;
|
||||
case kRight: dvbApi->Forward(); break;
|
||||
|
6
remote.c
6
remote.c
@ -6,7 +6,7 @@
|
||||
*
|
||||
* Ported to LIRC by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
|
||||
*
|
||||
* $Id: remote.c 1.19 2000/11/11 11:22:22 kls Exp $
|
||||
* $Id: remote.c 1.20 2000/12/03 11:55:06 kls Exp $
|
||||
*/
|
||||
|
||||
#include "remote.h"
|
||||
@ -115,7 +115,7 @@ cRcIoRCU::cRcIoRCU(char *DeviceName)
|
||||
|
||||
cRcIoRCU::~cRcIoRCU()
|
||||
{
|
||||
Stop();
|
||||
Cancel();
|
||||
}
|
||||
|
||||
void cRcIoRCU::Action(void)
|
||||
@ -420,7 +420,7 @@ cRcIoLIRC::cRcIoLIRC(char *DeviceName)
|
||||
|
||||
cRcIoLIRC::~cRcIoLIRC()
|
||||
{
|
||||
Stop();
|
||||
Cancel();
|
||||
}
|
||||
|
||||
void cRcIoLIRC::Action(void)
|
||||
|
3
svdrp.c
3
svdrp.c
@ -10,7 +10,7 @@
|
||||
* and interact with the Video Disk Recorder - or write a full featured
|
||||
* graphical interface that sits on top of an SVDRP connection.
|
||||
*
|
||||
* $Id: svdrp.c 1.12 2000/11/05 13:44:42 kls Exp $
|
||||
* $Id: svdrp.c 1.13 2000/12/03 15:34:35 kls Exp $
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
@ -18,6 +18,7 @@
|
||||
#include "svdrp.h"
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdarg.h>
|
||||
|
33
thread.c
33
thread.c
@ -4,12 +4,15 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: thread.c 1.5 2000/11/22 17:11:04 kls Exp $
|
||||
* $Id: thread.c 1.6 2000/12/03 15:35:02 kls Exp $
|
||||
*/
|
||||
|
||||
#include "thread.h"
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include "tools.h"
|
||||
|
||||
// --- cThread ---------------------------------------------------------------
|
||||
|
||||
@ -25,7 +28,7 @@ cThread::cThread(void)
|
||||
signalHandlerInstalled = true;
|
||||
}
|
||||
running = false;
|
||||
parentPid = lockingPid = 0;
|
||||
parentPid = threadPid = lockingPid = 0;
|
||||
locked = 0;
|
||||
}
|
||||
|
||||
@ -40,6 +43,7 @@ void cThread::SignalHandler(int signum)
|
||||
|
||||
void *cThread::StartThread(cThread *Thread)
|
||||
{
|
||||
Thread->threadPid = getpid();
|
||||
Thread->Action();
|
||||
return NULL;
|
||||
}
|
||||
@ -54,8 +58,31 @@ bool cThread::Start(void)
|
||||
return true; //XXX return value of pthread_create()???
|
||||
}
|
||||
|
||||
void cThread::Stop(void)
|
||||
bool cThread::Active(void)
|
||||
{
|
||||
if (threadPid) {
|
||||
if (kill(threadPid, SIGIO) < 0) { // couldn't find another way of checking whether the thread is still running - any ideas?
|
||||
if (errno == ESRCH)
|
||||
threadPid = 0;
|
||||
else
|
||||
LOG_ERROR;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void cThread::Cancel(int WaitSeconds)
|
||||
{
|
||||
if (WaitSeconds > 0) {
|
||||
for (time_t t0 = time(NULL) + WaitSeconds; time(NULL) < t0; ) {
|
||||
if (!Active())
|
||||
return;
|
||||
usleep(10000);
|
||||
}
|
||||
esyslog(LOG_ERR, "ERROR: thread %d won't end (waited %d seconds) - cancelling it...", threadPid, WaitSeconds);
|
||||
}
|
||||
pthread_cancel(thread);
|
||||
}
|
||||
|
||||
|
7
thread.h
7
thread.h
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: thread.h 1.3 2000/11/14 18:38:11 kls Exp $
|
||||
* $Id: thread.h 1.4 2000/12/03 11:18:37 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __THREAD_H
|
||||
@ -28,7 +28,7 @@ class cThread {
|
||||
private:
|
||||
pthread_t thread;
|
||||
cMutex Mutex;
|
||||
pid_t parentPid, lockingPid;
|
||||
pid_t parentPid, threadPid, lockingPid;
|
||||
int locked;
|
||||
bool running;
|
||||
static bool signalHandlerInstalled;
|
||||
@ -39,11 +39,12 @@ private:
|
||||
protected:
|
||||
void WakeUp(void);
|
||||
virtual void Action(void) = 0;
|
||||
void Stop(void);
|
||||
void Cancel(int WaitSeconds = 0);
|
||||
public:
|
||||
cThread(void);
|
||||
virtual ~cThread();
|
||||
bool Start(void);
|
||||
bool Active(void);
|
||||
};
|
||||
|
||||
// cThreadLock can be used to easily set a lock in a thread and make absolutely
|
||||
|
65
tools.c
65
tools.c
@ -4,7 +4,7 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.c 1.23 2000/11/11 15:17:12 kls Exp $
|
||||
* $Id: tools.c 1.24 2000/12/03 15:39:11 kls Exp $
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
@ -15,10 +15,7 @@
|
||||
#if defined(DEBUG_OSD)
|
||||
#include <ncurses.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define MaxBuffer 1000
|
||||
@ -30,29 +27,6 @@ void writechar(int filedes, char c)
|
||||
write(filedes, &c, sizeof(c));
|
||||
}
|
||||
|
||||
void writeint(int filedes, int n)
|
||||
{
|
||||
write(filedes, &n, sizeof(n));
|
||||
}
|
||||
|
||||
char readchar(int filedes)
|
||||
{
|
||||
char c;
|
||||
read(filedes, &c, 1);
|
||||
return c;
|
||||
}
|
||||
|
||||
bool readint(int filedes, int &n)
|
||||
{
|
||||
return cFile::AnyFileReady(filedes, 0) && read(filedes, &n, sizeof(n)) == sizeof(n);
|
||||
}
|
||||
|
||||
void purge(int filedes)
|
||||
{
|
||||
while (cFile::AnyFileReady(filedes, 0))
|
||||
readchar(filedes);
|
||||
}
|
||||
|
||||
char *readline(FILE *f)
|
||||
{
|
||||
static char buffer[MaxBuffer];
|
||||
@ -205,7 +179,7 @@ bool MakeDirs(const char *FileName, bool IsDirectory)
|
||||
if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
|
||||
dsyslog(LOG_INFO, "creating directory %s", s);
|
||||
if (mkdir(s, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) {
|
||||
esyslog(LOG_ERR, "ERROR: %s: %s", s, strerror(errno));
|
||||
LOG_ERROR_STR(s);
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
@ -271,41 +245,6 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckProcess(pid_t pid)
|
||||
{
|
||||
pid_t Pid2Check = pid;
|
||||
int status;
|
||||
pid = waitpid(Pid2Check, &status, WNOHANG);
|
||||
if (pid < 0) {
|
||||
if (errno != ECHILD)
|
||||
LOG_ERROR;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void KillProcess(pid_t pid, int Timeout)
|
||||
{
|
||||
pid_t Pid2Wait4 = pid;
|
||||
for (time_t t0 = time(NULL); time(NULL) - t0 < Timeout; ) {
|
||||
int status;
|
||||
pid_t pid = waitpid(Pid2Wait4, &status, WNOHANG);
|
||||
if (pid < 0) {
|
||||
if (errno != ECHILD)
|
||||
LOG_ERROR;
|
||||
return;
|
||||
}
|
||||
if (pid == Pid2Wait4)
|
||||
return;
|
||||
}
|
||||
esyslog(LOG_ERR, "ERROR: process %d won't end (waited %d seconds) - terminating it...", Pid2Wait4, Timeout);
|
||||
if (kill(Pid2Wait4, SIGTERM) < 0) {
|
||||
esyslog(LOG_ERR, "ERROR: process %d won't terminate (%s) - killing it...", Pid2Wait4, strerror(errno));
|
||||
if (kill(Pid2Wait4, SIGKILL) < 0)
|
||||
esyslog(LOG_ERR, "ERROR: process %d won't die (%s) - giving up", Pid2Wait4, strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
// --- cFile -----------------------------------------------------------------
|
||||
|
||||
bool cFile::files[FD_SETSIZE] = { false };
|
||||
|
15
tools.h
15
tools.h
@ -4,13 +4,13 @@
|
||||
* See the main source file 'vdr.c' for copyright information and
|
||||
* how to reach the author.
|
||||
*
|
||||
* $Id: tools.h 1.20 2000/11/12 15:27:06 kls Exp $
|
||||
* $Id: tools.h 1.21 2000/12/03 15:32:54 kls Exp $
|
||||
*/
|
||||
|
||||
#ifndef __TOOLS_H
|
||||
#define __TOOLS_H
|
||||
|
||||
#include <errno.h>
|
||||
//#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -24,19 +24,14 @@ extern int SysLogLevel;
|
||||
#define isyslog if (SysLogLevel > 1) syslog
|
||||
#define dsyslog if (SysLogLevel > 2) syslog
|
||||
|
||||
#define LOG_ERROR esyslog(LOG_ERR, "ERROR (%s,%d): %s", __FILE__, __LINE__, strerror(errno))
|
||||
#define LOG_ERROR_STR(s) esyslog(LOG_ERR, "ERROR: %s: %s", s, strerror(errno));
|
||||
#define LOG_ERROR esyslog(LOG_ERR, "ERROR (%s,%d): %m", __FILE__, __LINE__)
|
||||
#define LOG_ERROR_STR(s) esyslog(LOG_ERR, "ERROR: %s: %m", s)
|
||||
|
||||
#define SECSINDAY 86400
|
||||
#define MAXPROCESSTIMEOUT 3 // seconds
|
||||
|
||||
#define DELETENULL(p) (delete (p), p = NULL)
|
||||
|
||||
void writechar(int filedes, char c);
|
||||
void writeint(int filedes, int n);
|
||||
char readchar(int filedes);
|
||||
bool readint(int filedes, int &n);
|
||||
void purge(int filedes);
|
||||
char *readline(FILE *f);
|
||||
char *strn0cpy(char *dest, const char *src, size_t n);
|
||||
char *strreplace(char *s, char c1, char c2);
|
||||
@ -51,8 +46,6 @@ uint FreeDiskSpaceMB(const char *Directory);
|
||||
bool DirectoryOk(const char *DirName, bool LogErrors = false);
|
||||
bool MakeDirs(const char *FileName, bool IsDirectory = false);
|
||||
bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks = false);
|
||||
bool CheckProcess(pid_t pid);
|
||||
void KillProcess(pid_t pid, int Timeout = MAXPROCESSTIMEOUT);
|
||||
|
||||
class cFile {
|
||||
private:
|
||||
|
6
vdr.c
6
vdr.c
@ -22,7 +22,7 @@
|
||||
*
|
||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
||||
*
|
||||
* $Id: vdr.c 1.46 2000/11/18 13:46:56 kls Exp $
|
||||
* $Id: vdr.c 1.47 2000/12/03 15:36:46 kls Exp $
|
||||
*/
|
||||
|
||||
#include <getopt.h>
|
||||
@ -141,8 +141,8 @@ int main(int argc, char *argv[])
|
||||
#if !defined(DEBUG_OSD) && !defined(REMOTE_KBD)
|
||||
pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
fprintf(stderr, "%s\n", strerror(errno));
|
||||
esyslog(LOG_ERR, "ERROR: %s", strerror(errno));
|
||||
fprintf(stderr, "%m\n");
|
||||
esyslog(LOG_ERR, "ERROR: %m");
|
||||
abort();
|
||||
}
|
||||
if (pid != 0)
|
||||
|
Loading…
Reference in New Issue
Block a user