ostream-file.c revision 54c7c11b95b2477e6536ac101ceac1f3617e93c3
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2002-2007 Dovecot authors, see the included COPYING file */
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger/* @UNSAFE: whole file */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen/* try to keep the buffer size within 4k..128k. ReiserFS may actually return
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen 128k as optimal size. */
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen ((fstream)->head == (fstream)->tail && !(fstream)->full)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen ((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX)
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen size_t buffer_size, max_buffer_size, optimal_block_size;
d1414c09cf0d58ac983054e2f4e1a1f329272dcfTimo Sirainen size_t head, tail; /* first unsent/unused byte */
c57776c06ec99ba9b0dafdbf9475ea72ea8ca134Timo Sirainen unsigned int full:1; /* if head == tail, is buffer empty or full? */
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainenstatic void stream_send_io(struct file_ostream *fstream);
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainenstatic void stream_closed(struct file_ostream *fstream)
e70d5895795732b8247ab9abb045b438e954bc46Timo Sirainen if (fstream->autoclose_fd && fstream->fd != -1) {
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainenstatic void o_stream_file_close(struct iostream_private *stream)
59beb411159176b39e48a52d60dd3239732e67b4Timo Sirainen struct file_ostream *fstream = (struct file_ostream *)stream;
1ddec6312bc6882aeb17d4d46d19cbca1723b68bTimo Sirainen /* flush output before really closing it */
0469ed17dafcc56589ce00960a23f4f06817dfb5Timo Sirainenstatic void o_stream_file_destroy(struct iostream_private *stream)
704fbadd78375da18dcaf2c5d93ac8cfe2c61358Timo Sirainen struct file_ostream *fstream = (struct file_ostream *)stream;
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Siraineno_stream_file_set_max_buffer_size(struct iostream_private *stream,
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen struct file_ostream *fstream = (struct file_ostream *)stream;
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainenstatic void update_buffer(struct file_ostream *fstream, size_t size)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen /* ...HXXXT... */
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainenstatic void o_stream_socket_cork(struct file_ostream *fstream)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen if (fstream->corked && !fstream->socket_cork_set) {
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainenstatic int o_stream_lseek(struct file_ostream *fstream)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen if (fstream->real_offset == fstream->buffer_offset)
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen ret = lseek(fstream->fd, (off_t)fstream->buffer_offset, SEEK_SET);
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen fstream->ostream.ostream.stream_errno = errno;
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen fstream->ostream.ostream.stream_errno = EINVAL;
21c317a20c4c3784b54fb3e90ee3751870afdcc3Timo Sirainen fstream->real_offset = fstream->buffer_offset;
97c339398f1aba6f315b55a9b6ee6b020e33bea4Timo Sirainenstatic ssize_t o_stream_writev(struct file_ostream *fstream,
6e873f135368bcfdd1de4458dded791d0c4d00cdTimo Sirainen fstream->real_offset == fstream->buffer_offset) {
6e873f135368bcfdd1de4458dded791d0c4d00cdTimo Sirainen ret = write(fstream->fd, iov->iov_base, iov->iov_len);
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen ret = pwrite(fstream->fd, iov->iov_base, iov->iov_len,
25757faf029c369a8318349dafe952e2358df1d8Timo Sirainen for (i = 0; i < IOV_MAX; i++)
94a78eb438622fa53abef1e1726714dacad4b61cTimo Sirainen ret = writev(fstream->fd, (const struct iovec *)iov,
e9e2d23e1ea5a149a7d8828d2a45b9f2313c3785Timo Sirainen ret = writev(fstream->fd, (const struct iovec *)iov,
if (ret < 0) {
return ret;
int iov_len;
if (iov_len > 0) {
if (ret < 0)
int ret;
else if (!set) {
/* XXXT...HXXX */
int ret;
if (ret == 0)
sent = 0;
fstream);
return sent;
unsigned int iov_count)
if (ret < 0)
iov++;
iov_count--;
if (iov_count == 0)
return ret;
iov++;
iov_count--;
for (i = 0; i < iov_count; i++) {
return ret;
return ret;
if (ret <= 0) {
ret = 0;
int iov_len;
const unsigned char *data;
int pos;
skip_size = 0;
if (size == 0) {
if (ret < 0)
if (skip_size > 0) {
ret = 0;
skip_size = 0;
iov_len = 0;
const unsigned char *data;
if (ret < 0) {
int in_fd;
if (ret == 0) {
if (ret > 0) {
return ret;
static struct file_ostream *
return fstream;
struct ostream *
if (offset >= 0) {
if (max_buffer_size == 0)
return ostream;
struct ostream *
return ostream;