ostream-file.c revision 007d354a674fb3ddf49db160cf050cf61270a1a0
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen ostream-file.c : Output stream handling for files
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen Copyright (c) 2002 Timo Sirainen
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen Permission is hereby granted, free of charge, to any person obtaining
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen a copy of this software and associated documentation files (the
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen "Software"), to deal in the Software without restriction, including
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen without limitation the rights to use, copy, modify, merge, publish,
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen distribute, sublicense, and/or sell copies of the Software, and to
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen permit persons to whom the Software is furnished to do so, subject to
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen the following conditions:
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen The above copyright notice and this permission notice shall be
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen included in all copies or substantial portions of the Software.
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen/* @UNSAFE: whole file */
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen/* try to keep the buffer size within 4k..128k. ReiserFS may actually return
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen 128k as optimal size. */
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen ((fstream)->head == (fstream)->tail && !(fstream)->full)
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen ((size) < SSIZE_T_MAX ? (size_t)(size) : SSIZE_T_MAX)
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen size_t buffer_size, max_buffer_size, optimal_block_size;
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen size_t head, tail; /* first unsent/unused byte */
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen void (*timeout_cb)(void *);
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen unsigned int full:1; /* if head == tail, is buffer empty or full? */
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainenstatic void stream_closed(struct file_ostream *fstream)
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen if (fstream->autoclose_fd && fstream->fd != -1) {
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen struct file_ostream *fstream = (struct file_ostream *) stream;
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen /* flush output before really closing it */
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen struct file_ostream *fstream = (struct file_ostream *) stream;
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen p_free(fstream->ostream.iostream.pool, fstream->buffer);
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen struct file_ostream *fstream = (struct file_ostream *) stream;
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainenstatic void _set_blocking(struct _iostream *stream, int timeout_msecs,
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen struct file_ostream *fstream = (struct file_ostream *) stream;
8871c97974dd4e682c7b8d5cff0bbc5b024f56f2Timo Sirainen net_set_nonblock(fstream->fd, timeout_msecs == 0);
while (size > 0) {
size = 0;
/* XXXT...HXXX */
static ssize_t
iov++;
iov_size--;
if (ret < 0) {
return ret;
if (size > 0) {
iov_len++;
if (first)
int iov_len;
int ret;
return ret;
/* XXXT...HXXX */
if (ret < 0) {
int iov_len;
sent = 0;
fstream);
return sent;
if (ret > 0)
return ret;
return ret;
int first;
if (first)
if (ret < 0) {
ret = 0;
int iov_len;
const unsigned char *data;
int pos;
skip_size = 0;
if (overlapping)
if (size == 0) {
if (overlapping) {
if (ret < 0) {
if (skip_size > 0) {
ret = 0;
skip_size = 0;
iov_len--;
iov_len--;
const unsigned char *data;
if (ret < 0) {
overlapping = 0;
if (ret == 0) {
return ret;
if (overlapping <= 0)
return ret;
struct ostream *
int autoclose_fd)
if (offset >= 0) {
#ifndef HAVE_LINUX_SENDFILE
return ostream;