istream-file.c revision 8cba3d69f0d0a3f03dc3b630e18896aa00ebb6ff
e59faf65ce864fe95dc00f5d52b8323cdbd0608aTimo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen/* @UNSAFE: whole file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen void (*timeout_cb)(void *);
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen struct _istream *_stream = (struct _istream *) stream;
c3a636e4c9ae776e0eed06b6d7ad1ccfb6003afdTimo Sirainen if (fstream->autoclose_fd && _stream->fd != -1) {
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen struct _istream *_stream = (struct _istream *) stream;
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainen p_free(_stream->iostream.pool, _stream->w_buffer);
5d03d9f439e41c90215a3c938ffebe4c2a8ae257Timo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
d1fff80640050631b06bfab904a34b2ad24601e8Timo Sirainenstatic void _set_blocking(struct _iostream *stream, int timeout_msecs,
2fb9ae42f9e36388ec6db24188b9108434043fd0Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen net_set_nonblock(fstream->istream.fd, timeout_msecs == 0);
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainenstatic void i_stream_grow_buffer(struct _istream *stream, size_t bytes)
367e28a16854ee9f7247b2518f36f5e9163fcc10Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->buffer_size = nearest_power(stream->buffer_size);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->buffer_size > fstream->max_buffer_size)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->buffer_size = fstream->max_buffer_size;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen p_realloc(stream->iostream.pool, stream->w_buffer,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void i_stream_compress(struct _istream *stream)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen memmove(stream->w_buffer, stream->w_buffer + stream->skip,
b34fdb68d376d85b4880da4a4bdf67ae726a381bTimo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* remove the unused bytes from beginning of buffer */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->buffer_size < fstream->max_buffer_size) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* buffer is full - grow it */
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen i_stream_grow_buffer(stream, I_STREAM_MIN_SIZE);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen i_assert(stream->istream.v_limit >= stream->istream.v_offset);
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen stream->istream.v_offset + fstream->skip_left;
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen if (read_limit <= stream->pos - stream->skip) {
4da8c6cdefabd31262318c32da3c13de1d9ea953Timo Sirainen /* virtual limit reached == EOF */
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen if (ret == 0 && timeout_time > 0 && time(NULL) > timeout_time) {
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen /* timeouted */
18c209a06941ef583b08b173dadfbe4571995bf9Timo Sirainen fstream->timeout_cb(fstream->timeout_context);
cf0ad1a0bddb0787f3d7b408a96d721a8b2a98a3Timo Sirainen if (errno == ECONNRESET || errno == ETIMEDOUT) {
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* treat as disconnection */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen } while (ret == 0 && STREAM_IS_BLOCKING(fstream));
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void _skip(struct _istream *stream, uoff_t count)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstatic void _seek(struct _istream *stream, uoff_t v_offset)
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainenstruct istream *i_stream_create_file(int fd, pool_t pool,
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen fstream = p_new(pool, struct file_istream, 1);
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen fstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;
62fc2fe221eccc834ac6b11b94b55335d5027cd1Timo Sirainen fstream->istream.iostream.set_blocking = _set_blocking;
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen /* get size of fd if it's a file */
8d3278a82b964217d95c340ec6f82037cdc59d19Timo Sirainen if (fstat(fd, &st) < 0 || !S_ISREG(st.st_mode))