static int s_expect_reply (zpipes_client_t *self, int message_id) { zpipes_msg_t *reply = zpipes_msg_recv (self->dealer); if (!reply) return -1; int rc = zpipes_msg_id (reply) == message_id? 0: -1; zpipes_msg_destroy (&reply); return rc; }
static int s_expect_reply (zsock_t *dealer, int message_id) { zpipes_msg_t *reply = zpipes_msg_recv (dealer); if (!reply) { puts ("- interrupted"); return -1; } int rc = zpipes_msg_id (reply) == message_id? 0: -1; if (rc) zsys_warning ("expected %d, got %d/%s\n", message_id, zpipes_msg_id (reply), zpipes_msg_command (reply)); zpipes_msg_destroy (&reply); return rc; }
void zpipes_client_destroy (zpipes_client_t **self_p) { assert (self_p); if (*self_p) { zpipes_client_t *self = *self_p; if (self->dealer) { zpipes_msg_send_close (self->dealer); // Get reply, ignore it: could be ok or an error depending // on what the client did before. zpipes_msg_t *reply = zpipes_msg_recv (self->dealer); zpipes_msg_destroy (&reply); } zsock_destroy (&self->dealer); free (self); *self_p = NULL; } }
ssize_t zpipes_client_read (zpipes_client_t *self, void *data, size_t size, int timeout) { assert (self); zpipes_msg_send_read (self->dealer, size, timeout); zpipes_msg_t *reply = zpipes_msg_recv (self->dealer); if (!reply) { self->error = EINTR; return -1; // Interrupted } ssize_t rc = 0; if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_OK) { zchunk_t *chunk = zpipes_msg_chunk (reply); ssize_t bytes = zchunk_size (chunk); assert (bytes <= size); memcpy (data, zchunk_data (chunk), bytes); rc = bytes; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_END) rc = 0; else if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_TIMEOUT) { self->error = EAGAIN; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_READ_FAILED) { // TODO: better error code? // This happens if we close a pipe while there's a pending read self->error = EINTR; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_INVALID) { self->error = EBADF; rc = -1; } zpipes_msg_destroy (&reply); return rc; }
ssize_t zpipes_client_write (zpipes_client_t *self, void *data, size_t size, int timeout) { assert (self); zchunk_t *chunk = zchunk_new (data, size); assert (chunk); zpipes_msg_t *request = zpipes_msg_new (ZPIPES_MSG_WRITE); zpipes_msg_set_chunk (request, &chunk); zpipes_msg_set_timeout (request, timeout); zpipes_msg_send (&request, self->dealer); zpipes_msg_t *reply = zpipes_msg_recv (self->dealer); if (!reply) { self->error = EINTR; return -1; // Interrupted } ssize_t rc = size; if (zpipes_msg_id (reply) == ZPIPES_MSG_WRITE_TIMEOUT) { self->error = EAGAIN; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_WRITE_FAILED) { // TODO: better error code? // This happens if we close a pipe while there's a pending write self->error = EINTR; rc = -1; } else if (zpipes_msg_id (reply) == ZPIPES_MSG_INVALID) { self->error = EBADF; rc = -1; } zpipes_msg_destroy (&reply); return rc; }