Aloha.
here's fstream->file which tells if it's a regular file :)
Oooh, nice! But does that work outside ostream.c? :)
They're not dup()ed, they just use the same file descriptors. But .. hmm. that would be possible, but that's still quite a lot of code for cases which are rarely needed..
But it'd be clean and the way to avoid the largest number of syscalls if pread/pwrite are not an option.
Another possible solution is to change output to always use pwrite(), avoiding the need for seeks completly.
Changing ostream to use pwrite() would require replacing the one writev() call too with multiple pwrite()s, not nice .. :)
How about: [...]
Thank you for the patch. It worked, except for two little things: 1. I don't use Linux, so the #define for pseek broke the compile and 2. I had to remove the lseek() call in _read(), which was the whole point in using pread() :) In mbox folders this wouldn't have mattered since the loop is written in a way that assumes mail 4 starts exactly where mail 3 ends, which is not true for my case. This worked for me: --- ../dovecot/src/lib/istream-file.c Tue Aug 26 23:18:16 2003 +++ ./src/lib/istream-file.c Tue Oct 21 16:18:55 2003 @@ -169,7 +169,15 @@ return -1; } - ret = read(stream->fd, stream->w_buffer + stream->pos, size); + if (fstream->file) { + ret = pread(stream->fd, + stream->w_buffer + stream->pos, size, + stream->istream.start_offset + + stream->istream.v_offset); + } else { + ret = read(stream->fd, + stream->w_buffer + stream->pos, size); + } if (ret == 0) { /* EOF */ stream->istream.stream_errno = 0; @@ -228,7 +236,7 @@ stream->istream.stream_errno = EOVERFLOW; ret = -1; } else { - ret = lseek(stream->fd, (off_t)real_offset, SEEK_SET); + ret = (off_t)real_offset; if (ret < 0) stream->istream.stream_errno = errno; else if (ret != (off_t)real_offset) {