void *context;
};
+static void
+iostream_proxy_completion(struct iostream_proxy *proxy,
+ enum iostream_proxy_side side,
+ enum iostream_pump_status pump_status)
+{
+ enum iostream_proxy_status status;
+
+ switch (pump_status) {
+ case IOSTREAM_PUMP_STATUS_INPUT_EOF:
+ status = IOSTREAM_PROXY_STATUS_INPUT_EOF;
+ break;
+ case IOSTREAM_PUMP_STATUS_INPUT_ERROR:
+ status = IOSTREAM_PROXY_STATUS_INPUT_ERROR;
+ break;
+ case IOSTREAM_PUMP_STATUS_OUTPUT_ERROR:
+ status = IOSTREAM_PROXY_STATUS_OTHER_SIDE_OUTPUT_ERROR;
+ break;
+ default:
+ i_unreached();
+ }
+ proxy->callback(side, status, proxy->context);
+}
+
static
void iostream_proxy_rtl_completion(enum iostream_pump_status status,
struct iostream_proxy *proxy)
{
- bool success = (status == IOSTREAM_PUMP_STATUS_INPUT_EOF);
- proxy->callback(IOSTREAM_PROXY_SIDE_RIGHT, success, proxy->context);
+ iostream_proxy_completion(proxy, IOSTREAM_PROXY_SIDE_RIGHT, status);
}
static
void iostream_proxy_ltr_completion(enum iostream_pump_status status,
struct iostream_proxy *proxy)
{
- bool success = (status == IOSTREAM_PUMP_STATUS_INPUT_EOF);
- proxy->callback(IOSTREAM_PROXY_SIDE_LEFT, success, proxy->context);
+ iostream_proxy_completion(proxy, IOSTREAM_PROXY_SIDE_LEFT, status);
}
struct iostream_proxy *
struct iostream_proxy;
enum iostream_proxy_side {
+ /* Input is coming from left side's istream and is proxied to
+ right side's ostream. */
IOSTREAM_PROXY_SIDE_LEFT,
+ /* Input is coming from right side's istream and is proxied to
+ left side's ostream. */
IOSTREAM_PROXY_SIDE_RIGHT
};
+enum iostream_proxy_status {
+ /* proxy succeeded - EOF received from istream and all output was
+ written successfully to ostream. */
+ IOSTREAM_PROXY_STATUS_INPUT_EOF,
+ /* proxy failed - istream returned an error */
+ IOSTREAM_PROXY_STATUS_INPUT_ERROR,
+ /* proxy failed - other side's ostream returned an error */
+ IOSTREAM_PROXY_STATUS_OTHER_SIDE_OUTPUT_ERROR,
+};
+
+/* The callback maybe be called once or twice. Usually the first call should
+ destroy the proxy, but it's possible for it to just wait for the other
+ direction of the proxy to finish as well and call the callback.
+
+ Note that the sides mean which side is the reader side. If the failure is in
+ ostream, it's the other side's ostream that failed. So for example if
+ side=left, the write failed to the right side's ostream.
+
+ The callback is called when the proxy succeeds or fails due to
+ iostreams. (It's not called if proxy is destroyed.) */
typedef void iostream_proxy_callback_t(enum iostream_proxy_side side,
- bool success,
+ enum iostream_proxy_status status,
void *context);
struct iostream_proxy *
iostream_proxy_callback_t *callback, void *context);
#define iostream_proxy_set_completion_callback(proxy, callback, context) \
iostream_proxy_set_completion_callback(proxy, (iostream_proxy_callback_t *)callback, context + \
- CALLBACK_TYPECHECK(callback, void (*)(enum iostream_proxy_side side, bool, typeof(context))))
+ CALLBACK_TYPECHECK(callback, void (*)(enum iostream_proxy_side side, enum iostream_proxy_status, typeof(context))))
void iostream_proxy_ref(struct iostream_proxy *proxy);
void iostream_proxy_unref(struct iostream_proxy **proxy_r);