static int ConnectionSend(ConnectionRef conn, const PacketHeader *packet) // Send a packet to the server. Use this when you're not expecting a // reply. // // conn must be a valid connection // packet must be a valid, ready-to-send, packet // Returns an errno-style error code { int err; assert(conn != NULL); assert(conn->fSockFD != -1); // connection must not be shut down // conn->fSockCF may or may not be NULL; it's OK to send a packet when listening // because there's no reply; OTOH, you can't do an RPC while listening because // an unsolicited packet might get mixed up with the RPC reply. assert(packet != NULL); assert(packet->fMagic == kPacketMagic); assert(packet->fSize >= sizeof(PacketHeader)); // Simply send the packet down the socket. err = MoreUNIXWrite(conn->fSockFD, packet, packet->fSize, NULL); return err; }
extern int MoreUNIXCopyDescriptorToDescriptor(int source, int dest) // See comment in header. { int err; bool done; char * buffer; static const size_t kBufferSize = 64 * 1024; assert(source >= 0); assert(dest >= 0); err = 0; buffer = (char *) malloc(kBufferSize); if (buffer == NULL) { err = ENOMEM; } if (err == 0) { done = false; do { size_t bytesRead; err = MoreUNIXRead(source, buffer, kBufferSize, &bytesRead); if (err == EPIPE) { done = true; err = 0; } if (err == 0) { err = MoreUNIXWrite(dest, buffer, bytesRead, NULL); } } while (err == 0 && !done); } free(buffer); return err; }