3 * (Convenience wrapper around BSD sockets)
5 * Copyright (C) 2004, 2015 by Chris Jaekl
13 #include <sys/socket.h>
14 #include <sys/types.h>
16 #include "qdunittest.h"
18 #include "qderrhandler.h"
22 void qdSockCheckClose(struct qdSocket *sock)
24 if ((sock->closeRequested) && (0 == sock->toWrite)) {
25 // printf("\nCLOSE(%d)\n", sock->sd);
27 memset(sock, 0x00, sizeof(struct qdSocket));
33 void qdSockClose(struct qdSocket *sock)
41 sock->closeRequested = TRUE;
42 qdSockCheckClose(sock);
45 // Returns 0 on success, non-zero on failure
46 int qdSockConnect(struct qdSocket *sock, const char * host, int port)
50 struct sockaddr_in sa;
53 assert(0 == sock->sd);
54 assert(0 == sock->closeRequested);
56 memset(&sa, 0x00, sizeof(struct sockaddr_in));
58 he = gethostbyname(host);
60 qdAbort("gethostbyname() failed", h_errno);
64 sa.sin_family = AF_INET;
65 sa.sin_port = htons(port);
66 memcpy(&(sa.sin_addr), (he->h_addr_list[0]), sizeof(struct in_addr));
68 sock->sd = socket(AF_INET, SOCK_STREAM, 0);
70 qdAbort("Could not create client socket.", sock->sd);
73 ret = connect(sock->sd, (struct sockaddr *)&sa, sizeof(sa));
75 return ret; // Could not connect
80 ssize_t qdSockFlush(struct qdSocket *to)
87 written = write(to->sd, to->buf, to->toWrite);
89 assert(written <= to->toWrite);
90 to->toWrite -= written;
94 for (idx = 0; idx < to->toWrite; ++idx) {
100 else if (((-1) == written) && ((EAGAIN == errno) || (EWOULDBLOCK == errno))) {
101 // Socket is busy, leave pending write for later
105 // Some unexpected error has occurred on the socket.
107 to->toWrite = 0; // abandon unwritten data that we cannot flush
108 // TODO: optionally log this condition, so that a sysadmin can see what's happening
115 void qdSockInit(struct qdSocket *sock)
117 memset(sock, 0x00, sizeof(struct qdSocket));
120 ssize_t qdSockWrite(struct qdSocket *to, char * buf, ssize_t n)
126 if ((to->toWrite + n) > QD_SOCK_BUF_SIZE) {
127 // TODO: implement this functionality
128 qdAbort("Unimplemented: write buffer overflow. Aborting.", 0);
131 // TODO: should be smarter here (use a circular buffer to avoid O(n^2) worst-case performance)
132 memcpy((to->buf + to->toWrite), buf, n);
135 return qdSockFlush(to);