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