istream-file.c revision 8bdf70ab07588d57373f5f19abb8577985ff358a
45312f52ff3a3d4c137447be4c7556500c2f8bf2Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen/* @UNSAFE: whole file */
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen void (*timeout_cb)(void *);
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen struct _istream *_stream = (struct _istream *) stream;
dee43975a70bcdb9dc83d34d6a2b177d37bb7194Timo Sirainen if (fstream->autoclose_fd && _stream->fd != -1) {
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct _istream *_stream = (struct _istream *) stream;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen p_free(_stream->iostream.pool, _stream->w_buffer);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void _set_max_buffer_size(struct _iostream *stream, size_t max_size)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void _set_blocking(struct _iostream *stream, int timeout_msecs,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
3b49aee9ced3b0370a3be396aca53acd5f21418cTimo Sirainen net_set_nonblock(fstream->istream.fd, timeout_msecs == 0);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void i_stream_grow_buffer(struct _istream *stream, size_t bytes)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen stream->buffer_size = nearest_power(stream->buffer_size);
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen stream->buffer_size > fstream->max_buffer_size)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen stream->buffer_size = fstream->max_buffer_size;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen p_realloc(stream->iostream.pool, stream->w_buffer,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainenstatic void i_stream_compress(struct _istream *stream)
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen memmove(stream->w_buffer, stream->w_buffer + stream->skip,
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
24e5e4526d8f5cbc056ab97fd0d154d0936d7a5eTimo Sirainen /* remove the unused bytes from beginning of buffer */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen stream->buffer_size < fstream->max_buffer_size) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* buffer is full - grow it */
7a24bdc1a5e2d5368c2569b4852192f2bdb5a31fTimo Sirainen i_stream_grow_buffer(stream, I_STREAM_MIN_SIZE);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (ret == 0 && timeout_time > 0 && time(NULL) > timeout_time) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* timeouted */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen fstream->timeout_cb(fstream->timeout_context);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (errno == ECONNRESET || errno == ETIMEDOUT) {
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* treat as disconnection */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen } while (ret == 0 && STREAM_IS_BLOCKING(fstream));
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic void _seek(struct _istream *stream, uoff_t v_offset)
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen fstream->skip_left += v_offset - stream->istream.v_offset;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainenstatic uoff_t _get_size(struct _istream *stream)
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen struct file_istream *fstream = (struct file_istream *) stream;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (fstream->file && fstat(stream->fd, &st) == 0 && S_ISREG(st.st_mode))
939a0d82523538b2de38a02bc9f790a67b7ebf47Timo Sirainenstruct istream *i_stream_create_file(int fd, pool_t pool,
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen fstream = p_new(pool, struct file_istream, 1);
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen fstream->istream.iostream.set_max_buffer_size = _set_max_buffer_size;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen fstream->istream.iostream.set_blocking = _set_blocking;
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen /* get size of fd if it's a file */
4ece61edd7c266a4b8f3b290a7f0a3cb3d13ca0fTimo Sirainen if (fstat(fd, &st) == 0 && S_ISREG(st.st_mode))