Hi all,

I've been working on getting the proton-c library to build on Solaris, and I 
have had to implement a few workarounds. I'd like to get the group's opinion on 
these changes, and hopefully get some sort of official Solaris support going.

First and foremost, I hit the following error upon compiling posix/io.c:

#error "Don't know how to turn off SIGPIPE on this platform"

As the error indicates, Solaris does not have a way to turn off SIGPIPE. My 
workaround here was to simply not attempt to ignore SIGPIPE:

@@ -246,7 +252,16 @@ static inline int pn_create_socket(int af) {
   return sock;
}
#else
-#error "Don't know how to turn off SIGPIPE on this platform"
+/*#error "Don't know how to turn off SIGPIPE on this platform"*/
+ssize_t pn_send(pn_io_t *io, pn_socket_t socket, const void *buf, size_t len) {
+  ssize_t count = send(socket, buf, len, 0);
+  io->wouldblock = count < 0 && (errno == EAGAIN || errno == EWOULDBLOCK);
+  return count;
+}
+
+static inline int pn_create_socket(int af) {
+  return socket(af, SOCK_STREAM, getprotobyname("tcp")->p_proto);
+}
#endif
 ssize_t pn_recv(pn_io_t *io, pn_socket_t socket, void *buf, size_t size)

This is based on the assumption that given that SIGPIPE cannot be disabled on 
Solaris, most applications built for Solaris must have mechanisms in place to 
deal with SIGPIPE. What do others think?

The second issue I hit was that in pn_listen and pn_connect, the call to 
getaddrinfo always failed, unless I added a hint of ai_socktype=SOCK_STREAM:

--- a/proton-c/src/posix/io.c
+++ b/proton-c/src/posix/io.c
@@ -123,8 +123,11 @@ static inline int pn_create_socket(int af);
 pn_socket_t pn_listen(pn_io_t *io, const char *host, const char *port)
{
-  struct addrinfo *addr;
-  int code = getaddrinfo(host, port, NULL, &addr);
+  struct addrinfo hints = {0}, *addr;
+  int code;
+
+  hints.ai_socktype = SOCK_STREAM;
+  code = getaddrinfo(host, port, &hints, &addr);
   if (code) {
     pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s\n", host, 
port, gai_strerror(code));
     return PN_INVALID_SOCKET;
@@ -163,8 +166,11 @@ pn_socket_t pn_listen(pn_io_t *io, const char *host, const 
char *port)
 pn_socket_t pn_connect(pn_io_t *io, const char *host, const char *port)
{
-  struct addrinfo *addr;
-  int code = getaddrinfo(host, port, NULL, &addr);
+  struct addrinfo hints = {0}, *addr;
+  int code;
+
+  hints.ai_socktype = SOCK_STREAM;
+  code = getaddrinfo(host, port, &hints, &addr);
   if (code) {
     pn_error_format(io->error, PN_ERR, "getaddrinfo(%s, %s): %s", host, port, 
gai_strerror(code));
     return PN_INVALID_SOCKET;

Would there be any reason not to provide this hint for all platforms?

The third major issue I encountered was that 'errno' was not being read in my 
multi-threaded application. This would manifest as constant failure returns 
from pn_connect - because the 'connect()' socket call was returning EINPROGRESS 
- but errno was always set to zero. To fix this I needed to pass the '-pthread' 
option to gcc, by adding '-DCMAKE_C_FLAGS=-pthread' to the cmake command line. 
Perhaps this option could be set inside the CMakeLists.txt itself, but I am not 
familiar with cmake. If anybody can suggest how the the -pthread argument can 
be integrated into cmake, I would be happy to try it out.

I would appreciate any feedback anyone might have.

Thanks
Sahir

Reply via email to