Example #1
0
static int sp_inproc_ctx_connect (const char *addr, void *hint,
    struct sp_epbase **epbase)
{
    int rc;
    struct sp_list_item *it;
    struct sp_inprocc *inprocc;
    struct sp_inprocb *inprocb;
    struct sp_msgpipe *pipe;

    /*  Insert the entry into the endpoint repository. */
    inprocc = sp_alloc (sizeof (struct sp_inprocc), "inprocc");
    alloc_assert (inprocc);
    rc = sp_inprocc_init (inprocc, addr, hint);
    if (sp_slow (rc != 0))
        return rc;
    sp_list_insert (&self.connected, &inprocc->list,
        sp_list_end (&self.connected));

    /*  During this process a pipe may be created. */
    for (it = sp_list_begin (&self.bound);
          it != sp_list_end (&self.bound);
          it = sp_list_next (&self.bound, it)) {
        inprocb = sp_cont (it, struct sp_inprocb, list);
        if (strcmp (addr, inprocb->addr) == 0) {
            pipe = sp_alloc (sizeof (struct sp_msgpipe), "msgpipe");
            alloc_assert (pipe);
            sp_msgpipe_init (pipe, inprocb, inprocc);
            break;
        }
    }

    sp_assert (epbase);
    *epbase = &inprocc->epbase;
    return 0;
}
Example #2
0
void sp_stream_init (struct sp_stream *self, struct sp_epbase *epbase,
    struct sp_usock *usock)
{
    int rc;

    /*  Redirect the underlying socket's events to this state machine. */
    self->usock = usock;
    self->sink = &sp_stream_state_start;
    self->original_sink = sp_usock_setsink (usock, &self->sink);

    /*  Initialise the pipe to communicate with the user. */
    /*  TODO: Socket type may reject the pipe. What then? */
    rc = sp_pipebase_init (&self->pipebase, &sp_stream_pipebase_vfptr, epbase);
    sp_assert (rc == 0);

    /*  Start the header timeout timer. */
    sp_timer_init (&self->hdr_timeout, &self->sink, usock->cp);
    sp_timer_start (&self->hdr_timeout, 1000);

    /*  Send the protocol header. */
    sp_usock_send (usock, "\0\0SP\0\0\0\0", 8);

    /*  Receive the protocol header from the peer. */
    sp_usock_recv (usock, self->hdr, 8);
}
Example #3
0
static void sp_stream_received (const struct sp_cp_sink **self,
    struct sp_usock *usock)
{
    int rc;
    struct sp_stream *stream;
    uint64_t size;

