ostream.h revision 862ec874f9373e3e499e237d3b9f71fdf1413fee
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#ifndef OSTREAM_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define OSTREAM_H
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#include "ioloop.h"
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainenstruct ostream {
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen uoff_t offset;
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen /* errno for the last operation send/seek operation. cleared before
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen each call. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int stream_errno;
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* errno of the last failed send/seek. never cleared. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen int last_failed_errno;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen /* overflow is set when some of the data given to send()
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen functions was neither sent nor buffered. It's never unset inside
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen ostream code. */
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen unsigned int overflow:1;
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen unsigned int closed:1;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen struct ostream_private *real_stream;
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen};
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns 1 if all data is sent (not necessarily flushed), 0 if not.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Pretty much the only real reason to return 0 is if you wish to send more
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen data to client which isn't buffered, eg. o_stream_send_istream(). */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainentypedef int stream_flush_callback_t(void *context);
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen/* Create new output stream from given file descriptor.
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainen If max_buffer_size is 0, an "optimal" buffer size is used (max 128kB). */
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Sirainenstruct ostream *
defb12ecd360df672ffb2f4dbf4d1218a0a9549cTimo Siraineno_stream_create_fd(int fd, size_t max_buffer_size, bool autoclose_fd);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Create an output stream from a regular file which begins at given offset.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen If offset==(uoff_t)-1, the current offset isn't known. */
04ab375449dd97eed50ada88dd0df2abab01cfeeTimo Sirainenstruct ostream *
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Siraineno_stream_create_fd_file(int fd, uoff_t offset, bool autoclose_fd);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Create an output stream to a buffer. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct ostream *o_stream_create_buffer(buffer_t *buf);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen/* Create an output streams that always fails the writes. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenstruct ostream *o_stream_create_error(int stream_errno);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Set name (e.g. path) for output stream. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid o_stream_set_name(struct ostream *stream, const char *name);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Get output stream's name. Returns "" if stream has no name. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *o_stream_get_name(struct ostream *stream);
84f80d9231b6ddc80ebfae425fd3674620fdf746Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Return file descriptor for stream, or -1 if none is available. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint o_stream_get_fd(struct ostream *stream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns error string for the previous error (stream_errno,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen not last_failed_errno). */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenconst char *o_stream_get_error(struct ostream *stream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen/* Close this stream (but not its parents) and unreference it. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid o_stream_destroy(struct ostream **stream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Reference counting. References start from 1, so calling o_stream_unref()
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen destroys the stream if o_stream_ref() is never used. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid o_stream_ref(struct ostream *stream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Unreferences the stream and sets stream pointer to NULL. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid o_stream_unref(struct ostream **stream);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen/* Mark the stream and all of its parent streams closed. Nothing will be
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen sent after this call. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid o_stream_close(struct ostream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Set IO_WRITE callback. Default will just try to flush the output and
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen finishes when the buffer is empty. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid o_stream_set_flush_callback(struct ostream *stream,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen stream_flush_callback_t *callback,
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen void *context) ATTR_NULL(3);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen#define o_stream_set_flush_callback(stream, callback, context) \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen o_stream_set_flush_callback(stream + \
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen CALLBACK_TYPECHECK(callback, int (*)(typeof(context))), \
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen (stream_flush_callback_t *)callback, context)
8d630c15a8ed6f85553467c3a231a273defca5f6Timo Sirainenvoid o_stream_unset_flush_callback(struct ostream *stream);
bf661a542d17273066e720b4f75868a1ff975a4cTimo Sirainen/* Change the maximum size for stream's output buffer to grow. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Delays sending as far as possible, writing only full buffers. Also sets
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen TCP_CORK on if supported. */
ab0155cbec1286e1cd00a0e01d78e0f3ca34cea6Timo Sirainenvoid o_stream_cork(struct ostream *stream);
ab0155cbec1286e1cd00a0e01d78e0f3ca34cea6Timo Sirainenvoid o_stream_uncork(struct ostream *stream);
ab0155cbec1286e1cd00a0e01d78e0f3ca34cea6Timo Sirainen/* Try to flush the output stream. Returns 1 if all sent, 0 if not,
ab0155cbec1286e1cd00a0e01d78e0f3ca34cea6Timo Sirainen -1 if error. */
ab0155cbec1286e1cd00a0e01d78e0f3ca34cea6Timo Sirainenint o_stream_flush(struct ostream *stream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Set "flush pending" state of stream. If set, the flush callback is called
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen when more data is allowed to be sent, even if the buffer itself is empty. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid o_stream_set_flush_pending(struct ostream *stream, bool set);
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainen/* Returns number of bytes currently in buffer. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainensize_t o_stream_get_buffer_used_size(const struct ostream *stream) ATTR_PURE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Returns number of bytes we can still write without failing. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainensize_t o_stream_get_buffer_avail_size(const struct ostream *stream) ATTR_PURE;
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Seek to specified position from beginning of file. This works only for
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen files. Returns 1 if successful, -1 if error. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint o_stream_seek(struct ostream *stream, uoff_t offset);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen/* Returns number of bytes sent, -1 = error */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenssize_t o_stream_send(struct ostream *stream, const void *data, size_t size);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenssize_t o_stream_sendv(struct ostream *stream, const struct const_iovec *iov,
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen unsigned int iov_count);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenssize_t o_stream_send_str(struct ostream *stream, const char *str);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen/* Send with delayed error handling. o_stream_has_errors() or
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen o_stream_ignore_last_errors() must be called after these functions before
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen the stream is destroyed. */
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenvoid o_stream_nsend(struct ostream *stream, const void *data, size_t size);
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainenvoid o_stream_nsendv(struct ostream *stream, const struct const_iovec *iov,
d756ebcfa96bd7cff02097c8f26df9df368b81b1Timo Sirainen unsigned int iov_count);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid o_stream_nsend_str(struct ostream *stream, const char *str);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenvoid o_stream_nflush(struct ostream *stream);
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* Flushes the stream and returns -1 if stream->last_failed_errno is
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen non-zero. Marks the stream's error handling as completed. errno is also set
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainen to last_failed_errno. */
b2c1349cf07410aefab0f5b17153af9e5cfcf48fTimo Sirainenint o_stream_nfinish(struct ostream *stream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Marks the stream's error handling as completed to avoid i_panic() on
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen destroy. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenvoid o_stream_ignore_last_errors(struct ostream *stream);
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen/* If error handling is disabled, the i_panic() on destroy is never called.
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainen This function can be called immediately after the stream is created.
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen When creating wrapper streams, they copy this behavior from the parent
faed8babca9914257f34fb2e603d74016d563b2dTimo Sirainen stream. */
16c89b1260c9d07c01c83a9219424d3727069b2eTimo Sirainenvoid o_stream_set_no_error_handling(struct ostream *stream, bool set);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Send data from input stream. Returns number of bytes sent, or -1 if error.
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen Note that this function may block if either instream or outstream is
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen blocking.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen Also note that this function may not add anything to the output buffer, so
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen if you want the flush callback to be called when more data can be written,
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen you'll need to call o_stream_set_flush_pending() manually.
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen It's also possible to use this function to copy data within same file
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen descriptor. If the file must be grown, you have to do it manually before
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen calling this function. */
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainenoff_t o_stream_send_istream(struct ostream *outstream,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen struct istream *instream);
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen/* Write data to specified offset. Returns 0 if successful, -1 if error. */
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainenint o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen uoff_t offset);
e015e2f7e7f48874495f9df8b0dd192b7ffcb5ccTimo Sirainen
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainen/* If there are any I/O loop items associated with the stream, move all of
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen them to current_ioloop. */
fdc557286bc9f92c5f3bb49096ff6e2bcec0ea79Timo Sirainenvoid o_stream_switch_ioloop(struct ostream *stream);
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen
a3ee5ce6ecc8e228ee69300fdd562d7ac8be89a7Timo Sirainen#endif
0cb2e8eb55e70f8ebe1e8349bdf49e4cbe5d8834Timo Sirainen