mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Made I/O more robust by handling EINTR
This commit is contained in:
parent
0ac6edbfc6
commit
000ce0cf21
@ -126,3 +126,6 @@ Matjaz Thaler <matjaz.thaler@guest.arnes.si>
|
|||||||
|
|
||||||
Artur Skawina <skawina@geocities.com>
|
Artur Skawina <skawina@geocities.com>
|
||||||
for improving the font file generation in the Makefile
|
for improving the font file generation in the Makefile
|
||||||
|
|
||||||
|
Werner Fink <werner@suse.de>
|
||||||
|
for making I/O more robust by handling EINTR
|
||||||
|
3
HISTORY
3
HISTORY
@ -622,7 +622,7 @@ Video Disk Recorder Revision History
|
|||||||
- Fixed calculating the timeout value in cFile::FileReady() (thanks to
|
- Fixed calculating the timeout value in cFile::FileReady() (thanks to
|
||||||
Wolfgang Henselmann-Weiss).
|
Wolfgang Henselmann-Weiss).
|
||||||
|
|
||||||
2001-08-11: Version 0.91
|
2001-08-12: Version 0.91
|
||||||
|
|
||||||
- Fixed displaying colored button texts that are too long.
|
- Fixed displaying colored button texts that are too long.
|
||||||
- Suppressing replay progress display when replaying a DVD.
|
- Suppressing replay progress display when replaying a DVD.
|
||||||
@ -648,3 +648,4 @@ Video Disk Recorder Revision History
|
|||||||
- Fixed displaying editing marks when toggling a mark in "pause" mode.
|
- Fixed displaying editing marks when toggling a mark in "pause" mode.
|
||||||
- If there is no free DVB device to record, the log message will now be given
|
- If there is no free DVB device to record, the log message will now be given
|
||||||
only once.
|
only once.
|
||||||
|
- Made I/O more robust by handling EINTR (thanks to Werner Fink).
|
||||||
|
29
dvbapi.c
29
dvbapi.c
@ -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.105 2001/08/11 12:21:49 kls Exp $
|
* $Id: dvbapi.c 1.106 2001/08/12 15:09:42 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define DVDDEBUG 1
|
//#define DVDDEBUG 1
|
||||||
@ -82,6 +82,8 @@ extern "C" {
|
|||||||
|
|
||||||
#define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
|
#define CHECK(s) { if ((s) < 0) LOG_ERROR; } // used for 'ioctl()' calls
|
||||||
|
|
||||||
|
#define FATALERRNO (errno != EAGAIN && errno != EINTR)
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
|
|
||||||
const char *IndexToHMSF(int Index, bool WithFrame)
|
const char *IndexToHMSF(int Index, bool WithFrame)
|
||||||
@ -158,7 +160,7 @@ cIndexFile::cIndexFile(const char *FileName, bool Record)
|
|||||||
if (index) {
|
if (index) {
|
||||||
f = open(fileName, O_RDONLY);
|
f = open(fileName, O_RDONLY);
|
||||||
if (f >= 0) {
|
if (f >= 0) {
|
||||||
if ((int)read(f, index, buf.st_size) != buf.st_size) {
|
if ((int)safe_read(f, index, buf.st_size) != buf.st_size) {
|
||||||
esyslog(LOG_ERR, "ERROR: can't read from file '%s'", fileName);
|
esyslog(LOG_ERR, "ERROR: can't read from file '%s'", fileName);
|
||||||
delete index;
|
delete index;
|
||||||
index = NULL;
|
index = NULL;
|
||||||
@ -222,7 +224,7 @@ bool cIndexFile::CatchUp(void)
|
|||||||
int offset = (last + 1) * sizeof(tIndex);
|
int offset = (last + 1) * sizeof(tIndex);
|
||||||
int delta = (newLast - last) * sizeof(tIndex);
|
int delta = (newLast - last) * sizeof(tIndex);
|
||||||
if (lseek(f, offset, SEEK_SET) == offset) {
|
if (lseek(f, offset, SEEK_SET) == offset) {
|
||||||
if (read(f, &index[last + 1], delta) != delta) {
|
if (safe_read(f, &index[last + 1], delta) != delta) {
|
||||||
esyslog(LOG_ERR, "ERROR: can't read from index");
|
esyslog(LOG_ERR, "ERROR: can't read from index");
|
||||||
delete index;
|
delete index;
|
||||||
index = NULL;
|
index = NULL;
|
||||||
@ -249,7 +251,7 @@ void cIndexFile::Write(uchar PictureType, uchar FileNumber, int FileOffset)
|
|||||||
{
|
{
|
||||||
if (f >= 0) {
|
if (f >= 0) {
|
||||||
tIndex i = { FileOffset, PictureType, FileNumber, 0 };
|
tIndex i = { FileOffset, PictureType, FileNumber, 0 };
|
||||||
if (write(f, &i, sizeof(i)) != sizeof(i)) {
|
if (safe_write(f, &i, sizeof(i)) != sizeof(i)) {
|
||||||
esyslog(LOG_ERR, "ERROR: can't write to index file");
|
esyslog(LOG_ERR, "ERROR: can't write to index file");
|
||||||
close(f);
|
close(f);
|
||||||
f = -1;
|
f = -1;
|
||||||
@ -542,7 +544,7 @@ void cRecordBuffer::Input(void)
|
|||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
}
|
}
|
||||||
else if (r < 0) {
|
else if (r < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (FATALERRNO) {
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
if (errno != EBUFFEROVERFLOW)
|
if (errno != EBUFFEROVERFLOW)
|
||||||
break;
|
break;
|
||||||
@ -569,8 +571,9 @@ void cRecordBuffer::Output(void)
|
|||||||
int r = 0;
|
int r = 0;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int g = Get(b + r, sizeof(b) - r);
|
int g = Get(b + r, sizeof(b) - r);
|
||||||
if (g > 0) {
|
if (g > 0)
|
||||||
r += g;
|
r += g;
|
||||||
|
if (r > 0) {
|
||||||
int Count = r, Result;
|
int Count = r, Result;
|
||||||
const uchar *p = remux.Process(b, Count, Result, &pictureType);
|
const uchar *p = remux.Process(b, Count, Result, &pictureType);
|
||||||
if (p) {
|
if (p) {
|
||||||
@ -580,7 +583,7 @@ void cRecordBuffer::Output(void)
|
|||||||
if (index && pictureType != NO_PICTURE)
|
if (index && pictureType != NO_PICTURE)
|
||||||
index->Write(pictureType, fileName.Number(), fileSize);
|
index->Write(pictureType, fileName.Number(), fileSize);
|
||||||
while (Result > 0) {
|
while (Result > 0) {
|
||||||
int w = write(recordFile, p, Result);
|
int w = safe_write(recordFile, p, Result);
|
||||||
if (w < 0) {
|
if (w < 0) {
|
||||||
LOG_ERROR_STR(fileName.Name());
|
LOG_ERROR_STR(fileName.Name());
|
||||||
recording = false;
|
recording = false;
|
||||||
@ -619,7 +622,7 @@ int ReadFrame(int f, uchar *b, int Length, int Max)
|
|||||||
esyslog(LOG_ERR, "ERROR: frame larger than buffer (%d > %d)", Length, Max);
|
esyslog(LOG_ERR, "ERROR: frame larger than buffer (%d > %d)", Length, Max);
|
||||||
Length = Max;
|
Length = Max;
|
||||||
}
|
}
|
||||||
int r = read(f, b, Length);
|
int r = safe_read(f, b, Length);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
return r;
|
return r;
|
||||||
@ -705,7 +708,7 @@ void cPlayBuffer::Output(void)
|
|||||||
p += w;
|
p += w;
|
||||||
r -= w;
|
r -= w;
|
||||||
}
|
}
|
||||||
else if (w < 0 && errno != EAGAIN) {
|
else if (w < 0 && FATALERRNO) {
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
Stop();
|
Stop();
|
||||||
return;
|
return;
|
||||||
@ -922,7 +925,7 @@ void cReplayBuffer::Input(void)
|
|||||||
}
|
}
|
||||||
else if (r == 0)
|
else if (r == 0)
|
||||||
eof = true;
|
eof = true;
|
||||||
else if (r < 0 && errno != EAGAIN) {
|
else if (r < 0 && FATALERRNO) {
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2071,7 +2074,7 @@ void cTransferBuffer::Input(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (r < 0) {
|
else if (r < 0) {
|
||||||
if (errno != EAGAIN) {
|
if (FATALERRNO) {
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
if (errno != EBUFFEROVERFLOW)
|
if (errno != EBUFFEROVERFLOW)
|
||||||
break;
|
break;
|
||||||
@ -2105,7 +2108,7 @@ void cTransferBuffer::Output(void)
|
|||||||
p += w;
|
p += w;
|
||||||
r -= w;
|
r -= w;
|
||||||
}
|
}
|
||||||
else if (w < 0 && errno != EAGAIN) {
|
else if (w < 0 && FATALERRNO) {
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
Stop();
|
Stop();
|
||||||
return;
|
return;
|
||||||
@ -2214,7 +2217,7 @@ void cCuttingBuffer::Action(void)
|
|||||||
}
|
}
|
||||||
LastIFrame = 0;
|
LastIFrame = 0;
|
||||||
}
|
}
|
||||||
write(toFile, buffer, Length);
|
safe_write(toFile, buffer, Length);
|
||||||
toIndex->Write(PictureType, toFileName->Number(), FileSize);
|
toIndex->Write(PictureType, toFileName->Number(), FileSize);
|
||||||
FileSize += Length;
|
FileSize += Length;
|
||||||
if (!LastIFrame)
|
if (!LastIFrame)
|
||||||
|
6
eit.c
6
eit.c
@ -13,7 +13,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* $Id: eit.c 1.18 2001/08/11 14:51:28 kls Exp $
|
* $Id: eit.c 1.19 2001/08/12 15:04:37 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
@ -1229,11 +1229,11 @@ void cSIProcessor::Action()
|
|||||||
{
|
{
|
||||||
/* read section */
|
/* read section */
|
||||||
unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-)
|
unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-)
|
||||||
if (read(filters[a].handle, buf, 3) == 3)
|
if (safe_read(filters[a].handle, buf, 3) == 3)
|
||||||
{
|
{
|
||||||
int seclen = ((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF);
|
int seclen = ((buf[1] & 0x0F) << 8) | (buf[2] & 0xFF);
|
||||||
int pid = filters[a].pid;
|
int pid = filters[a].pid;
|
||||||
int n = read(filters[a].handle, buf + 3, seclen);
|
int n = safe_read(filters[a].handle, buf + 3, seclen);
|
||||||
if (n == seclen)
|
if (n == seclen)
|
||||||
{
|
{
|
||||||
seclen += 3;
|
seclen += 3;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* 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: recording.c 1.32 2001/06/16 10:33:20 kls Exp $
|
* $Id: recording.c 1.33 2001/08/12 15:09:59 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -141,7 +141,7 @@ int cResumeFile::Read(void)
|
|||||||
if (fileName) {
|
if (fileName) {
|
||||||
int f = open(fileName, O_RDONLY);
|
int f = open(fileName, O_RDONLY);
|
||||||
if (f >= 0) {
|
if (f >= 0) {
|
||||||
if (read(f, &resume, sizeof(resume)) != sizeof(resume)) {
|
if (safe_read(f, &resume, sizeof(resume)) != sizeof(resume)) {
|
||||||
resume = -1;
|
resume = -1;
|
||||||
LOG_ERROR_STR(fileName);
|
LOG_ERROR_STR(fileName);
|
||||||
}
|
}
|
||||||
@ -158,7 +158,7 @@ bool cResumeFile::Save(int Index)
|
|||||||
if (fileName) {
|
if (fileName) {
|
||||||
int f = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
int f = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
|
||||||
if (f >= 0) {
|
if (f >= 0) {
|
||||||
if (write(f, &Index, sizeof(Index)) != sizeof(Index))
|
if (safe_write(f, &Index, sizeof(Index)) != sizeof(Index))
|
||||||
LOG_ERROR_STR(fileName);
|
LOG_ERROR_STR(fileName);
|
||||||
close(f);
|
close(f);
|
||||||
return true;
|
return true;
|
||||||
@ -243,7 +243,7 @@ cRecording::cRecording(const char *FileName)
|
|||||||
int size = buf.st_size;
|
int size = buf.st_size;
|
||||||
summary = new char[size + 1]; // +1 for terminating 0
|
summary = new char[size + 1]; // +1 for terminating 0
|
||||||
if (summary) {
|
if (summary) {
|
||||||
int rbytes = read(f, summary, size);
|
int rbytes = safe_read(f, summary, size);
|
||||||
if (rbytes >= 0) {
|
if (rbytes >= 0) {
|
||||||
summary[rbytes] = 0;
|
summary[rbytes] = 0;
|
||||||
if (rbytes != size)
|
if (rbytes != size)
|
||||||
|
6
remote.c
6
remote.c
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Ported to LIRC by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
|
* Ported to LIRC by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
|
||||||
*
|
*
|
||||||
* $Id: remote.c 1.23 2001/07/27 10:17:19 kls Exp $
|
* $Id: remote.c 1.24 2001/08/12 15:07:26 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
@ -199,7 +199,7 @@ int cRcIoRCU::ReceiveByte(int TimeoutMs)
|
|||||||
// Returns the byte if one was received within a timeout, -1 otherwise
|
// Returns the byte if one was received within a timeout, -1 otherwise
|
||||||
if (cFile::FileReady(f, TimeoutMs)) {
|
if (cFile::FileReady(f, TimeoutMs)) {
|
||||||
unsigned char b;
|
unsigned char b;
|
||||||
if (read(f, &b, 1) == 1)
|
if (safe_read(f, &b, 1) == 1)
|
||||||
return b;
|
return b;
|
||||||
else
|
else
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
@ -436,7 +436,7 @@ void cRcIoLIRC::Action(void)
|
|||||||
|
|
||||||
LOCK_THREAD;
|
LOCK_THREAD;
|
||||||
|
|
||||||
if (cFile::FileReady(f, REPEATLIMIT) && read(f, buf, sizeof(buf)) > 21) {
|
if (cFile::FileReady(f, REPEATLIMIT) && safe_read(f, buf, sizeof(buf)) > 21) {
|
||||||
if (!receivedData) { // only accept new data the previous data has been fetched
|
if (!receivedData) { // only accept new data the previous data has been fetched
|
||||||
int count;
|
int count;
|
||||||
sscanf(buf, "%*x %x %29s", &count, LastKeyName); // '29' in '%29s' is LIRC_KEY_BUF-1!
|
sscanf(buf, "%*x %x %29s", &count, LastKeyName); // '29' in '%29s' is LIRC_KEY_BUF-1!
|
||||||
|
6
svdrp.c
6
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 1.20 2001/07/22 13:58:48 kls Exp $
|
* $Id: svdrp.c 1.21 2001/08/12 15:10:16 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -264,7 +264,7 @@ bool cSVDRP::Send(const char *s, int length)
|
|||||||
{
|
{
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
length = strlen(s);
|
length = strlen(s);
|
||||||
int wbytes = write(file, s, length);
|
int wbytes = safe_write(file, s, length);
|
||||||
if (wbytes == length)
|
if (wbytes == length)
|
||||||
return true;
|
return true;
|
||||||
if (wbytes < 0) {
|
if (wbytes < 0) {
|
||||||
@ -920,7 +920,7 @@ void cSVDRP::Process(void)
|
|||||||
lastActivity = time(NULL);
|
lastActivity = time(NULL);
|
||||||
if (file.Ready(false)) {
|
if (file.Ready(false)) {
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
int r = read(file, &c, 1);
|
int r = safe_read(file, &c, 1);
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
if (c == '\n' || c == 0x00) {
|
if (c == '\n' || c == 0x00) {
|
||||||
// strip trailing whitespace:
|
// strip trailing whitespace:
|
||||||
|
28
tools.c
28
tools.c
@ -4,7 +4,7 @@
|
|||||||
* 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: tools.c 1.38 2001/08/11 14:49:48 kls Exp $
|
* $Id: tools.c 1.39 2001/08/12 15:12:54 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -23,9 +23,33 @@
|
|||||||
|
|
||||||
int SysLogLevel = 3;
|
int SysLogLevel = 3;
|
||||||
|
|
||||||
|
ssize_t safe_read(int filedes, void *buffer, size_t size)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
ssize_t p = read(filedes, buffer, size);
|
||||||
|
if (p < 0 && errno == EINTR) {
|
||||||
|
dsyslog(LOG_INFO, "EINTR while reading from file handle %d - retrying", filedes);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t safe_write(int filedes, const void *buffer, size_t size)
|
||||||
|
{
|
||||||
|
for (;;) {
|
||||||
|
ssize_t p = write(filedes, buffer, size);
|
||||||
|
if (p < 0 && errno == EINTR) {
|
||||||
|
dsyslog(LOG_INFO, "EINTR while writing to file handle %d - retrying", filedes);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void writechar(int filedes, char c)
|
void writechar(int filedes, char c)
|
||||||
{
|
{
|
||||||
write(filedes, &c, sizeof(c));
|
safe_write(filedes, &c, sizeof(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
char *readline(FILE *f)
|
char *readline(FILE *f)
|
||||||
|
4
tools.h
4
tools.h
@ -4,7 +4,7 @@
|
|||||||
* 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: tools.h 1.27 2001/08/11 09:52:14 kls Exp $
|
* $Id: tools.h 1.28 2001/08/12 15:13:02 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -33,6 +33,8 @@ extern int SysLogLevel;
|
|||||||
|
|
||||||
template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; };
|
template<class T> inline void swap(T &a, T &b) { T t = a; a = b; b = t; };
|
||||||
|
|
||||||
|
ssize_t safe_read(int filedes, void *buffer, size_t size);
|
||||||
|
ssize_t safe_write(int filedes, const void *buffer, size_t size);
|
||||||
void writechar(int filedes, char c);
|
void writechar(int filedes, char c);
|
||||||
char *readline(FILE *f);
|
char *readline(FILE *f);
|
||||||
char *strn0cpy(char *dest, const char *src, size_t n);
|
char *strn0cpy(char *dest, const char *src, size_t n);
|
||||||
|
Loading…
Reference in New Issue
Block a user