    stream = sp_cont (self, struct sp_stream, sink);
    switch (stream->instate) {
    case SP_STREAM_INSTATE_HDR:
        size = sp_getll (stream->inhdr);
        rc = sp_msgref_init (&stream->inmsg, (size_t) size);
        errnum_assert (rc == 0, -rc);
        if (!size) {
            sp_pipebase_received (&stream->pipebase);
            break;
        }
        stream->instate = SP_STREAM_INSTATE_BODY;
        sp_usock_recv (stream->usock, sp_msgref_data (&stream->inmsg),
            (size_t) size);
        break;
    case SP_STREAM_INSTATE_BODY:
        sp_pipebase_received (&stream->pipebase);
        break;
    default:
        sp_assert (0);
    }
}
Example #4
0
int sp_pipe_recv (struct sp_pipe *self, void *buf, size_t *len)
{
    struct sp_pipebase *pipebase;

    pipebase = (struct sp_pipebase*) self;
    sp_assert (pipebase->instate == SP_PIPEBASE_INSTATE_IDLE);
    pipebase->instate = SP_PIPEBASE_INSTATE_RECEIVING;
    pipebase->vfptr->recv (pipebase, buf, len);
    if (sp_fast (pipebase->instate == SP_PIPEBASE_INSTATE_RECEIVED)) {
        pipebase->instate = SP_PIPEBASE_INSTATE_IDLE;
        return 0;
    }
    sp_assert (pipebase->instate == SP_PIPEBASE_INSTATE_RECEIVING);
    pipebase->instate = SP_PIPEBASE_INSTATE_ASYNC;
    return SP_PIPEBASE_RELEASE;
}
Example #5
0
int sp_pipe_send (struct sp_pipe *self, const void *buf, size_t len)
{
    struct sp_pipebase *pipebase;

    pipebase = (struct sp_pipebase*) self;
    sp_assert (pipebase->outstate == SP_PIPEBASE_OUTSTATE_IDLE);
    pipebase->outstate = SP_PIPEBASE_OUTSTATE_SENDING;
    pipebase->vfptr->send (pipebase, buf, len);
    if (sp_fast (pipebase->outstate == SP_PIPEBASE_OUTSTATE_SENT)) {
        pipebase->outstate = SP_PIPEBASE_OUTSTATE_IDLE;
        return 0;
    }
    sp_assert (pipebase->outstate == SP_PIPEBASE_OUTSTATE_SENDING);
    pipebase->outstate = SP_PIPEBASE_OUTSTATE_ASYNC;
    return SP_PIPEBASE_RELEASE;
}
Example #6
0
File: array.c Project: maknoll/jzon
void spec_string_with_escaped_quotes(void)
{
    const char *json_string = "[\"The Word \\\"Foo\\\" is so damn bar!\"]";

    struct jzon *jzon = jzon_parse(json_string);
    sp_assert(jzon != NULL);

    jzon_free(jzon);
}
Example #7
0
int sp_pipebase_init (struct sp_pipebase *self,
    const struct sp_pipebase_vfptr *vfptr, struct sp_epbase *epbase)
{
    sp_assert (epbase->sock);
    self->vfptr = vfptr;
    self->instate = SP_PIPEBASE_INSTATE_DEACTIVATED;
    self->outstate = SP_PIPEBASE_OUTSTATE_DEACTIVATED;
    self->epbase = epbase;
    return sp_sock_add (self->epbase->sock, (struct sp_pipe*) self);
}
Example #8
0
void sp_pipebase_received (struct sp_pipebase *self)
{
    if (sp_fast (self->instate == SP_PIPEBASE_INSTATE_RECEIVING)) {
        self->instate = SP_PIPEBASE_INSTATE_RECEIVED;
        return;
    }
    sp_assert (self->instate == SP_PIPEBASE_INSTATE_ASYNC);
    self->instate = SP_PIPEBASE_INSTATE_IDLE;
    if (self->epbase->sock)
        sp_sock_in (self->epbase->sock, (struct sp_pipe*) self);
}
Example #9
0
void sp_pipebase_sent (struct sp_pipebase *self)
{
    if (sp_fast (self->outstate == SP_PIPEBASE_OUTSTATE_SENDING)) {
        self->outstate = SP_PIPEBASE_OUTSTATE_SENT;
        return;
    }
    sp_assert (self->outstate == SP_PIPEBASE_OUTSTATE_ASYNC);
    self->outstate = SP_PIPEBASE_OUTSTATE_IDLE;
    if (self->epbase->sock)
        sp_sock_out (self->epbase->sock, (struct sp_pipe*) self);
}
Example #10
0
void worker (void *arg)
{
    int rc;
    int s;
    char buf [3];

    s = sp_socket (AF_SP, SP_PAIR);
    errno_assert (s != -1);
    rc = sp_recv (s, buf, sizeof (buf), 0);
    sp_assert (rc == -1 && sp_errno () == ETERM);
    rc = sp_close (s);
    errno_assert (rc == 0);
}
Example #11
0
int sp_term (void)
{
#if defined SP_HAVE_WINDOWS
    int rc;
#endif
    int i;

    sp_glock_lock ();

    /*  If there are still references to the library, do nothing, just
        decrement the reference count. */
    --sp_ctx_refcount;
    if (sp_ctx_refcount) {
        sp_glock_unlock ();
        return 0;
    }

    /*  Notify all the open sockets about the process shutdown and wait till
        all of them are closed. */
    sp_mutex_lock (&self.sync);
    if (self.nsocks) {
        for (i = 0; i != self.max_socks; ++i)
            if (self.socks [i])
                sp_sock_zombify (self.socks [i]);
        self.zombie = 1;
        sp_cond_wait (&self.termcond, &self.sync);
    }
    sp_mutex_unlock (&self.sync);

    /*  Final deallocation of the global resources. */
    sp_cond_term (&self.termcond);
    sp_list_term (&self.socktypes);
    sp_list_term (&self.transports);
    sp_mutex_term (&self.sync);
    sp_free (self.socks);
    self.socks = NULL;

    /*  Shut down the memory allocation subsystem. */
    sp_alloc_term ();

    /*  On Windows, uninitialise the socket library. */
#if defined SP_HAVE_WINDOWS
    rc = WSACleanup ();
    sp_assert (rc == 0);
#endif

    sp_glock_unlock ();

    return 0;
}
Example #12
0
int sp_shutdown (int s, int how)
{
    int rc;

    SP_BASIC_CHECKS;

    rc = sp_sock_shutdown (self.socks [s], how);
    if (sp_slow (rc < 0)) {
        errno = -rc;
        return -1;
    }
    sp_assert (rc == 0);

    return 0;
}
Example #13
0
static void sp_stream_err (const struct sp_cp_sink **self,
    struct sp_usock *usock, int errnum)
{
    struct sp_stream *stream;
    const struct sp_cp_sink **original_sink;

