[dovecot-cvs] dovecot/src/lib istream-data.c, 1.11,
1.12 istream-file.c, 1.22, 1.23 istream-internal.h, 1.6,
1.7 istream-limit.c, 1.12, 1.13 istream-mmap.c, 1.15,
1.16 istream.c, 1.27, 1.28 istream.h, 1.16,
1.17 ostream-file.c, 1.45, 1.46
cras at dovecot.org
cras at dovecot.org
Tue Mar 29 13:28:09 EEST 2005
Update of /var/lib/cvs/dovecot/src/lib
In directory talvi:/tmp/cvs-serv331/lib
Modified Files:
istream-data.c istream-file.c istream-internal.h
istream-limit.c istream-mmap.c istream.c istream.h
ostream-file.c
Log Message:
Replaced i_stream_get_size() with i_stream_stat(). Added i_stream_sync().
Index: istream-data.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream-data.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- istream-data.c 28 Mar 2005 13:06:43 -0000 1.11
+++ istream-data.c 29 Mar 2005 10:28:06 -0000 1.12
@@ -28,9 +28,10 @@
stream->istream.v_offset = v_offset;
}
-static uoff_t _get_size(struct _istream *stream)
+static const struct stat *_stat(struct _istream *stream)
{
- return stream->pos;
+ stream->statbuf.st_size = stream->pos;
+ return &stream->statbuf;
}
struct istream *i_stream_create_from_data(pool_t pool, const void *data,
@@ -48,7 +49,7 @@
stream->read = _read;
stream->seek = _seek;
- stream->get_size = _get_size;
+ stream->stat = _stat;
stream->istream.seekable = TRUE;
return _i_stream_create(stream, pool, -1, 0);
Index: istream-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream-file.c,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -d -r1.22 -r1.23
--- istream-file.c 28 Mar 2005 13:06:43 -0000 1.22
+++ istream-file.c 29 Mar 2005 10:28:06 -0000 1.23
@@ -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;
- if (fstream->file && fstat(stream->fd, &st) == 0 && S_ISREG(st.st_mode))
- return (uoff_t)st.st_size;
- else
- return (uoff_t)-1;
+ 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 (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)) {
Index: istream-internal.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream-internal.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- istream-internal.h 28 Mar 2005 22:35:12 -0000 1.6
+++ istream-internal.h 29 Mar 2005 10:28:06 -0000 1.7
@@ -1,6 +1,8 @@
#ifndef __ISTREAM_INTERNAL_H
#define __ISTREAM_INTERNAL_H
+#include <sys/stat.h>
+
#include "istream.h"
#include "iostream-internal.h"
@@ -11,7 +13,8 @@
/* methods: */
ssize_t (*read)(struct _istream *stream);
void (*seek)(struct _istream *stream, uoff_t v_offset);
- uoff_t (*get_size)(struct _istream *stream);
+ void (*sync)(struct _istream *stream);
+ const struct stat *(*stat)(struct _istream *stream);
/* data: */
struct istream istream;
@@ -22,6 +25,7 @@
string_t *line_str; /* for i_stream_next_line() if w_buffer == NULL */
size_t buffer_size;
uoff_t abs_start_offset;
+ struct stat statbuf;
size_t skip, pos;
};
Index: istream-limit.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream-limit.c,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- istream-limit.c 28 Mar 2005 13:06:43 -0000 1.12
+++ istream-limit.c 29 Mar 2005 10:28:06 -0000 1.13
@@ -89,12 +89,19 @@
stream->skip = stream->pos = 0;
}
-static uoff_t _get_size(struct _istream *stream)
+static const struct stat *_stat(struct _istream *stream)
{
struct limit_istream *lstream = (struct limit_istream *) stream;
+ const struct stat *st;
- return lstream->v_size != (uoff_t)-1 ? lstream->v_size :
- i_stream_get_size(lstream->input);
+ st = i_stream_stat(lstream->input);
+ if (st == NULL)
+ return NULL;
+
+ stream->statbuf = *st;
+ if (lstream->v_size != (uoff_t)-1)
+ stream->statbuf.st_size = lstream->v_size;
+ return &stream->statbuf;
}
struct istream *i_stream_create_limit(pool_t pool, struct istream *input,
@@ -120,7 +127,7 @@
lstream->istream.read = _read;
lstream->istream.seek = _seek;
- lstream->istream.get_size = _get_size;
+ lstream->istream.stat = _stat;
lstream->istream.istream.seekable = input->seekable;
return _i_stream_create(&lstream->istream, pool, i_stream_get_fd(input),
Index: istream-mmap.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream-mmap.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -d -r1.15 -r1.16
--- istream-mmap.c 28 Mar 2005 13:06:43 -0000 1.15
+++ istream-mmap.c 29 Mar 2005 10:28:06 -0000 1.16
@@ -1,6 +1,7 @@
/* Copyright (c) 2002-2003 Timo Sirainen */
#include "lib.h"
+#include "ioloop.h"
#include "mmap-util.h"
#include "istream-internal.h"
@@ -10,7 +11,8 @@
struct mmap_istream {
struct _istream istream;
- int fd;
+ struct timeval fstat_cache_stamp;
+
void *mmap_base;
off_t mmap_offset;
size_t mmap_block_size;
@@ -25,10 +27,10 @@
{
struct mmap_istream *mstream = (struct mmap_istream *) stream;
- if (mstream->autoclose_fd && mstream->fd != -1) {
- if (close(mstream->fd) < 0)
+ if (mstream->autoclose_fd && mstream->istream.fd != -1) {
+ if (close(mstream->istream.fd) < 0)
i_error("mmap_istream.close() failed: %m");
- mstream->fd = -1;
+ mstream->istream.fd = -1;
}
}
@@ -115,7 +117,7 @@
} else {
mstream->mmap_base =
mmap(NULL, stream->buffer_size, PROT_READ, MAP_PRIVATE,
- mstream->fd, mstream->mmap_offset);
+ stream->fd, mstream->mmap_offset);
if (mstream->mmap_base == MAP_FAILED) {
stream->istream.stream_errno = errno;
mstream->mmap_base = NULL;
@@ -157,11 +159,39 @@
stream->istream.v_offset = v_offset;
}
-static uoff_t _get_size(struct _istream *stream)
+static void _sync(struct _istream *stream)
{
struct mmap_istream *mstream = (struct mmap_istream *) stream;
- return mstream->v_size;
+ i_stream_munmap(mstream);
+ stream->skip = stream->pos = stream->istream.v_offset;
+
+ mstream->fstat_cache_stamp.tv_sec = 0;
+}
+
+static int fstat_cached(struct mmap_istream *mstream)
+{
+ if (mstream->fstat_cache_stamp.tv_sec == ioloop_timeval.tv_sec &&
+ mstream->fstat_cache_stamp.tv_usec == ioloop_timeval.tv_usec)
+ return 0;
+
+ if (fstat(mstream->istream.fd, &mstream->istream.statbuf) < 0) {
+ i_error("mmap_istream.fstat() failed: %m");
+ return -1;
+ }
+
+ mstream->fstat_cache_stamp = ioloop_timeval;
+ return 0;
+}
+
+static const struct stat *_stat(struct _istream *stream)
+{
+ struct mmap_istream *mstream = (struct mmap_istream *) stream;
+
+ if (fstat_cached(mstream) < 0)
+ return NULL;
+
+ return &stream->statbuf;
}
struct istream *i_stream_create_mmap(int fd, pool_t pool, size_t block_size,
@@ -187,7 +217,6 @@
}
mstream = p_new(pool, struct mmap_istream, 1);
- mstream->fd = fd;
_set_max_buffer_size(&mstream->istream.iostream, block_size);
mstream->autoclose_fd = autoclose_fd;
mstream->v_size = v_size;
@@ -198,7 +227,8 @@
mstream->istream.read = _read;
mstream->istream.seek = _seek;
- mstream->istream.get_size = _get_size;
+ mstream->istream.sync = _sync;
+ mstream->istream.stat = _stat;
istream = _i_stream_create(&mstream->istream, pool, fd, start_offset);
istream->mmaped = TRUE;
Index: istream.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- istream.c 28 Mar 2005 22:35:12 -0000 1.27
+++ istream.c 29 Mar 2005 10:28:07 -0000 1.28
@@ -1,6 +1,7 @@
/* Copyright (c) 2002-2003 Timo Sirainen */
#include "lib.h"
+#include "ioloop.h"
#include "str.h"
#include "istream-internal.h"
@@ -90,11 +91,19 @@
_stream->seek(_stream, v_offset);
}
-uoff_t i_stream_get_size(struct istream *stream)
+void i_stream_sync(struct istream *stream)
{
struct _istream *_stream = stream->real_stream;
- return _stream->get_size(_stream);
+ if (!stream->closed && _stream->sync != NULL)
+ _stream->sync(_stream);
+}
+
+const struct stat *i_stream_stat(struct istream *stream)
+{
+ struct _istream *_stream = stream->real_stream;
+
+ return _stream->stat(_stream);
}
int i_stream_have_bytes_left(struct istream *stream)
@@ -234,6 +243,12 @@
_stream->abs_start_offset = abs_start_offset;
_stream->istream.real_stream = _stream;
+ memset(&_stream->statbuf, 0, sizeof(_stream->statbuf));
+ _stream->statbuf.st_size = -1;
+ _stream->statbuf.st_atime =
+ _stream->statbuf.st_mtime =
+ _stream->statbuf.st_ctime = ioloop_time;
+
_io_stream_init(pool, &_stream->iostream);
return &_stream->istream;
}
Index: istream.h
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/istream.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -d -r1.16 -r1.17
--- istream.h 28 Mar 2005 22:35:12 -0000 1.16
+++ istream.h 29 Mar 2005 10:28:07 -0000 1.17
@@ -35,6 +35,9 @@
/* Mark the stream closed. Any reads after this will return -1. The data
already read can still be used. */
void i_stream_close(struct istream *stream);
+/* Sync the stream with the underlying backend, ie. if a file has been
+ modified, flush any cached data. */
+void i_stream_sync(struct istream *stream);
/* Change the maximum size for stream's input buffer to grow. Useful only
for buffered streams (currently only file). */
@@ -49,8 +52,10 @@
/* Seek to specified position from beginning of file. Never fails, the next
read tells if it was successful. This works only for files. */
void i_stream_seek(struct istream *stream, uoff_t v_offset);
-/* Returns size of the stream, or (uoff_t)-1 if unknown */
-uoff_t i_stream_get_size(struct istream *stream);
+/* Returns struct stat, or NULL if error. As the underlying stream may not be
+ a file, only some of the fields might be set, others would be zero.
+ st_size is always set, and if it's not known, it's -1. */
+const struct stat *i_stream_stat(struct istream *stream);
/* Returns TRUE if there are any bytes left to be read or in buffer. */
int i_stream_have_bytes_left(struct istream *stream);
Index: ostream-file.c
===================================================================
RCS file: /var/lib/cvs/dovecot/src/lib/ostream-file.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- ostream-file.c 27 Mar 2005 13:51:54 -0000 1.45
+++ ostream-file.c 29 Mar 2005 10:28:07 -0000 1.46
@@ -636,12 +636,19 @@
static off_t _send_istream(struct _ostream *outstream, struct istream *instream)
{
struct file_ostream *foutstream = (struct file_ostream *)outstream;
+ const struct stat *st;
uoff_t in_size;
off_t ret;
int in_fd, overlapping;
+ st = i_stream_stat(instream);
+ if (st == NULL) {
+ outstream->ostream.stream_errno = instream->stream_errno;
+ return -1;
+ }
+
in_fd = i_stream_get_fd(instream);
- in_size = i_stream_get_size(instream);
+ in_size = st->st_size;
i_assert(instream->v_offset <= in_size);
outstream->ostream.stream_errno = 0;
More information about the dovecot-cvs
mailing list