378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen /* All of the istream was successfully sent to ostream. */
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen /* Caller needs to wait for more input from non-blocking istream. */
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen /* Caller needs to wait for output to non-blocking ostream.
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen o_stream_set_flush_pending() is automatically called. */
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen /* Read from istream failed. See istream->stream_errno. */
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen /* Write to ostream failed. See ostream->stream_errno. */
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen /* Number of bytes sent via o_stream_send*() and similar functions.
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen This is counting the input data. For example with a compressed
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen ostream this is counting the uncompressed bytes. The compressed
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen bytes could be counted from the parent ostream's offset.
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen Seeking to a specified offset only makes sense if there is no
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen difference between input and output data sizes (e.g. there are no
bf87a5247ca33660ab8f20c12556ad16d7159395Timo Sirainen wrapper ostreams changing the data). */
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen /* errno for the last operation send/seek operation. cleared before
6cc0546c058f3e6253c6f99727b28dd602712974Timo Sirainen each call. */
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen /* overflow is set when some of the data given to send()
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen functions was neither sent nor buffered. It's never unset inside
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen ostream code. */
8b2cf1c1bd8ddcea0525b62fd35ba76e136828a1Timo Sirainen /* o_stream_send() writes all the data or returns failure */
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen/* Returns 1 if all data is sent (not necessarily flushed), 0 if not.
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen Pretty much the only real reason to return 0 is if you wish to send more
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen data to client which isn't buffered, eg. o_stream_send_istream(). */
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainentypedef int stream_flush_callback_t(void *context);
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainentypedef void ostream_callback_t(void *context);
9b7eeffb5752b500ac62ba1fd01c4a8c4ada14e9Timo Sirainen/* Create new output stream from given file descriptor.
9b7eeffb5752b500ac62ba1fd01c4a8c4ada14e9Timo Sirainen If max_buffer_size is 0, an "optimal" buffer size is used (max 128kB). */
e93184a9055c2530366dfe617e07199603c399ddMartti Rannanjärvistruct ostream *o_stream_create_fd(int fd, size_t max_buffer_size);
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainen/* The fd is set to -1 immediately to avoid accidentally closing it twice. */
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainenstruct ostream *o_stream_create_fd_autoclose(int *fd, size_t max_buffer_size);
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Sirainen/* Create an output stream from a regular file which begins at given offset.
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Sirainen If offset==(uoff_t)-1, the current offset isn't known. */
93fa87cf1a96c4f279ec4f5c311820313ba12c34Timo Siraineno_stream_create_fd_file(int fd, uoff_t offset, bool autoclose_fd);
43834f87bf431198f986e86052a4f6e558fdb07dTimo Sirainenstruct ostream *o_stream_create_fd_file_autoclose(int *fd, uoff_t offset);
b565a6a7a66fb9f224d00c06a950e3c1c585c18eTimo Sirainen/* Create an output stream to a buffer. */
b565a6a7a66fb9f224d00c06a950e3c1c585c18eTimo Sirainenstruct ostream *o_stream_create_buffer(buffer_t *buf);
0c1835a90dd1dcedaeaedd1cd91672299cbeb5beTimo Sirainen/* Create an output streams that always fails the writes. */
0c1835a90dd1dcedaeaedd1cd91672299cbeb5beTimo Sirainenstruct ostream *o_stream_create_error(int stream_errno);
f4735bf7ec2019fdc730e9ebdb39e5a4ea580405Timo Siraineno_stream_create_error_str(int stream_errno, const char *fmt, ...)
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainen/* Create an output stream that simply passes through data. This is mainly
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainen useful as a wrapper when combined with destroy callbacks. */
981139bb2e446bb2050c1158614725f8413fd709Timo Sirainenstruct ostream *o_stream_create_passthrough(struct ostream *output);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen/* Set name (e.g. path) for output stream. */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenvoid o_stream_set_name(struct ostream *stream, const char *name);
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainen/* Get output stream's name. Returns "" if stream has no name. */
8cb72c59d5ea4e9e5f638d7ec840bb853f5a188eTimo Sirainenconst char *o_stream_get_name(struct ostream *stream);
8b247780e911909a9fdc47f69ce6d1478902ad98Timo Sirainen/* Return file descriptor for stream, or -1 if none is available. */
f988b93c2ef773987bcdcbfb4cca39b955e3a392Timo Sirainen/* Returns error string for the previous error. */
862ec874f9373e3e499e237d3b9f71fdf1413feeTimo Sirainenconst char *o_stream_get_error(struct ostream *stream);
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen/* Close this stream (but not its parents) and unreference it. */
cd56a23e21f1df3f79648cf07e2f4385e2fadebbTimo Sirainenvoid o_stream_destroy(struct ostream **stream);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Reference counting. References start from 1, so calling o_stream_unref()
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen destroys the stream if o_stream_ref() is never used. */
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen/* Unreferences the stream and sets stream pointer to NULL. */
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen/* Call the given callback function when stream is destroyed. */
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainenvoid o_stream_add_destroy_callback(struct ostream *stream,
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen#define o_stream_add_destroy_callback(stream, callback, context) \
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainen/* Remove the destroy callback. */
eb98a038ca8b0ef33d1d11794803ce09547496faTimo Sirainenvoid o_stream_remove_destroy_callback(struct ostream *stream,
e2ce8d4a6ac5d82a906178148453e7613fab9ba0Timo Sirainen/* Mark the stream and all of its parent streams closed. Nothing will be
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen sent after this call. When using ostreams that require writing a trailer,
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen o_stream_finish() must be used before the stream is closed. When ostream
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen is destroyed, it's also closed but its parents aren't.
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen Closing the ostream (also via destroy) will first flush the ostream, and
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen afterwards requires one of: a) stream has failed, b) there is no more
5ec4fc44e8d4e2160f07b1a7f4fce1ccfec3f6c1Timo Sirainen buffered data, c) o_stream_set_no_error_handling() has been called. */
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen/* Set IO_WRITE callback. Default will just try to flush the output and
211ed7806d8715ec2280ffbf5d10f0d6e4f1beb2Timo Sirainen finishes when the buffer is empty. */
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenvoid o_stream_set_flush_callback(struct ostream *stream,
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainen#define o_stream_set_flush_callback(stream, callback, context) \
27a44fcfd8d19bffe0f267f20a2b5d3fe7600fddTimo Sirainen CALLBACK_TYPECHECK(callback, int (*)(typeof(context))), \
59151b71059df1190acd75d8717ed04a7920c862Timo Sirainenvoid o_stream_unset_flush_callback(struct ostream *stream);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Change the maximum size for stream's output buffer to grow. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenvoid o_stream_set_max_buffer_size(struct ostream *stream, size_t max_size);
556f95092c3bc850517d5ab2bb502024a55645f1Timo Sirainen/* Returns the current max. buffer size. */
556f95092c3bc850517d5ab2bb502024a55645f1Timo Sirainensize_t o_stream_get_max_buffer_size(struct ostream *stream);
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Delays sending as far as possible, writing only full buffers. Also sets
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen TCP_CORK on if supported. */
b688884f23be2333bea1a8bd4ee849336aebedaaTimo Sirainen/* Try to flush the buffer by calling o_stream_flush() and remove TCP_CORK.
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen Note that after this o_stream_flush() must be called, unless the stream
23c8c511f98924acfc7048e9dc4ccc982c34e320Timo Sirainen ignores errors. */
10ff47d5d6146995e16da00d36eca7d162064a7bTimo Sirainenbool o_stream_is_corked(struct ostream *stream);
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen/* Try to flush the output stream. If o_stream_nsend*() had been used and
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen the stream had overflown, return error. Returns 1 if all data is sent,
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen 0 there's still buffered data, -1 if error. */
b56679429b82dfea1ceecc40efea50dd8e4e0ac5Timo Sirainen/* Wrapper to easily both uncork and flush. */
b56679429b82dfea1ceecc40efea50dd8e4e0ac5Timo Sirainenstatic inline int o_stream_uncork_flush(struct ostream *stream)
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen/* Set "flush pending" state of stream. If set, the flush callback is called
5238111c460098d9cc8cc22527026138a278b9a4Timo Sirainen when more data is allowed to be sent, even if the buffer itself is empty. */
6ef7e31619edfaa17ed044b45861d106a86191efTimo Sirainenvoid o_stream_set_flush_pending(struct ostream *stream, bool set);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen/* Returns number of bytes currently in buffer. */
68a4946b12583b88fa802e52ebee45cd96056772Timo Sirainensize_t o_stream_get_buffer_used_size(const struct ostream *stream) ATTR_PURE;
de954ff15b495be13007a8aca2c09fd1d356a283Timo Sirainen/* Returns number of bytes we can still write without failing. */
de954ff15b495be13007a8aca2c09fd1d356a283Timo Sirainensize_t o_stream_get_buffer_avail_size(const struct ostream *stream) ATTR_PURE;
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen/* Seek to specified position from beginning of file. This works only for
ecc81625167ed96c04c02aa190a1ea5baa65b474Timo Sirainen files. Returns 1 if successful, -1 if error. */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenint o_stream_seek(struct ostream *stream, uoff_t offset);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainen/* Returns number of bytes sent, -1 = error */
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenssize_t o_stream_send(struct ostream *stream, const void *data, size_t size);
2767104d81e97a109f0aa9758792bfa1da325a97Timo Sirainenssize_t o_stream_sendv(struct ostream *stream, const struct const_iovec *iov,
0ce5f96804e81cb0f857e7df32c0272f1eed9377Timo Sirainen unsigned int iov_count);
c0435c854a0e7246373b9752d163095cc4fbe985Timo Sirainenssize_t o_stream_send_str(struct ostream *stream, const char *str);
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen/* Send with delayed error handling. o_stream_flush() or
ceb43cc04edb94445fab8f914bc4da6d740403d1Timo Sirainen o_stream_ignore_last_errors() must be called after these functions before
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen the stream is destroyed. If any of the data can't be sent due to stream's
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen buffer getting full, all further nsends are ignores and o_stream_flush()
9de176ef7f3d28ff486c2a8805110b84389e4f19Timo Sirainen will fail. */
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_nsend(struct ostream *stream, const void *data, size_t size);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_nsendv(struct ostream *stream, const struct const_iovec *iov,
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen unsigned int iov_count);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_nsend_str(struct ostream *stream, const char *str);
84717f00ddbf5cd0ebe3f285090d5e97e458e19cTimo Sirainen/* Mark the ostream as finished and flush it. If the ostream has a footer,
84717f00ddbf5cd0ebe3f285090d5e97e458e19cTimo Sirainen it's written here. Any further write attempts to the ostream will
84717f00ddbf5cd0ebe3f285090d5e97e458e19cTimo Sirainen assert-crash. Returns the same as o_stream_flush(). Afterwards any calls to
84717f00ddbf5cd0ebe3f285090d5e97e458e19cTimo Sirainen this function are identical to o_stream_flush(). */
d6193a892452ae87548f5745dada01f82816765dTimo Sirainen/* Specify whether calling o_stream_finish() will cause the parent stream to
d6193a892452ae87548f5745dada01f82816765dTimo Sirainen be finished as well. The default is yes. */
d6193a892452ae87548f5745dada01f82816765dTimo Sirainenvoid o_stream_set_finish_also_parent(struct ostream *stream, bool set);
d6193a892452ae87548f5745dada01f82816765dTimo Sirainen/* Specify whether calling o_stream_finish() on a child stream will cause
d6193a892452ae87548f5745dada01f82816765dTimo Sirainen this stream to be finished as well. The default is yes. */
d6193a892452ae87548f5745dada01f82816765dTimo Sirainenvoid o_stream_set_finish_via_child(struct ostream *stream, bool set);
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen/* Marks the stream's error handling as completed to avoid i_panic() on
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_ignore_last_errors(struct ostream *stream);
7660a5183e89459d255dc5873894ff08806711d5Timo Sirainen/* Abort writing to the ostream, also marking any previous error handling as
7660a5183e89459d255dc5873894ff08806711d5Timo Sirainen completed. If the stream hasn't already failed, sets the stream_errno=EPIPE.
7660a5183e89459d255dc5873894ff08806711d5Timo Sirainen This is necessary when aborting write to streams that require finishing. */
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen/* If error handling is disabled, the i_panic() on destroy is never called.
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen This function can be called immediately after the stream is created.
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainen When creating wrapper streams, they copy this behavior from the parent
e2a88d59c0d47d63ce1ad5b1fd95e487124a3fd4Timo Sirainenvoid o_stream_set_no_error_handling(struct ostream *stream, bool set);
378e6cb162b355d6f103526505bc00b9a78962e7Timo Sirainen/* Send all of the instream to outstream.
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen On non-failure instream is skips over all data written to outstream.
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen This means that the number of bytes written to outstream is always equal to
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen the number of bytes skipped in instream.
03f5c621d06d6b6d77a145196c9633a7aa64dc78Timo Sirainen It's also possible to use this function to copy data within same file
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen descriptor, even if the source and destination overlaps. If the file must
6adf683655750bcb809275cd65dc75fd12214198Timo Sirainen be grown, you have to do it manually before calling this function. */
378e6cb162b355d6f103526505bc00b9a78962e7Timo Siraineno_stream_send_istream(struct ostream *outstream, struct istream *instream);
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen/* Same as o_stream_send_istream(), but assume that reads and writes will
34d5077c37dc6224a2d430a72ae51a3f38e9e4f6Timo Sirainen succeed. If not, o_stream_flush() will fail with the correct error
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainen message (even istream's). */
b90fb7f78aca271243c26074ddd6587cce112a1eTimo Sirainenvoid o_stream_nsend_istream(struct ostream *outstream, struct istream *instream);
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainen/* Write data to specified offset. Returns 0 if successful, -1 if error. */
8cdb3234fe3c77e477c7a0e6934678f58fc54d4dTimo Sirainenint o_stream_pwrite(struct ostream *stream, const void *data, size_t size,
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen/* Return the last timestamp when something was successfully sent to the
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen ostream's internal buffers (no guarantees that anything was sent further).
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainen The timestamp is 0 if nothing has ever been written. */
f8b6c3d6bc9d63665af5e0a3c8b604438e4c3a4eTimo Sirainenvoid o_stream_get_last_write_time(struct ostream *stream, struct timeval *tv_r);
71da447014454c84828d9dface77219875554d7dTimo Sirainen/* If there are any I/O loop items associated with the stream, move all of
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Bosch them to provided/current ioloop. */
8aa8399893c66b40e2790a4568256807a6ec6742Stephan Boschvoid o_stream_switch_ioloop_to(struct ostream *stream, struct ioloop *ioloop);