    stream = sp_cont (self, struct sp_stream, sink);
    original_sink = stream->original_sink;

    /*  Terminate the session object. */
    sp_stream_term (stream);

    /*  Notify the parent state machine about the failure. */
    sp_assert ((*original_sink)->err);
    (*original_sink)->err (original_sink, usock, errnum);
}
Example #14
0
static void sp_stream_hdr_timeout (const struct sp_cp_sink **self,
    struct sp_timer *timer)
{
    struct sp_stream *stream;
    const struct sp_cp_sink **original_sink;

    /*  The initial protocol header exchange have timed out. */
    stream = sp_cont (self, struct sp_stream, sink);
    original_sink = stream->original_sink;

    /*  Terminate the session object. */
    sp_stream_term (stream);

    /*  Notify the parent state machine about the failure. */
    sp_assert ((*original_sink)->err);
    (*original_sink)->err (original_sink, stream->usock, ETIMEDOUT);
}
Example #15
0
static void sp_stream_activate (struct sp_stream *self)
{
    self->sink = &sp_stream_state_active;
    sp_timer_stop (&self->hdr_timeout);

    /*  Check the header. */
    /*  TODO: If it does not conform, drop the connection. */
    if (memcmp (self->hdr, "\0\0SP\0\0\0\0", 8) != 0)
        sp_assert (0);

    /*  Connection is ready for sending. Make outpipe available
        to the SP socket. */
    sp_pipebase_activate (&self->pipebase);

    /*  Start waiting for incoming messages. First, read the 8-byte size. */
    self->instate = SP_STREAM_INSTATE_HDR;
    sp_usock_recv (self->usock, self->inhdr, 8);
}
Example #16
0
File: array.c Project: maknoll/jzon
void spec_simple_array(void)
{
    struct jzon *jzon = jzon_parse("[1, 2, 3]");
    sp_assert(jzon != NULL);
    sp_assert(jzon->type == JZON_ARRAY);
    sp_assert(jzon->array != NULL);
    sp_assert_equal_i(jzon->array->capacity, 3);
    sp_assert(jzon_get_number(jzon->array->elements[0]) == 1.0);
    sp_assert(jzon_get_number(jzon->array->elements[1]) == 2.0);
    sp_assert(jzon_get_number(jzon->array->elements[2]) == 3.0);

    jzon_free(jzon);
}
Example #17
0
static int sp_inproc_ctx_bind (const char *addr, void *hint,
    struct sp_epbase **epbase)
{
    int rc;
    struct sp_list_item *it;
    struct sp_inprocb *inprocb;
    struct sp_inprocc *inprocc;
    struct sp_msgpipe *pipe;

    /*  Check whether the endpoint isn't already bound. */
    /*  TODO:  This is an O(n) algorithm! */
    for (it = sp_list_begin (&self.bound); it != sp_list_end (&self.bound);
          it = sp_list_next (&self.bound, it)) {
        inprocb = sp_cont (it, struct sp_inprocb, list);
        if (strncmp (addr, inprocb->addr, SP_INPROCB_NAMELEN_MAX) == 0)
            return -EADDRINUSE;
    }

    /*  Insert the entry into the endpoint repository. */
    inprocb = sp_alloc (sizeof (struct sp_inprocb), "inprocb");
    alloc_assert (inprocb);
    rc = sp_inprocb_init (inprocb, addr, hint);
    if (sp_slow (rc != 0))
        return rc;
    sp_list_insert (&self.bound, &inprocb->list, sp_list_end (&self.bound));

