ostream.h revision 34d5077c37dc6224a2d430a72ae51a3f38e9e4f6
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* All of the istream was successfully sent to ostream. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* Caller needs to wait for more input from non-blocking istream. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* Caller needs to wait for output to non-blocking ostream.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen o_stream_set_flush_pending() is automatically called. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* Read from istream failed. See istream->stream_errno. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* Write to ostream failed. See ostream->stream_errno. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* Number of bytes sent via o_stream_send*() and similar functions.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen This is counting the input data. For example with a compressed
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen ostream this is counting the uncompressed bytes. The compressed
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen bytes could be counted from the parent ostream's offset.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Seeking to a specified offset only makes sense if there is no
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen difference between input and output data sizes (e.g. there are no
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen wrapper ostreams changing the data). */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* errno for the last operation send/seek operation. cleared before
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen each call. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* overflow is set when some of the data given to send()
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen functions was neither sent nor buffered. It's never unset inside
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen ostream code. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen /* o_stream_send() writes all the data or returns failure */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns 1 if all data is sent (not necessarily flushed), 0 if not.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Pretty much the only real reason to return 0 is if you wish to send more
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen data to client which isn't buffered, eg. o_stream_send_istream(). */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainentypedef int stream_flush_callback_t(void *context);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainentypedef void ostream_callback_t(void *context);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Create new output stream from given file descriptor.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen If max_buffer_size is 0, an "optimal" buffer size is used (max 128kB). */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct ostream *o_stream_create_fd(int fd, size_t max_buffer_size);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* The fd is set to -1 immediately to avoid accidentally closing it twice. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct ostream *o_stream_create_fd_autoclose(int *fd, size_t max_buffer_size);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Create an output stream from a regular file which begins at given offset.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen If offset==(uoff_t)-1, the current offset isn't known. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Siraineno_stream_create_fd_file(int fd, uoff_t offset, bool autoclose_fd);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct ostream *o_stream_create_fd_file_autoclose(int *fd, uoff_t offset);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Create an output stream to a buffer. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct ostream *o_stream_create_buffer(buffer_t *buf);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Create an output streams that always fails the writes. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct ostream *o_stream_create_error(int stream_errno);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Siraineno_stream_create_error_str(int stream_errno, const char *fmt, ...)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Create an output stream that simply passes through data. This is mainly
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen useful as a wrapper when combined with destroy callbacks. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstruct ostream *o_stream_create_passthrough(struct ostream *output);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Set name (e.g. path) for output stream. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_set_name(struct ostream *stream, const char *name);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Get output stream's name. Returns "" if stream has no name. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst char *o_stream_get_name(struct ostream *stream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Return file descriptor for stream, or -1 if none is available. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns error string for the previous error. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenconst char *o_stream_get_error(struct ostream *stream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Close this stream (but not its parents) and unreference it. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_destroy(struct ostream **stream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Reference counting. References start from 1, so calling o_stream_unref()
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen destroys the stream if o_stream_ref() is never used. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Unreferences the stream and sets stream pointer to NULL. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Call the given callback function when stream is destroyed. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_add_destroy_callback(struct ostream *stream,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#define o_stream_add_destroy_callback(stream, callback, context) \
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Remove the destroy callback. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_remove_destroy_callback(struct ostream *stream,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Mark the stream and all of its parent streams closed. Nothing will be
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen sent after this call. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Set IO_WRITE callback. Default will just try to flush the output and
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen finishes when the buffer is empty. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_set_flush_callback(struct ostream *stream,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen#define o_stream_set_flush_callback(stream, callback, context) \
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen CALLBACK_TYPECHECK(callback, int (*)(typeof(context))), \
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_unset_flush_callback(struct ostream *stream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Change the maximum size for stream's output buffer to grow. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns the current max. buffer size. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainensize_t o_stream_get_max_buffer_size(struct ostream *stream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Delays sending as far as possible, writing only full buffers. Also sets
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen TCP_CORK on if supported. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Try to flush the buffer by calling o_stream_flush() and remove TCP_CORK.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen Note that after this o_stream_flush() must be called, unless the stream
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen ignores errors. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenbool o_stream_is_corked(struct ostream *stream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Try to flush the output stream. If o_stream_nsend*() had been used and
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen the stream had overflown, return error. Returns 1 if all data is sent,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen 0 there's still buffered data, -1 if error. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Set "flush pending" state of stream. If set, the flush callback is called
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen when more data is allowed to be sent, even if the buffer itself is empty. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_set_flush_pending(struct ostream *stream, bool set);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns number of bytes currently in buffer. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainensize_t o_stream_get_buffer_used_size(const struct ostream *stream) ATTR_PURE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns number of bytes we can still write without failing. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainensize_t o_stream_get_buffer_avail_size(const struct ostream *stream) ATTR_PURE;
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Seek to specified position from beginning of file. This works only for
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen files. Returns 1 if successful, -1 if error. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenint o_stream_seek(struct ostream *stream, uoff_t offset);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Returns number of bytes sent, -1 = error */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenssize_t o_stream_send(struct ostream *stream, const void *data, size_t size);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenssize_t o_stream_sendv(struct ostream *stream, const struct const_iovec *iov,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int iov_count);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenssize_t o_stream_send_str(struct ostream *stream, const char *str);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Send with delayed error handling. o_stream_flush() or
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen o_stream_ignore_last_errors() must be called after these functions before
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen the stream is destroyed. If any of the data can't be sent due to stream's
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen buffer getting full, all further nsends are ignores and o_stream_flush()
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen will fail. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_nsend(struct ostream *stream, const void *data, size_t size);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_nsendv(struct ostream *stream, const struct const_iovec *iov,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen unsigned int iov_count);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_nsend_str(struct ostream *stream, const char *str);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenstatic inline int o_stream_nfinish(struct ostream *stream)
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Marks the stream's error handling as completed to avoid i_panic() on
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_ignore_last_errors(struct ostream *stream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* If error handling is disabled, the i_panic() on destroy is never called.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen This function can be called immediately after the stream is created.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen When creating wrapper streams, they copy this behavior from the parent
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_set_no_error_handling(struct ostream *stream, bool set);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Send all of the instream to outstream.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen On non-failure instream is skips over all data written to outstream.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen This means that the number of bytes written to outstream is always equal to
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen the number of bytes skipped in instream.
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen It's also possible to use this function to copy data within same file
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen descriptor, even if the source and destination overlaps. If the file must
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen be grown, you have to do it manually before calling this function. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Siraineno_stream_send_istream(struct ostream *outstream, struct istream *instream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Same as o_stream_send_istream(), but assume that reads and writes will
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen succeed. If not, o_stream_flush() will fail with the correct error
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen message (even istream's). */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenvoid o_stream_nsend_istream(struct ostream *outstream, struct istream *instream);
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* Write data to specified offset. Returns 0 if successful, -1 if error. */
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainenint o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen/* If there are any I/O loop items associated with the stream, move all of
b8a1347a9ea2cecf0d16f24748c2600fea8c7158Timo Sirainen them to current_ioloop. */