Skip to content

Commit eddc8bc

Browse files
committed
Fix EOF check for "-m 2" option on non-Windows environment
Without this fix, an infinite loop occurs if upstream finishes first.
1 parent 7c1d79f commit eddc8bc

File tree

1 file changed

+20
-5
lines changed

1 file changed

+20
-5
lines changed

tsreadex.cpp

+20-5
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ int ReadFileToBuffer(HANDLE file, uint8_t *buf, size_t count, HANDLE asyncContex
6464
OVERLAPPED ol = {};
6565
DWORD nRead;
6666
if (asyncContext) {
67+
// For asynchronous, returns -1 for EOF
6768
ol.hEvent = asyncContext;
6869
if (ReadFile(file, buf, static_cast<DWORD>(count), nullptr, &ol)) {
6970
return GetOverlappedResult(file, &ol, &nRead, FALSE) ? nRead : -1;
@@ -79,6 +80,7 @@ int ReadFileToBuffer(HANDLE file, uint8_t *buf, size_t count, HANDLE asyncContex
7980
}
8081
}
8182
else if (ReadFile(file, buf, static_cast<DWORD>(count), &nRead, nullptr)) {
83+
// For synchronous, 0 means EOF
8284
return nRead;
8385
}
8486
return -1;
@@ -105,12 +107,19 @@ int64_t SeekFile(int file, int64_t offset)
105107
}
106108

107109
template<class P>
108-
int ReadFileToBuffer(int file, uint8_t *buf, size_t count, bool asyncContext, P asyncCancelProc)
110+
int ReadFileToBuffer(int file, uint8_t *buf, size_t count, int &asyncContext, P asyncCancelProc)
109111
{
110112
for (;;) {
111113
int ret = static_cast<int>(read(file, buf, count));
112114
if (ret >= 0 || !asyncContext || (errno != EAGAIN && errno != EWOULDBLOCK) || asyncCancelProc()) {
113-
return ret;
115+
// Asynchronous FIFO reading can be opened before a writer opens it, then read() returns 0.
116+
if (asyncContext && ret > 0) {
117+
// Connected.
118+
asyncContext = 2;
119+
}
120+
// For asynchronous, returns -1 for EOF
121+
// For synchronous, 0 means EOF
122+
return asyncContext == 2 && ret == 0 ? -1 : ret;
114123
}
115124
fd_set rfd;
116125
FD_ZERO(&rfd);
@@ -123,7 +132,7 @@ int ReadFileToBuffer(int file, uint8_t *buf, size_t count, bool asyncContext, P
123132
}
124133
}
125134

126-
void CloseFile(int file, bool asyncContext)
135+
void CloseFile(int file, int asyncContext)
127136
{
128137
static_cast<void>(asyncContext);
129138
if (file >= 0) {
@@ -296,7 +305,8 @@ int main(int argc, char **argv)
296305
}
297306
#else
298307
bool traceToStdout = traceName[0] == '-' && !traceName[1];
299-
bool asyncContext = timeoutMode == 2;
308+
// 0: synchronous, 1: not connected yet, 2: connected.
309+
int asyncContext = timeoutMode == 2;
300310
int file;
301311
int openedFile = -1;
302312
if (srcName[0] == '-' && !srcName[1]) {
@@ -407,6 +417,11 @@ int main(int argc, char **argv)
407417
if (n < 0) {
408418
completed = true;
409419
}
420+
#ifndef _WIN32
421+
else if (n <= 0) {
422+
retry = true;
423+
}
424+
#endif
410425
else {
411426
bufCount += n;
412427
filePos += n;
@@ -420,7 +435,7 @@ int main(int argc, char **argv)
420435
}
421436
else {
422437
SleepFor(std::chrono::milliseconds(200));
423-
if (SeekFile(file, filePos) != filePos) {
438+
if (timeoutMode != 2 && SeekFile(file, filePos) != filePos) {
424439
fprintf(stderr, "Warning: seek failed.\n");
425440
completed = true;
426441
}

0 commit comments

Comments
 (0)