    /*  During this process new pipes may be created. */
    for (it = sp_list_begin (&self.connected);
          it != sp_list_end (&self.connected);
          it = sp_list_next (&self.connected, it)) {
        inprocc = sp_cont (it, struct sp_inprocc, list);
        if (strncmp (addr, inprocc->addr, SP_INPROCC_NAMELEN_MAX) == 0) {
            pipe = sp_alloc (sizeof (struct sp_msgpipe), "msgpipe");
            alloc_assert (pipe);
            sp_msgpipe_init (pipe, inprocb, inprocc);
        }
    }

    sp_assert (epbase);
    *epbase = &inprocb->epbase;
    return 0;
}
Example #18
0
int sp_recv (int s, void *buf, size_t len, int flags)
{
    int rc;

    SP_BASIC_CHECKS;

    if (sp_slow (!buf && len)) {
        errno = EFAULT;
        return -1;
    }

    rc = sp_sock_recv (self.socks [s], buf, &len, flags);
    if (sp_slow (rc < 0)) {
        errno = -rc;
        return -1;
    }
    sp_assert (rc == 0);

    return (int) len;
}
Example #19
0
static void sp_stream_hdr_sent (const struct sp_cp_sink **self,
    struct sp_usock *usock)
{
    struct sp_stream *stream;

    stream = sp_cont (self, struct sp_stream, sink);

    if (stream->sink == &sp_stream_state_received) {
        sp_stream_activate (stream);
        return;
    }

    if (stream->sink == &sp_stream_state_start) {
        stream->sink = &sp_stream_state_sent;
        return;
    }

    /*  This event is not defined in other states. */
    sp_assert (0);
}
Example #20
0
void sp_epbase_init (struct sp_epbase *self,
    const struct sp_epbase_vfptr *vfptr, const char *addr, void *hint)
{
    /*  Set up the virtual functions table. */
    self->vfptr = vfptr;

    /*  Remember which socket the endpoint belongs to. */
    self->sock = (struct sp_sock*) hint;

    /*  Store the textual for of the address. */
    sp_assert (strlen (addr) <= SP_SOCKADDR_MAX);
#if defined _MSC_VER
#pragma warning (push)
#pragma warning (disable:4996)
#endif
    strcpy (self->addr, addr);
#if defined _MSC_VER
#pragma warning (pop)
#endif
}
Example #21
0
static void sp_stream_sent (const struct sp_cp_sink **self,
    struct sp_usock *usock)
{
    struct sp_stream *stream;
    size_t size;

