#pragma once #include struct prot_msg { uint8_t *data; // malloc'd buffer, should be free'd by recipient size_t length; // length of data }; // The interface exposed here is NOT thread-safe. Having multiple // threads in in the same process working with prot is unsafe, since // internal communication assumes one calling thread. // This is a channel, a "connection", to another party. struct prot; // Returns a file descriptor that becomes readable in select(2) if // there may be a new event on the channel. Do not actually read data // from this file descriptor. int prot_get_select_fd(struct prot *ch); // Terminates the connection, blocks until acknowledged. Then channel // is closed and freed. void prot_terminate(struct prot *ch); // Create channel on which the server can accept new connections using // prot_accept(). Only one accept channel can be made in one process. struct prot* prot_create_accept_channel(); // Returns a new connection with a client if such an establishment // request is ready; an acknowledgement is replied to the request. If // no new connection is ready at the moment, the function returns // NULL. (This is a non-blocking function.) struct prot* prot_accept(struct prot *ach); // Creates a client connection to a server with the specified address. // Blocks until the establishment request is acknowledged. struct prot* prot_connect(uint32_t server_addr); // Receives a waiting message; returns {.data=NULL} on error, in which // case errno is set: EAGAIN = no message ready; ECONNRESET = peer // closed connection; other values: internal errors. // Channel should not be an accept channel. This is a non-blocking // function. struct prot_msg prot_recv(struct prot *ch); // Sends the given data on the given channel. Channel should not be an // accept channel. Returns 0 on success and -1 on error, in which case // errno is set: ECONNRESET = peer closed connection; other values: // internal errors. int prot_send(struct prot *ch, const void *data, size_t length);