diff options
-rw-r--r-- | dvbapi.c | 105 | ||||
-rw-r--r-- | dvbapi.h | 17 | ||||
-rw-r--r-- | interface.c | 27 | ||||
-rw-r--r-- | interface.h | 8 | ||||
-rw-r--r-- | menu.c | 48 | ||||
-rw-r--r-- | menu.h | 9 | ||||
-rw-r--r-- | osd.c | 4 | ||||
-rw-r--r-- | osd.h | 8 | ||||
-rw-r--r-- | osm.c | 31 | ||||
-rw-r--r-- | recording.c | 21 | ||||
-rw-r--r-- | recording.h | 8 | ||||
-rw-r--r-- | remote.c | 25 | ||||
-rw-r--r-- | remote.h | 3 | ||||
-rw-r--r-- | tools.c | 5 |
14 files changed, 248 insertions, 71 deletions
@@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.c 1.4 2000/04/22 13:09:49 kls Exp $ + * $Id: dvbapi.c 1.5 2000/04/23 15:32:00 kls Exp $ */ #include "dvbapi.h" @@ -85,7 +85,7 @@ public: int Last(void) { return last; } int GetResume(void) { return resume; } bool StoreResume(int Index); - static char *Str(int Index); + static char *Str(int Index, bool WithFrame = false); }; cIndexFile::cIndexFile(const char *FileName, bool Record) @@ -256,7 +256,7 @@ bool cIndexFile::StoreResume(int Index) return false; } -char *cIndexFile::Str(int Index) +char *cIndexFile::Str(int Index, bool WithFrame) { static char buffer[16]; int f = (Index % FRAMESPERSEC) + 1; @@ -264,7 +264,7 @@ char *cIndexFile::Str(int Index) int m = s / 60 % 60; int h = s / 3600; s %= 60; - snprintf(buffer, sizeof(buffer), "%d:%02d:%02d.%02d", h, m, s, f); + snprintf(buffer, sizeof(buffer), WithFrame ? "%d:%02d:%02d.%02d" : "%d:%02d:%02d", h, m, s, f); return buffer; } @@ -752,6 +752,7 @@ public: int Resume(void); bool Save(void); void SkipSeconds(int Seconds); + void GetIndex(int &Current, int &Total); }; cReplayBuffer::cReplayBuffer(int *OutFile, const char *FileName) @@ -849,6 +850,16 @@ void cReplayBuffer::SkipSeconds(int Seconds) } } +void cReplayBuffer::GetIndex(int &Current, int &Total) +{ + if (index) { + Current = index->Get(fileNumber, fileOffset); + Total = index->Last(); + } + else + Current = Total = -1; +} + void cReplayBuffer::SkipAudioBlocks(void) { int Length; @@ -1003,6 +1014,8 @@ cDvbApi::cDvbApi(void) leaveok(stdscr, TRUE); window = NULL; #endif + lastProgress = -1; + replayTitle = NULL; } cDvbApi::~cDvbApi() @@ -1018,6 +1031,7 @@ cDvbApi::~cDvbApi() endwin(); #endif } + delete replayTitle; } #ifdef DEBUG_OSD @@ -1054,8 +1068,10 @@ void cDvbApi::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co } #endif -void cDvbApi::Open(int w, int h, int d) +void cDvbApi::Open(int w, int h) { + int d = (h < 0) ? MenuLines + h : 0; + h = abs(h); cols = w; rows = h; #ifdef DEBUG_OSD @@ -1081,6 +1097,8 @@ void cDvbApi::Open(int w, int h, int d) SETCOLOR(clrCyan, 0x00, 0xFC, 0xFC, 255); SETCOLOR(clrMagenta, 0xB0, 0x00, 0xFC, 255); SETCOLOR(clrWhite, 0xFC, 0xFC, 0xFC, 255); + + lastProgress = -1; } void cDvbApi::Close(void) @@ -1088,6 +1106,7 @@ void cDvbApi::Close(void) #ifndef DEBUG_OSD Cmd(OSD_Close); #endif + lastProgress = -1; } void cDvbApi::Clear(void) @@ -1134,6 +1153,50 @@ void cDvbApi::Text(int x, int y, const char *s, eDvbColor colorFg, eDvbColor col #endif } +void cDvbApi::ShowProgress(bool Initial) +{ + int Current, Total; + + if (GetIndex(&Current, &Total)) { + if (Initial) { + if (replayTitle) + Text(0, 0, replayTitle); + Text(-7, 2, cIndexFile::Str(Total)); + } +#ifdef DEBUG_OSD + int p = cols * Current / Total; + Fill(0, 1, p, 1, clrGreen); + Fill(p, 1, cols - p, 1, clrWhite); +#else + int w = cols * charWidth; + int p = w * Current / Total; + if (p != lastProgress) { + int y1 = 1 * lineHeight; + int y2 = 2 * lineHeight - 1; + int x1, x2; + eDvbColor color; + if (lastProgress < p) { + x1 = lastProgress + 1; + x2 = p; + if (p >= w) + p = w - 1; + color = clrGreen; + } + else { + x1 = p + 1; + x2 = lastProgress; + color = clrWhite; + } + if (lastProgress < 0) + Cmd(OSD_FillBlock, clrWhite, 0, y1, w - 1, y2); + Cmd(OSD_FillBlock, color, x1, y1, x2, y2); + lastProgress = p; + } +#endif + Text(0, 2, cIndexFile::Str(Current)); + } +} + bool cDvbApi::SetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Ca, int Pnr) { if (videoDev >= 0) { @@ -1312,7 +1375,7 @@ void cDvbApi::SetReplayMode(int Mode) } } -bool cDvbApi::StartReplay(const char *FileName) +bool cDvbApi::StartReplay(const char *FileName, const char *Title) { if (Recording()) { esyslog(LOG_ERR, "ERROR: StartReplay() called while recording - ignored!"); @@ -1321,6 +1384,13 @@ bool cDvbApi::StartReplay(const char *FileName) StopReplay(); if (videoDev >= 0) { + lastProgress = -1; + delete replayTitle; + if (Title) { + if ((replayTitle = strdup(Title)) == NULL) + esyslog(LOG_ERR, "ERROR: StartReplay: can't copy title '%s'", Title); + } + // Check FileName: if (!FileName) { @@ -1364,7 +1434,7 @@ bool cDvbApi::StartReplay(const char *FileName) bool FastRewind = false; int ResumeIndex = Buffer->Resume(); if (ResumeIndex >= 0) - isyslog(LOG_INFO, "resuming replay at index %d (%s)", ResumeIndex, cIndexFile::Str(ResumeIndex)); + isyslog(LOG_INFO, "resuming replay at index %d (%s)", ResumeIndex, cIndexFile::Str(ResumeIndex, true)); for (;;) { if (Buffer->Read() < 0) break; @@ -1408,6 +1478,12 @@ bool cDvbApi::StartReplay(const char *FileName) Buffer->SkipSeconds(Seconds); } } + case dvbGetIndex: { + int Current, Total; + Buffer->GetIndex(Current, Total); + writeint(toMain, Current); + writeint(toMain, Total); + } break; } } @@ -1473,3 +1549,18 @@ void cDvbApi::Skip(int Seconds) } } +bool cDvbApi::GetIndex(int *Current, int *Total) +{ + if (pidReplay) { + int total; + writechar(toReplay, dvbGetIndex); + if (readint(fromReplay, *Current) && readint(fromReplay, total)) { + if (Total) + *Total = total; + } + else + *Current = -1; + } + return *Current >= 0; +} + @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: dvbapi.h 1.4 2000/04/22 13:07:34 kls Exp $ + * $Id: dvbapi.h 1.5 2000/04/23 10:08:27 kls Exp $ */ #ifndef __DVBAPI_H @@ -62,13 +62,21 @@ private: int cols, rows; void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL); public: - void Open(int w, int h, int d = 0); + void Open(int w, int h); void Close(void); void Clear(void); void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground); void ClrEol(int x, int y, eDvbColor color = clrBackground); void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground); + // Progress Display facilities + +private: + int lastProgress; + char *replayTitle; +public: + void ShowProgress(bool Initial = false); + // Channel facilities bool SetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Ca, int Pnr); @@ -81,6 +89,7 @@ private: dvbFastForward, dvbFastRewind, dvbSkip, + dvbGetIndex, }; bool isMainProcess; pid_t pidRecord, pidReplay; @@ -105,10 +114,11 @@ public: // returned. void StopRecord(void); // Stops the current recording session (if any). - bool StartReplay(const char *FileName); + bool StartReplay(const char *FileName, const char *Title = NULL); // Starts replaying the given file. // 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 StopReplay(void); // Stops the current replay session (if any). void PauseReplay(void); @@ -122,6 +132,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); }; #endif //__DVBAPI_H diff --git a/interface.c b/interface.c index fd1fa2dc..2eaf5f3a 100644 --- a/interface.c +++ b/interface.c @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: interface.c 1.4 2000/04/22 13:51:48 kls Exp $ + * $Id: interface.c 1.5 2000/04/23 15:11:41 kls Exp $ */ #include "interface.h" @@ -33,10 +33,10 @@ void cInterface::Init(void) #endif } -void cInterface::Open(int NumCols, int NumLines, int StartLine) +void cInterface::Open(int NumCols, int NumLines) { if (!open++) - DvbApi.Open(NumCols, NumLines, StartLine); + DvbApi.Open(NumCols, NumLines); } void cInterface::Close(void) @@ -47,23 +47,28 @@ void cInterface::Close(void) DvbApi.Close(); } -unsigned int cInterface::GetCh(void) +unsigned int cInterface::GetCh(bool Wait) { #ifdef DEBUG_REMOTE + timeout(Wait ? 1000 :10); int c = getch(); return (c > 0) ? c : 0; #else -//XXX #ifdef DEBUG_OSD -//XXX wrefresh(window);//XXX -//XXX #endif - unsigned int Command; - return RcIo.GetCommand(&Command) ? Command : 0; +#ifdef DEBUG_OSD + timeout(0); + getch(); // just to make 'ncurses' display the window: +#endif + if (Wait || RcIo.InputAvailable()) { + unsigned int Command; + return RcIo.GetCommand(&Command, NULL) ? Command : 0; + } + return 0; #endif } -eKeys cInterface::GetKey(void) +eKeys cInterface::GetKey(bool Wait) { - eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh()); + eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait)); keyFromWait = kNone; return Key; } diff --git a/interface.h b/interface.h index 76fdab8d..050e17c4 100644 --- a/interface.h +++ b/interface.h @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: interface.h 1.5 2000/04/22 13:07:16 kls Exp $ + * $Id: interface.h 1.6 2000/04/23 14:57:13 kls Exp $ */ #ifndef __INTERFACE_H @@ -20,16 +20,16 @@ private: int open; int cols[MaxCols]; eKeys keyFromWait; - unsigned int GetCh(void); + unsigned int GetCh(bool Wait = true); void QueryKeys(void); void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor); eKeys Wait(int Seconds = 1, bool KeepChar = false); public: cInterface(void); void Init(void); - void Open(int NumCols = MenuColumns, int NumLines = MenuLines, int StartLine = 0); + void Open(int NumCols = MenuColumns, int NumLines = MenuLines); void Close(void); - eKeys GetKey(void); + eKeys GetKey(bool Wait = true); void Clear(void); void ClearEol(int x, int y, eDvbColor Color = clrBackground); void SetCols(int *c); @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: menu.c 1.5 2000/04/22 15:21:08 kls Exp $ + * $Id: menu.c 1.6 2000/04/23 15:38:16 kls Exp $ */ #include "menu.h" @@ -915,16 +915,7 @@ cMenuRecordingItem::cMenuRecordingItem(cRecording *Recording) void cMenuRecordingItem::Set(void) { - char *buffer = NULL; - struct tm *t = localtime(&recording->start); - asprintf(&buffer, "%02d.%02d.%04d\t%02d:%02d\t%s", - t->tm_mday, - t->tm_mon + 1, - t->tm_year + 1900, - t->tm_hour, - t->tm_min, - recording->name); - SetText(buffer, false); + SetText(recording->Title('\t')); } // --- cMenuRecordings ------------------------------------------------------- @@ -957,7 +948,7 @@ eOSState cMenuRecordings::Play(void) cMenuRecordingItem *ri = (cMenuRecordingItem *)Get(Current()); if (ri) { //XXX what if this recording's file is currently in use??? - if (DvbApi.StartReplay(ri->recording->FileName())) + if (DvbApi.StartReplay(ri->recording->FileName(), ri->recording->Title())) return osEnd; } return osContinue; @@ -1022,3 +1013,36 @@ eOSState cMenuMain::ProcessKey(eKeys Key) return state; } +// --- cReplayDisplay -------------------------------------------------------- + +cReplayDisplay::cReplayDisplay(void) +{ + Interface.Open(MenuColumns, -3); + DvbApi.ShowProgress(true); +} + +cReplayDisplay::~cReplayDisplay() +{ + Interface.Close(); +} + +eKeys cReplayDisplay::ProcessKey(eKeys Key) +{ + if (!DvbApi.Replaying()) + return kOk; // will turn off replay display + DvbApi.ShowProgress(); + switch (Key) { + case kBegin: + case kPause: + case kStop: + case kSearchBack: + case kSearchForward: + case kSkipBack: + case kSkipForward: break; // will be done in main loop + case kMenu: break; // allow direct switching to menu + case kOk: break; // switches off replay display + default: Key = kNone; // ignore anything not explicitly known here + } + return Key; +} + @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: menu.h 1.2 2000/03/05 10:57:27 kls Exp $ + * $Id: menu.h 1.3 2000/04/23 09:25:33 kls Exp $ */ #ifndef _MENU_H @@ -18,4 +18,11 @@ public: virtual eOSState ProcessKey(eKeys Key); }; +class cReplayDisplay { +public: + cReplayDisplay(void); + ~cReplayDisplay(); + eKeys ProcessKey(eKeys Key); + }; + #endif //_MENU_H @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: osd.c 1.2 2000/02/27 17:23:07 kls Exp $ + * $Id: osd.c 1.3 2000/04/23 09:52:39 kls Exp $ */ #include "osd.h" @@ -35,7 +35,7 @@ cOsdItem::~cOsdItem() delete text; } -void cOsdItem::SetText(char *Text, bool Copy) +void cOsdItem::SetText(const char *Text, bool Copy) { delete text; text = Copy ? strdup(Text) : Text; @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: osd.h 1.2 2000/03/05 11:33:11 kls Exp $ + * $Id: osd.h 1.3 2000/04/23 09:53:19 kls Exp $ */ #ifndef __OSD_H @@ -28,7 +28,7 @@ enum eOSState { osUnknown, class cOsdItem : public cListObject { private: - char *text; + const char *text; int offset; eOSState state; protected: @@ -37,8 +37,8 @@ public: cOsdItem(eOSState State = osUnknown); cOsdItem(char *Text, eOSState State = osUnknown); virtual ~cOsdItem(); - void SetText(char *Text, bool Copy = true); - char *Text(void) { return text; } + void SetText(const char *Text, bool Copy = true); + const char *Text(void) { return text; } void Display(int Offset = -1, bool Current = false); virtual void Set(void) {} virtual eOSState ProcessKey(eKeys Key); @@ -22,7 +22,7 @@ * * The project's page is at http://www.cadsoft.de/people/kls/vdr * - * $Id: osm.c 1.7 2000/04/22 13:35:37 kls Exp $ + * $Id: osm.c 1.8 2000/04/23 14:57:57 kls Exp $ */ #include <signal.h> @@ -65,6 +65,7 @@ int main(int argc, char *argv[]) if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN); cMenuMain *Menu = NULL; + cReplayDisplay *ReplayDisplay = NULL; cTimer *Timer = NULL; int dcTime = 0, dcNumber = 0; int LastChannel = -1; @@ -72,9 +73,11 @@ int main(int argc, char *argv[]) while (!Interrupted) { // Channel display: if (CurrentChannel != LastChannel) { - cChannel *channel = Channels.Get(CurrentChannel); - if (channel) - Interface.DisplayChannel(CurrentChannel + 1, channel->name); + if (!Menu && !ReplayDisplay) { + cChannel *channel = Channels.Get(CurrentChannel); + if (channel) + Interface.DisplayChannel(CurrentChannel + 1, channel->name); + } LastChannel = CurrentChannel; } // Direct Channel Select (action): @@ -90,6 +93,7 @@ int main(int argc, char *argv[]) AssertFreeDiskSpace(); if (!Timer && (Timer = cTimer::GetMatch()) != NULL) { DELETENULL(Menu); + DELETENULL(ReplayDisplay); // make sure the timer won't be deleted: Timer->SetRecording(true); // switch to channel: @@ -114,7 +118,7 @@ int main(int argc, char *argv[]) } } // User Input: - eKeys key = Interface.GetKey(); + eKeys key = Interface.GetKey(!ReplayDisplay); if (Menu) { switch (Menu->ProcessKey(key)) { default: if (key != kMenu) @@ -124,7 +128,7 @@ int main(int argc, char *argv[]) break; } } - else { + else if (!ReplayDisplay || (key = ReplayDisplay->ProcessKey(key)) != kNone) { switch (key) { // Direct Channel Select (input): case k0: case k1: case k2: case k3: case k4: case k5: case k6: case k7: case k8: case k9: @@ -145,13 +149,16 @@ int main(int argc, char *argv[]) Interface.Error("Already recording!"); break; case kPause: DvbApi.PauseReplay(); break; - case kStop: DvbApi.StopReplay(); break; + case kStop: DELETENULL(ReplayDisplay); + DvbApi.StopReplay(); + break; case kSearchBack: DvbApi.FastRewind(); break; case kSearchForward: DvbApi.FastForward(); break; case kSkipBack: DvbApi.Skip(-60); break; case kSkipForward: DvbApi.Skip(60); break; // Menu Control: - case kMenu: Menu = new cMenuMain; + case kMenu: DELETENULL(ReplayDisplay); + Menu = new cMenuMain; Menu->Display(); break; // Up/Down Channel Select: @@ -164,8 +171,12 @@ int main(int argc, char *argv[]) } break; // Viewing Control: - case kOk: LastChannel = -1; break; // forces channel display - //TODO if replaying switch to progress display instead + case kOk: if (ReplayDisplay) + DELETENULL(ReplayDisplay); + else if (DvbApi.Replaying()) + ReplayDisplay = new cReplayDisplay; + else + LastChannel = -1; break; // forces channel display default: break; } } diff --git a/recording.c b/recording.c index de202ce0..6d70bd49 100644 --- a/recording.c +++ b/recording.c @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: recording.c 1.3 2000/04/16 15:47:45 kls Exp $ + * $Id: recording.c 1.4 2000/04/23 09:48:35 kls Exp $ */ #define _GNU_SOURCE @@ -140,12 +140,14 @@ cRecording::cRecording(const char *FileName) name[p - FileName] = 0; } } + titleBuffer = NULL; } cRecording::~cRecording() { delete fileName; delete name; + delete titleBuffer; } const char *cRecording::FileName(void) @@ -157,6 +159,23 @@ const char *cRecording::FileName(void) return fileName; } +const char *cRecording::Title(char Delimiter) +{ + delete titleBuffer; + titleBuffer = NULL; + struct tm *t = localtime(&start); + asprintf(&titleBuffer, "%02d.%02d.%04d%c%02d:%02d%c%s", + t->tm_mday, + t->tm_mon + 1, + t->tm_year + 1900, + Delimiter, + t->tm_hour, + t->tm_min, + Delimiter, + name); + return titleBuffer; +} + bool cRecording::Delete(void) { bool result = true; diff --git a/recording.h b/recording.h index 2e79a7da..3151896d 100644 --- a/recording.h +++ b/recording.h @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: recording.h 1.3 2000/04/16 15:44:09 kls Exp $ + * $Id: recording.h 1.4 2000/04/23 09:50:40 kls Exp $ */ #ifndef __RECORDING_H @@ -17,9 +17,12 @@ void AssertFreeDiskSpace(void); class cRecording : public cListObject { -public: + friend class cRecordings; +private: + char *titleBuffer; char *name; char *fileName; +public: time_t start; int priority; int lifetime; @@ -28,6 +31,7 @@ public: cRecording(const char *FileName); ~cRecording(); const char *FileName(void); + const char *Title(char Delimiter = ' '); bool Delete(void); // Changes the file name so that it will no longer be visible in the OSM // Returns false in case of error @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: remote.c 1.4 2000/04/22 15:21:41 kls Exp $ + * $Id: remote.c 1.5 2000/04/23 14:41:21 kls Exp $ */ #include "remote.h" @@ -51,9 +51,8 @@ cRcIo::~cRcIo() close(f); } -int cRcIo::ReceiveByte(bool Wait) +bool cRcIo::InputAvailable(bool Wait) { - // Returns the byte if one was received within a timeout, -1 otherwise if (f >= 0) { fd_set set; struct timeval timeout; @@ -61,13 +60,19 @@ int cRcIo::ReceiveByte(bool Wait) timeout.tv_usec = Wait ? 0 : 10000; FD_ZERO(&set); FD_SET(f, &set); - if (select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0) { - if (FD_ISSET(f, &set)) { - unsigned char b; - if (read(f, &b, 1) == 1) - return b; - } - } + if (select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0) + return FD_ISSET(f, &set); + } + return false; +} + +int cRcIo::ReceiveByte(bool Wait) +{ + // Returns the byte if one was received within a timeout, -1 otherwise + if (InputAvailable(Wait)) { + unsigned char b; + if (read(f, &b, 1) == 1) + return b; } return -1; } @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: remote.h 1.2 2000/04/16 13:53:50 kls Exp $ + * $Id: remote.h 1.3 2000/04/23 14:40:16 kls Exp $ */ #ifndef __REMOTE_H @@ -29,6 +29,7 @@ public: enum { modeH = 'h', modeB = 'b', modeS = 's' }; cRcIo(char *DeviceName); ~cRcIo(); + bool InputAvailable(bool Wait = false); void Flush(int WaitSeconds = 0); bool SetCode(unsigned char Code, unsigned short Address); bool SetMode(unsigned char Mode); @@ -4,7 +4,7 @@ * See the main source file 'osm.c' for copyright information and * how to reach the author. * - * $Id: tools.c 1.3 2000/04/15 15:10:05 kls Exp $ + * $Id: tools.c 1.4 2000/04/23 15:30:17 kls Exp $ */ #define _GNU_SOURCE @@ -40,8 +40,7 @@ char readchar(int filedes) bool readint(int filedes, int &n) { - //XXX timeout!! - return read(filedes, &n, sizeof(n)); + return read(filedes, &n, sizeof(n)) == sizeof(n); } char *readline(FILE *f) |