ostream-file.c revision 52b34f874a22615c67a9e1a1ee1679153559e377
c25356d5978632df6203437e1953bcb29e0c736fTimo Sirainen/* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* @UNSAFE: whole file */
252db51b6c0a605163326b3ea5d09e9936ca3b29Timo Sirainen/* try to keep the buffer size within 4k..128k. ReiserFS may actually return
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen 128k as optimal size. */
2526d52441ef368215ab6bf04fd0356d3b09d235Timo Sirainen ((fstream)->head == (fstream)->tail && !(fstream)->full)
09801f106cd531a28b4e03ec665e44c421264560Timo Sirainen ((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX)
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen size_t buffer_size, max_buffer_size, optimal_block_size;
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen size_t head, tail; /* first unsent/unused byte */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen unsigned int full:1; /* if head == tail, is buffer empty or full? */
5ac0b0bf32898c63da086ae169674ecac151a31eTimo Sirainenstatic void stream_send_io(struct file_ostream *fstream);
a10ed8c47534b4c6b6bf2711ccfe577e720a47b4Timo Sirainenstatic void stream_closed(struct file_ostream *fstream)
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen if (fstream->autoclose_fd && fstream->fd != -1) {
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenstatic void o_stream_file_close(struct iostream_private *stream)
07e4875d250e7a7157cd99132aafc773cf3cdf83Timo Sirainen struct file_ostream *fstream = (struct file_ostream *)stream;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen /* flush output before really closing it */
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic void o_stream_file_destroy(struct iostream_private *stream)
0a49b316fc729e5d57268ffa63c7122ac73f994cTimo Sirainen struct file_ostream *fstream = (struct file_ostream *)stream;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Siraineno_stream_file_set_max_buffer_size(struct iostream_private *stream,
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen struct file_ostream *fstream = (struct file_ostream *)stream;
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenstatic void update_buffer(struct file_ostream *fstream, size_t size)
7d207b1e77a7b5e3fda640e353acfc86d261fedfTimo Sirainen /* ...HXXXT... */
6f08b98ac63c25b747120d0c8f8e319b4e26ab0fTimo Sirainenstatic void o_stream_socket_cork(struct file_ostream *fstream)
7e1f68ad71d3485f1882142837b01f7a98ca8467Timo Sirainen if (fstream->corked && !fstream->socket_cork_set) {
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainenstatic int o_stream_lseek(struct file_ostream *fstream)
c06f4017027263cf3a08becc551f5126409e2a83Timo Sirainen if (fstream->real_offset == fstream->buffer_offset)
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen ret = lseek(fstream->fd, (off_t)fstream->buffer_offset, SEEK_SET);
282a436a74d8835edb45cc019b1c916013013fd3Timo Sirainen fstream->ostream.ostream.stream_errno = errno;
bool partial;
if (ret > 0)
size = 0;
for (i = 0; i < IOV_MAX; i++)
IOV_MAX);
size = 0;
for (i = 0; i < iov_size; i++)
iov_size);
if (ret > 0) {
if (ret < 0) {
iov++;
iov_size--;
if (size == 0)
if (ret2 > 0) {
if (ret2 <= 0)
return ret2;
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) {
return ret;
static struct file_ostream *
return fstream;
struct ostream *
if (offset >= 0) {
if (max_buffer_size == 0)
return ostream;
struct ostream *
return ostream;