    stream = sp_cont (self, struct sp_stream, sink);
    switch (stream->outstate) {
    case SP_STREAM_OUTSTATE_HDR:
        size = sp_msgref_size (&stream->outmsg);
        stream->outstate = SP_STREAM_OUTSTATE_BODY;
        if (!size) {
            sp_pipebase_sent (&stream->pipebase);
            break;
        }
        sp_usock_send (stream->usock, sp_msgref_data (&stream->outmsg), size);
        break;
    case SP_STREAM_OUTSTATE_BODY:
        sp_pipebase_sent (&stream->pipebase);
        break;
    default:
        sp_assert (0);
    }
}
Example #22
0
void sp_msgqueue_term (struct sp_msgqueue *self)
{
    int rc;
    size_t sz;

    /*  Deallocate messages in the pipe. */
    while (1) {
        sz = 0;
        rc = sp_msgqueue_recv (self, NULL, &sz);
        if (rc == -EAGAIN)
            break;
    }

    /*  There are no more messages in the pipe so there's at most one chunk
        in the queue. Deallocate it. */
    sp_assert (self->in.chunk == self->out.chunk);
    sp_free (self->in.chunk);

    /*  Deallocate the cached chunk, if any. */
    if (self->cache)
        sp_free (self->cache);

    sp_mutex_term (&self->sync);
}
Example #23
0
int main ()
{
    int rc;
    int rep;
    int req1;
    int req2;
    int resend_ivl;
    char buf [7];

    /*  Test req/rep with raw socket types. */

    rc = sp_init ();
    errno_assert (rc == 0);
    rep = sp_socket (AF_SP_RAW, SP_REP);
    errno_assert (rep != -1);
    rc = sp_bind (rep, "inproc://a");
    errno_assert (rc >= 0);
    req1 = sp_socket (AF_SP_RAW, SP_REQ);
    errno_assert (req1 != -1);
    rc = sp_connect (req1, "inproc://a");
    errno_assert (rc >= 0);
    req2 = sp_socket (AF_SP_RAW, SP_REQ);
    errno_assert (req2 != -1);
    rc = sp_connect (req2, "inproc://a");
    errno_assert (rc >= 0);

    rc = sp_send (req2, "ABC", 3, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (rep, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 7);
    rc = sp_send (rep, buf, 7, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 7);
    rc = sp_recv (req2, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);

    rc = sp_send (req1, "ABC", 3, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (rep, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 7);
    rc = sp_send (rep, buf, 7, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 7);
    rc = sp_recv (req1, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);

    rc = sp_close (rep);
    errno_assert (rc == 0);
    rc = sp_close (req1);
    errno_assert (rc == 0);    
    rc = sp_close (req2);
    errno_assert (rc == 0);
    rc = sp_term ();
    errno_assert (rc == 0);

    /*  Test req/rep with full socket types. */

    rc = sp_init ();
    errno_assert (rc == 0);
    rep = sp_socket (AF_SP, SP_REP);
    errno_assert (rep != -1);
    rc = sp_bind (rep, "inproc://a");
    errno_assert (rc >= 0);
    req1 = sp_socket (AF_SP, SP_REQ);
    errno_assert (req1 != -1);
    rc = sp_connect (req1, "inproc://a");
    errno_assert (rc >= 0);
    req2 = sp_socket (AF_SP, SP_REQ);
    errno_assert (req2 != -1);
    rc = sp_connect (req2, "inproc://a");
    errno_assert (rc >= 0);

    rc = sp_send (rep, "ABC", 3, 0);
    sp_assert (rc == -1 && sp_errno () == EFSM);
    rc = sp_recv (req1, buf, sizeof (buf), 0);
    sp_assert (rc == -1 && sp_errno () == EFSM);

    rc = sp_send (req2, "ABC", 3, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (rep, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_send (rep, buf, 3, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (req2, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);

    rc = sp_send (req1, "ABC", 3, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (rep, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_send (rep, buf, 3, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (req1, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);

    rc = sp_close (rep);
    errno_assert (rc == 0);
    rc = sp_close (req1);
    errno_assert (rc == 0);    
    rc = sp_close (req2);
    errno_assert (rc == 0);
    rc = sp_term ();
    errno_assert (rc == 0);

    /*  Test re-sending of the request. */

    rc = sp_init ();
    errno_assert (rc == 0);
    rep = sp_socket (AF_SP, SP_REP);
    errno_assert (rep != -1);
    rc = sp_bind (rep, "inproc://a");
    errno_assert (rc >= 0);
    req1 = sp_socket (AF_SP, SP_REQ);
    errno_assert (req1 != -1);
    rc = sp_connect (req1, "inproc://a");
    errno_assert (rc >= 0);
    resend_ivl = 100;
    rc = sp_setsockopt (req1, SP_REQ, SP_RESEND_IVL,
        &resend_ivl, sizeof (resend_ivl));
    errno_assert (rc == 0);

    rc = sp_send (req1, "ABC", 3, 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (rep, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);
    rc = sp_recv (rep, buf, sizeof (buf), 0);
    errno_assert (rc >= 0);
    sp_assert (rc == 3);

    rc = sp_close (req1);
    errno_assert (rc == 0);
    rc = sp_close (rep);
    errno_assert (rc == 0);
    rc = sp_term ();
    errno_assert (rc == 0);

    return 0;
}
Example #24
0
void spec_sample_one(void)
{
    sp_assert(42);
    sp_assert_equal_i(23, 23);
}
Example #25
0
int sp_freemsg (void *msg)
{
    sp_assert (0);
}
Example #26
0
int sp_sock_setopt (struct sp_sock *self, int level, int option,
    const void *optval, size_t optvallen)
{
    int rc;
    struct sp_sockbase *sockbase;
    int *dst;

    sockbase = (struct sp_sockbase*) self;

    sp_cp_lock (&sockbase->cp);

    /*  If sp_term() was already called, return ETERM. */
    if (sp_slow (sockbase->flags & SP_SOCK_FLAG_ZOMBIE)) {
        sp_cp_unlock (&sockbase->cp);
        return -ETERM;
    }

    /*  Generic socket-level options. */
    if (level == SP_SOL_SOCKET) {
        switch (option) {
        case SP_LINGER:
            dst = &sockbase->linger;
            break;
        case SP_SNDBUF:
            dst = &sockbase->sndbuf;
            break;
        case SP_RCVBUF:
            dst = &sockbase->rcvbuf;
            break;
        case SP_SNDTIMEO:
            dst = &sockbase->sndtimeo;
            break;
        case SP_RCVTIMEO:
            dst = &sockbase->rcvtimeo;
            break;
        case SP_RECONNECT_IVL:
            dst = &sockbase->reconnect_ivl;
            break;
        case SP_RECONNECT_IVL_MAX:
            dst = &sockbase->reconnect_ivl_max;
            break;
        default:
            sp_cp_unlock (&sockbase->cp);
            return -ENOPROTOOPT;
        }
        if (optvallen != sizeof (int)) {
            sp_cp_unlock (&sockbase->cp);
            return -EINVAL;
        }
        *dst = *(int*) optval;
        sp_cp_unlock (&sockbase->cp);
        return 0;
    }

    /*  Protocol-specific socket options. */
    if (level > SP_SOL_SOCKET) {
        rc = sockbase->vfptr->setopt (sockbase, level, option,
            optval, optvallen);
        sp_cp_unlock (&sockbase->cp);
        return rc;
    }

    /*  Transport-specific options. */
    if (level < SP_SOL_SOCKET) {
        sp_cp_unlock (&sockbase->cp);
        return -ENOPROTOOPT;
    }

    sp_assert (0);
}
Example #27
0
void spec_sample_two(void)
{
    sp_assert(23);
}
Example #28
0
int sp_sendmsg (int s, void *msg, int flags)
{
    sp_assert (0);
}
Example #29
0
int sp_sock_getopt (struct sp_sock *self, int level, int option,
    void *optval, size_t *optvallen, int internal)
{
    int rc;
    struct sp_sockbase *sockbase;
    int *src;

    sockbase = (struct sp_sockbase*) self;

    if (!internal)
        sp_cp_lock (&sockbase->cp);

    /*  If sp_term() was already called, return ETERM. */
    if (!internal && sp_slow (sockbase->flags & SP_SOCK_FLAG_ZOMBIE)) {
        sp_cp_unlock (&sockbase->cp);
        return -ETERM;
    }

    /*  Generic socket-level options. */
    if (level == SP_SOL_SOCKET) {
        switch (option) {
        case SP_LINGER:
            src = &sockbase->linger;
            break;
        case SP_SNDBUF:
            src = &sockbase->sndbuf;
            break;
        case SP_RCVBUF:
            src = &sockbase->rcvbuf;
            break;
        case SP_SNDTIMEO:
            src = &sockbase->sndtimeo;
            break;
        case SP_RCVTIMEO:
            src = &sockbase->rcvtimeo;
            break;
        case SP_RECONNECT_IVL:
            src = &sockbase->reconnect_ivl;
            break;
        case SP_RECONNECT_IVL_MAX:
            src = &sockbase->reconnect_ivl_max;
            break;
        default:
            if (!internal)
                sp_cp_unlock (&sockbase->cp);
            return -ENOPROTOOPT;
        }
        memcpy (optval, src,
            *optvallen < sizeof (int) ? *optvallen : sizeof (int));
        *optvallen = sizeof (int);
        if (!internal)
            sp_cp_unlock (&sockbase->cp);
        return 0;
    }

    /*  Protocol-specific socket options. */
    if (level > SP_SOL_SOCKET) {
        rc = sockbase->vfptr->getopt (sockbase, level, option,
            optval, optvallen);
        if (!internal)
            sp_cp_unlock (&sockbase->cp);
        return rc;
    }

    /*  Transport-specific options. */
    if (level < SP_SOL_SOCKET) {
        if (!internal)
            sp_cp_unlock (&sockbase->cp);
        return -ENOPROTOOPT;
    }

    sp_assert (0);
}
Example #30
0
int sp_recvmsg (int s, void **msg, int flags)
{
    sp_assert (0);
}