Skip to content

Commit a70174c

Browse files
committed
Handle non-seekable file descriptors
1 parent 46163d1 commit a70174c

2 files changed

Lines changed: 17 additions & 3 deletions

File tree

src/libutil/include/nix/util/serialise.hh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ struct FdSource : BufferedSource
179179
Descriptor fd;
180180
size_t read = 0;
181181
BackedStringView endOfFileError{"unexpected end-of-file"};
182+
bool isSeekable = true;
182183

183184
FdSource()
184185
: fd(INVALID_DESCRIPTOR)

src/libutil/serialise.cc

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,7 @@ bool FdSource::hasData()
202202

203203
void FdSource::skip(size_t len)
204204
{
205+
#ifndef _WIN32
205206
/* Discard data in the buffer. */
206207
if (len && buffer && bufPosIn - bufPosOut) {
207208
if (len >= bufPosIn - bufPosOut) {
@@ -213,9 +214,21 @@ void FdSource::skip(size_t len)
213214
}
214215
}
215216

216-
/* Seek forward in the file to skip the rest. */
217-
if (len && lseek(fd, len, SEEK_CUR) == -1)
218-
throw SysError("seeking forward in file");
217+
/* If we can, seek forward in the file to skip the rest. */
218+
if (isSeekable && len) {
219+
if (lseek(fd, len, SEEK_CUR) == -1) {
220+
if (errno == ESPIPE)
221+
isSeekable = false;
222+
else
223+
throw SysError("seeking forward in file");
224+
} else
225+
return;
226+
}
227+
#endif
228+
229+
/* Otherwise, skip by reading. */
230+
if (len)
231+
BufferedSource::skip(len);
219232
}
220233

221234
size_t StringSource::read(char * data, size_t len)

0 commit comments

Comments
 (0)