aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt3
-rw-r--r--src/core/socket.c4
-rw-r--r--src/nng.c7
-rw-r--r--src/nng.h1
-rw-r--r--src/nng_compat.c209
-rw-r--r--src/nng_compat.h147
-rw-r--r--src/platform/posix/posix_ipc.c1
-rw-r--r--src/platform/posix/posix_net.c1
-rw-r--r--src/platform/posix/posix_pipe.c2
-rw-r--r--src/platform/posix/posix_thread.c1
10 files changed, 368 insertions, 8 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 82d7205d..e9e8a31b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -27,6 +27,9 @@ set (NNG_SOURCES
nng.c
nng.h
+ nng_compat.c
+ nng_compat.h
+
core/defs.h
core/clock.c
diff --git a/src/core/socket.c b/src/core/socket.c
index f451ba45..24078941 100644
--- a/src/core/socket.c
+++ b/src/core/socket.c
@@ -741,7 +741,7 @@ nni_sock_senderr(nni_sock *sock, int err)
int
nni_sock_setopt(nni_sock *sock, int opt, const void *val, size_t size)
{
- int rv = ENOTSUP;
+ int rv = NNG_ENOTSUP;
nni_mtx_lock(&sock->s_mx);
if (sock->s_closing) {
@@ -784,7 +784,7 @@ nni_sock_setopt(nni_sock *sock, int opt, const void *val, size_t size)
int
nni_sock_getopt(nni_sock *sock, int opt, void *val, size_t *sizep)
{
- int rv = ENOTSUP;
+ int rv = NNG_ENOTSUP;
nni_mtx_lock(&sock->s_mx);
if (sock->s_closing) {
diff --git a/src/nng.c b/src/nng.c
index c6dfb7f4..28da1f20 100644
--- a/src/nng.c
+++ b/src/nng.c
@@ -260,6 +260,13 @@ nng_listen(nng_socket sid, const char *addr, nng_endpoint *epp, int flags)
int
+nng_endpoint_close(nng_endpoint eid)
+{
+ // XXX: FIXME: lookup endpoint by id, and then close it.
+ return (NNG_ENOTSUP);
+}
+
+int
nng_setopt(nng_socket sid, int opt, const void *val, size_t sz)
{
nni_sock *sock;
diff --git a/src/nng.h b/src/nng.h
index eb9a2d87..f9290996 100644
--- a/src/nng.h
+++ b/src/nng.h
@@ -20,7 +20,6 @@
extern "C" {
#endif
-#include <errno.h>
#include <stddef.h>
#include <stdint.h>
diff --git a/src/nng_compat.c b/src/nng_compat.c
index 94a0b3aa..7c0f6871 100644
--- a/src/nng_compat.c
+++ b/src/nng_compat.c
@@ -8,7 +8,10 @@
//
#include "nng.h"
-#include "nn_compat.h"
+#include "nng_compat.h"
+
+#include <string.h>
+#include <stdio.h>
// This file provides the "public" API. This is a thin wrapper around
// internal API functions. We use the public prefix instead of internal,
@@ -19,7 +22,209 @@
// Pretty much every function calls the nni_platform_init to check against
// fork related activity.
+static struct {
+ int perr;
+ int nerr;
+}
+nn_errnos[] = {
+ { NNG_EINTR, EINTR },
+ { NNG_ENOMEM, ENOMEM },
+ { NNG_EINVAL, EINVAL },
+ { NNG_EBUSY, EBUSY },
+ { NNG_ETIMEDOUT, ETIMEDOUT },
+ { NNG_ECONNREFUSED, ECONNREFUSED },
+ { NNG_ECLOSED, EBADF },
+ { NNG_EAGAIN, EAGAIN },
+ { NNG_ENOTSUP, ENOTSUP },
+ { NNG_EADDRINUSE, EADDRINUSE },
+ { NNG_ESTATE, EFSM },
+ { NNG_ENOENT, ENOENT },
+ { NNG_EPROTO, EPROTO },
+ { NNG_EUNREACHABLE, EHOSTUNREACH },
+ { NNG_EADDRINVAL, EADDRNOTAVAIL },
+ { NNG_EPERM, EACCES },
+ { NNG_EMSGSIZE, EMSGSIZE },
+ { NNG_ECONNABORTED, ECONNABORTED },
+ { NNG_ECONNRESET, ECONNRESET },
+ { 0, 0 },
+};
+
+const char *
+nn_strerror(int err)
+{
+ int i;
+ static char msgbuf[32];
+
+ for (i = 0; nn_errnos[i].perr != 0; i++) {
+ if (nn_errnos[i].perr == err) {
+ return (nng_strerror(nn_errnos[i].nerr));
+ }
+ }
+ if (err == EIO) {
+ return ("Unknown I/O error");
+ }
+
+ // Arguablye we could use strerror() here, but we should only
+ // be getting errnos we understand at this point.
+ (void) snprintf(msgbuf, sizeof (msgbuf), "Unknown error %d", err);
+ return (msgbuf);
+}
+
+
+static void
+nn_seterror(int err)
+{
+ int i;
+
+ for (i = 0; nn_errnos[i].nerr != 0; i++) {
+ if (nn_errnos[i].nerr == err) {
+ errno = nn_errnos[i].perr;
+ return;
+ }
+ }
+ // No idea...
+ errno = EIO;
+}
+
+
int
nn_socket(int domain, int protocol)
{
-} \ No newline at end of file
+ nng_socket sock;
+ int rv;
+
+ if ((domain != AF_SP) && (domain != AF_SP_RAW)) {
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ if ((rv = nng_open(&sock, protocol)) != 0) {
+ nn_seterror(rv);
+ return (-1);
+ }
+ if (domain == AF_SP_RAW) {
+ int raw = 1;
+ rv = nng_setopt(sock, NNG_OPT_RAW, &raw, sizeof (raw));
+ if (rv != 0) {
+ nn_seterror(rv);
+ nng_close(sock);
+ return (-1);
+ }
+ }
+ return ((int) sock);
+}
+
+
+int
+nn_close(int s)
+{
+ int rv;
+
+ if ((rv = nng_close((nng_socket) s)) != 0) {
+ nn_seterror(rv);
+ return (-1);
+ }
+ return (0);
+}
+
+
+int
+nn_bind(int s, const char *addr)
+{
+ int rv;
+ nng_endpoint ep;
+
+ if ((rv = nng_listen((nng_socket) s, addr, &ep, NNG_FLAG_SYNCH)) != 0) {
+ nn_seterror(rv);
+ return (-1);
+ }
+ return ((int) ep);
+}
+
+
+int
+nn_connect(int s, const char *addr)
+{
+ int rv;
+ nng_endpoint ep;
+
+ if ((rv = nng_dial((nng_socket) s, addr, &ep, 0)) != 0) {
+ nn_seterror(rv);
+ return (-1);
+ }
+ return ((int) ep);
+}
+
+
+int
+nn_shutdown(int s, int ep)
+{
+ int rv;
+
+ // Socket is wired into the endpoint... so passing a bad endpoint
+ // ID can result in affecting the wrong socket. But this requires
+ // a buggy application, and because we don't recycle endpoints
+ // until wrap, its unlikely to actually come up in practice.
+
+ if ((rv = nng_endpoint_close((nng_endpoint) ep)) != 0) {
+ nn_seterror(rv);
+ return (-1);
+ }
+ return (0);
+}
+
+
+int
+nn_send(int s, const void *buf, size_t len, int flags)
+{
+ int rv;
+
+ switch (flags) {
+ case NN_DONTWAIT:
+ flags = NNG_FLAG_NONBLOCK;
+ break;
+ case 0:
+ break;
+ default:
+ nn_seterror(NNG_EINVAL);
+ return (-1);
+ }
+ if (len == NN_MSG) {
+ // FIX ME -- this is a message allocated another way...
+ nn_seterror(NNG_ENOTSUP);
+ return (-1);
+ }
+ rv = nng_send((nng_socket) s, (void *)buf, len, flags);
+ if (rv != 0) {
+ nn_seterror(rv);
+ return (-1);
+ }
+ return ((int)len);
+}
+
+
+int
+nn_recv(int s, void *buf, size_t len, int flags)
+{
+ int rv;
+
+ switch (flags) {
+ case NN_DONTWAIT:
+ flags = NNG_FLAG_NONBLOCK;
+ break;
+ case 0:
+ break;
+ default:
+ nn_seterror(NNG_EINVAL);
+ return (-1);
+ }
+ if (len == NN_MSG) {
+ nn_seterror(NNG_ENOTSUP);
+ return (-1);
+ }
+ rv = nng_recv((nng_socket) s, buf, &len, flags);
+ if (rv != 0) {
+ nn_seterror(rv);
+ return (-1);
+ }
+ return ((int)len);
+}
diff --git a/src/nng_compat.h b/src/nng_compat.h
index 7b859831..020a342a 100644
--- a/src/nng_compat.h
+++ b/src/nng_compat.h
@@ -43,6 +43,25 @@ extern "C" {
#define AF_SP 1
#define AF_SP_RAW 2
+// Protocol stuff
+#define NN_PROTO_PAIR 1
+#define NN_PROTO_PUBSUB 2
+#define NN_PROTO_REQREP 3
+#define NN_PROTO_PIPELINE 5
+#define NN_PROTO_SURVEY 6
+#define NN_PROTO_BUS 7
+
+#define NN_PAIR (NN_PROTO_PAIR * 16 + 1)
+#define NN_PUB (NN_PROTO_PUBSUB * 16 + 0)
+#define NN_SUB (NN_PROTO_PUBSUB * 16 + 1)
+#define NN_REQ (NN_PROTO_REQREP * 16 + 0)
+#define NN_REP (NN_PROTO_REQREP * 16 + 1)
+#define NN_PUSH (NN_PROTO_PIPELINE * 16 + 0)
+#define NN_PULL (NN_PROTO_PIPELINE * 16 + 1)
+#define NN_SURVEYOR (NN_PROTO_SURVEY * 16 + 2)
+#define NN_RESPONDENT (NN_PROTO_SURVEY * 16 + 3)
+#define NN_BUS (NN_PROTO_BUS * 16 + 1)
+
#define NN_SOCKADDR_MAX 128
#define NN_SOL_SOCKET 0
@@ -53,6 +72,109 @@ extern "C" {
#define PROTO_SP 1
#define SP_HDR 1
+// Errnos. Legacy nanomsg uses posix errnos where possible.
+// If a define is not set, use add NN_ERRBASE. nng does not
+// return all of these values, so there may be some loss of
+// of information for edge cases, but we don't expect that to be
+// a problem really.
+#define NN_ERRBASE (0x10000000)
+#ifndef ENOTSUP
+#define ENOTSUP (NN_ERRBASE+1)
+#endif
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT (NN_ERRBASE+2)
+#endif
+#ifndef ENOBUFS
+#define ENOBUFS (NN_ERRBASE+3)
+#endif
+#ifndef ENETDOWN
+#define ENETDOWN (NN_ERRBASE+4)
+#endif
+#ifndef EADDRINUSE
+#define EADDRINUSE (NN_ERRBASE+5)
+#endif
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL (NN_ERRBASE+6)
+#endif
+#ifndef ENOTSOCK
+#define ENOTSOCK (NN_ERRBASE+7)
+#endif
+#ifndef EAGAIN
+#define EAGAIN (NN_ERRBASE+8)
+#endif
+#ifndef EBADF
+#define EBADF (NN_ERRBASE+9)
+#endif
+#ifndef EINVAL
+#define EINVAL (NN_ERRBASE+10)
+#endif
+#ifndef EMFILE
+#define EMFILE (NN_ERRBASE+11)
+#endif
+#ifndef EFAULT
+#define EFAULT (NN_ERRBASE+12)
+#endif
+#ifndef EACCES
+#define EACCES (NN_ERRBASE+13)
+#endif
+#ifndef ENETRESET
+#define ENETRESET (NN_ERRBASE+14)
+#endif
+#ifndef ENETUNREACH
+#define ENETUNREACH (NN_ERRBASE+15)
+#endif
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH (NN_ERRBASE+16)
+#endif
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT (NN_ERRBASE+17)
+#endif
+#ifndef EINPROGRESS
+#define EINPROGRESS (NN_ERRBASE+18)
+#endif
+#ifndef EPROTO
+#define EPROTO (NN_ERRBASE+19)
+#endif
+#ifndef ECONNREFUSED
+#define ECONNREFUSED (NN_ERRBASE+20)
+#endif
+#ifndef ENOTCONN
+#define ENOTCONN (NN_ERRBASE+21)
+#endif
+#ifndef EMSGSIZE
+#define EMSGSIZE (NN_ERRBASE+22)
+#endif
+#ifndef ETIMEDOUT
+#define ETIMEDOUT (NN_ERRBASE+23)
+#endif
+#ifndef ECONNABORTED
+#define ECONNABORTED (NN_ERRBASE+24)
+#endif
+#ifndef ECONNRESET
+#define ECONNRESET (NN_ERRBASE+25)
+#endif
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT (NN_ERRBASE+26)
+#endif
+#ifndef EISCONN
+#define EISCONN (NN_ERRBASE+27)
+#endif
+#ifndef ESOCKNOSUPPORT
+#define ESOCKNOSPPORT (NN_ERRBASE+28)
+#endif
+#ifndef ETERM
+#define ETERM (NN_ERRBASE+29)
+#endif
+#ifndef EFSM
+#define EFSM (NN_ERRBASE+30)
+#endif
+#ifndef ENOENT
+#define ENOENT (NN_ERRBASE+31)
+#endif
+#ifndef EIO
+#define EIO (NN_ERRBASE+32)
+#endif
+
// Socket options
#define NN_LINGER 1
#define NN_SNDBUF 2
@@ -72,14 +194,33 @@ extern "C" {
#define NN_RCVMAXSIZE 16
#define NN_MAXTTL 17
+// Protocol-specific options. To simplify thins we encode the protocol
+// level in the option.
+#define NN_SUB_UNSUBSCRIBE (NN_SUB * 16 + 1)
+#define NN_REQ_RESEND_IVL (NN_REQ * 16 + 1)
+#define NN_SURVEY_DEADLINE (NN_SURVEYOR * 16 + 1)
+
+// Level options for tranports
+#define NN_INPROC (-1)
+#define NN_IPC (-2)
+#define NN_IPC_SEC_ATTR 1
+#define NN_IPC_OUTBUFSZ 2
+#define NN_IPC_INBUFSZ 3
+#define NN_TCP (-3)
+#define NN_TCP_NODELAY 1
+#define NN_WS (-4)
+#define NN_WS_MSG_TYPE 1
+#define NN_WS_MSG_TYPE_TEXT 1
+#define NN_WS_MSG_TYPE_BINARY 2
+
// Poll stuff
-#define NN_POLLIN 1
-#define NN_POLLOUT 2
+#define NN_POLLIN 1
+#define NN_POLLOUT 2
struct nn_pollfd {
int fd;
uint16_t events;
uint16_t revents;
-}
+};
// Magical size for allocation
#define NN_MSG ((size_t) -1)
diff --git a/src/platform/posix/posix_ipc.c b/src/platform/posix/posix_ipc.c
index 584dc4a9..52474734 100644
--- a/src/platform/posix/posix_ipc.c
+++ b/src/platform/posix/posix_ipc.c
@@ -11,6 +11,7 @@
#ifdef PLATFORM_POSIX_IPC
+#include <errno.H>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
diff --git a/src/platform/posix/posix_net.c b/src/platform/posix/posix_net.c
index eb85669f..24b45819 100644
--- a/src/platform/posix/posix_net.c
+++ b/src/platform/posix/posix_net.c
@@ -11,6 +11,7 @@
#ifdef PLATFORM_POSIX_NET
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
diff --git a/src/platform/posix/posix_pipe.c b/src/platform/posix/posix_pipe.c
index 28cd909c..c86022ef 100644
--- a/src/platform/posix/posix_pipe.c
+++ b/src/platform/posix/posix_pipe.c
@@ -12,6 +12,8 @@
#ifdef PLATFORM_POSIX_PIPE
+#include <errno.h>
+
// This implementation of notification pipes works ~everywhere on POSIX,
// as it only relies on pipe() and non-blocking I/O.
diff --git a/src/platform/posix/posix_thread.c b/src/platform/posix/posix_thread.c
index fddc25da..72e1bcaf 100644
--- a/src/platform/posix/posix_thread.c
+++ b/src/platform/posix/posix_thread.c
@@ -13,6 +13,7 @@
#ifdef PLATFORM_POSIX_THREAD
+#include <errno.h>
#include <pthread.h>
#include <time.h>
#include <string.h>