Mercurial > dovecot > original-hg > dovecot-1.2
diff src/lib/istream-file.c @ 3241:b79853b4b005 HEAD
Replaced i_stream_get_size() with i_stream_stat(). Added i_stream_sync().
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Tue, 29 Mar 2005 13:28:06 +0300 |
parents | 904a268921af |
children | e05a1af4bbc7 |
line wrap: on
line diff
--- a/src/lib/istream-file.c Tue Mar 29 01:35:12 2005 +0300 +++ b/src/lib/istream-file.c Tue Mar 29 13:28:06 2005 +0300 @@ -3,6 +3,7 @@ /* @UNSAFE: whole file */ #include "lib.h" +#include "ioloop.h" #include "istream-internal.h" #include "network.h" @@ -15,6 +16,8 @@ struct file_istream { struct _istream istream; + struct timeval fstat_cache_stamp; + size_t max_buffer_size; uoff_t skip_left; @@ -173,15 +176,45 @@ stream->skip = stream->pos = 0; } -static uoff_t _get_size(struct _istream *stream) +static void _sync(struct _istream *stream) { struct file_istream *fstream = (struct file_istream *) stream; - struct stat st; + + fstream->fstat_cache_stamp.tv_sec = 0; + + if (!stream->istream.seekable) { + /* can't do anything or data would be lost */ + return; + } + + stream->skip = stream->pos = 0; +} + +static int fstat_cached(struct file_istream *fstream) +{ + if (fstream->fstat_cache_stamp.tv_sec == ioloop_timeval.tv_sec && + fstream->fstat_cache_stamp.tv_usec == ioloop_timeval.tv_usec) + return 0; - if (fstream->file && fstat(stream->fd, &st) == 0 && S_ISREG(st.st_mode)) - return (uoff_t)st.st_size; - else - return (uoff_t)-1; + if (fstat(fstream->istream.fd, &fstream->istream.statbuf) < 0) { + i_error("file_istream.fstat() failed: %m"); + return -1; + } + + fstream->fstat_cache_stamp = ioloop_timeval; + return 0; +} + +static const struct stat *_stat(struct _istream *stream) +{ + struct file_istream *fstream = (struct file_istream *) stream; + + if (fstream->file) { + if (fstat_cached(fstream) < 0) + return NULL; + } + + return &stream->statbuf; } struct istream *i_stream_create_file(int fd, pool_t pool, @@ -200,7 +233,8 @@ fstream->istream.read = _read; fstream->istream.seek = _seek; - fstream->istream.get_size = _get_size; + fstream->istream.sync = _sync; + fstream->istream.stat = _stat; /* get size of fd if it's a file */ if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode)) {