openbmc/build/tmp/deploy/sdk/witherspoon-2019-08-08/sysroots/armv6-openbmc-linux-gnueabi/usr/src/debug/systemd/1_242+AUTOINC+db2e367bfc-r0/git/src/libsystemd/sd-netlink/netlink-socket.c
int socket_read_message(sd_netlink* rtnl)
{
    _cleanup_(sd_netlink_message_unrefp) sd_netlink_message* first = NULL;
    struct iovec iov = {};
    uint32_t group = 0;
    bool multi_part = false, done = false;
    struct nlmsghdr* new_msg;
    size_t len;
    int r;
    unsigned i = 0;
    const NLTypeSystem* type_system_root;

    assert(rtnl);
    assert(rtnl->rbuffer);
    assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));

    type_system_root = type_system_get_root(rtnl->protocol);

    /* read nothing, just get the pending message size */
    r = socket_recv_message(rtnl->fd, &iov, NULL, true);
    if (r <= 0)
        return r;
    else
        len = (size_t)r;

    /* make room for the pending message */
    if (!greedy_realloc((void**)&rtnl->rbuffer, &rtnl->rbuffer_allocated, len,
                        sizeof(uint8_t)))
        return -ENOMEM;

    iov = IOVEC_MAKE(rtnl->rbuffer, rtnl->rbuffer_allocated);

    /* read the pending message */
    r = socket_recv_message(rtnl->fd, &iov, &group, false);
    if (r <= 0)
        return r;
    else
        len = (size_t)r;

    if (len > rtnl->rbuffer_allocated)
        /* message did not fit in read buffer */
        return -EIO;

    if (NLMSG_OK(rtnl->rbuffer, len) &&
        rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI)
    {
        multi_part = true;

        for (i = 0; i < rtnl->rqueue_partial_size; i++)
        {
            if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
                rtnl->rbuffer->nlmsg_seq)
            {
                first = rtnl->rqueue_partial[i];
                break;
            }
        }
    }

    for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done;
         new_msg = NLMSG_NEXT(new_msg, len))
    {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message* m = NULL;
        const NLType* nl_type;

        if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
            /* not broadcast and not for us */
            continue;

        if (new_msg->nlmsg_type == NLMSG_NOOP)
            /* silently drop noop messages */
            continue;

        if (new_msg->nlmsg_type == NLMSG_DONE)
        {
            /* finished reading multi-part message */
            done = true;

            /* if first is not defined, put NLMSG_DONE into the receive queue.
             */
            if (first)
                continue;
        }

        /* check that we support this message type */
        r = type_system_get_type(type_system_root, &nl_type,
                                 new_msg->nlmsg_type);
        if (r < 0)
        {
            if (r == -EOPNOTSUPP)
                log_debug("sd-netlink: ignored message with unknown type: %i",
                          new_msg->nlmsg_type);

            continue;
        }

        /* check that the size matches the message type */
        if (new_msg->nlmsg_len < NLMSG_LENGTH(type_get_size(nl_type)))
        {
            log_debug("sd-netlink: message larger than expected, dropping");
            continue;
        }

        r = message_new_empty(rtnl, &m);
        if (r < 0)
            return r;

        m->broadcast = !!group;

        m->hdr = memdup(new_msg, new_msg->nlmsg_len);
        if (!m->hdr)
            return -ENOMEM;

        /* seal and parse the top-level message */
        r = sd_netlink_message_rewind(m);
        if (r < 0)
            return r;

        /* push the message onto the multi-part message stack */
        if (first)
            m->next = first;
        first = TAKE_PTR(m);
    }

    if (len > 0)
        log_debug("sd-netlink: discarding %zu bytes of incoming message", len);

    if (!first)
        return 0;

    if (!multi_part || done)
    {
        /* we got a complete message, push it on the read queue */
        r = rtnl_rqueue_make_room(rtnl);
        if (r < 0)
            return r;

        rtnl->rqueue[rtnl->rqueue_size++] = TAKE_PTR(first);

        if (multi_part && (i < rtnl->rqueue_partial_size))
        {
            /* remove the message form the partial read queue */
            memmove(rtnl->rqueue_partial + i, rtnl->rqueue_partial + i + 1,
                    sizeof(sd_netlink_message*) *
                        (rtnl->rqueue_partial_size - i - 1));
            rtnl->rqueue_partial_size--;
        }

        return 1;
    }
    else
    {
        /* we only got a partial multi-part message, push it on the
           partial read queue */
        if (i < rtnl->rqueue_partial_size)
            rtnl->rqueue_partial[i] = TAKE_PTR(first);
        else
        {
            r = rtnl_rqueue_partial_make_room(rtnl);
            if (r < 0)
                return r;

            rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = TAKE_PTR(first);
        }

        return 0;
    }
}
/* On success, the number of bytes received is returned and *ret points to the
 * received message which has a valid header and the correct size. If nothing
 * useful was received 0 is returned. On failure, a negative error code is
 * returned.
 */
On success, the number of bytes received is returned and *ret points to the
received message which has a valid header and the correct size. If nothing
useful was received 0 is returned. On failure, a negative error code is
returned.
On success the number of bytes received is returned and * ret points to the received message which has a valid header and the correct size . If nothing useful was received 0 is returned . On failure a negative error code is returned .
int socket_read_message(sd_netlink* rtnl)
{
    _cleanup_(sd_netlink_message_unrefp) sd_netlink_message* first = NULL;
    struct iovec iov = {};
    uint32_t group = 0;
    bool multi_part = false, done = false;
    struct nlmsghdr* new_msg;
    size_t len;
    int r;
    unsigned i = 0;
    const NLTypeSystem* type_system_root;
    assert(rtnl);
    assert(rtnl->rbuffer);
    assert(rtnl->rbuffer_allocated >= sizeof(struct nlmsghdr));
    type_system_root = type_system_get_root(rtnl->protocol);
    r = socket_recv_message(rtnl->fd, &iov, NULL, true);
    if (r <= 0)
        return r;
    else
        len = (size_t)r;
    if (!greedy_realloc((void**)&rtnl->rbuffer, &rtnl->rbuffer_allocated, len,
                        sizeof(uint8_t)))
        return -ENOMEM;
    iov = IOVEC_MAKE(rtnl->rbuffer, rtnl->rbuffer_allocated);
    r = socket_recv_message(rtnl->fd, &iov, &group, false);
    if (r <= 0)
        return r;
    else
        len = (size_t)r;
    if (len > rtnl->rbuffer_allocated)
        return -EIO;
    if (NLMSG_OK(rtnl->rbuffer, len) &&
        rtnl->rbuffer->nlmsg_flags & NLM_F_MULTI)
    {
        multi_part = true;
        for (i = 0; i < rtnl->rqueue_partial_size; i++)
        {
            if (rtnl_message_get_serial(rtnl->rqueue_partial[i]) ==
                rtnl->rbuffer->nlmsg_seq)
            {
                first = rtnl->rqueue_partial[i];
                break;
            }
        }
    }
    for (new_msg = rtnl->rbuffer; NLMSG_OK(new_msg, len) && !done;
         new_msg = NLMSG_NEXT(new_msg, len))
    {
        _cleanup_(sd_netlink_message_unrefp) sd_netlink_message* m = NULL;
        const NLType* nl_type;
        if (!group && new_msg->nlmsg_pid != rtnl->sockaddr.nl.nl_pid)
            continue;
        if (new_msg->nlmsg_type == NLMSG_NOOP)
            continue;
        if (new_msg->nlmsg_type == NLMSG_DONE)
        {
            done = true;
            if (first)
                continue;
        }
        r = type_system_get_type(type_system_root, &nl_type,
                                 new_msg->nlmsg_type);
        if (r < 0)
        {
            if (r == -EOPNOTSUPP)
                log_debug("sd-netlink: ignored message with unknown type: %i",
                          new_msg->nlmsg_type);
            continue;
        }
        if (new_msg->nlmsg_len < NLMSG_LENGTH(type_get_size(nl_type)))
        {
            log_debug("sd-netlink: message larger than expected, dropping");
            continue;
        }
        r = message_new_empty(rtnl, &m);
        if (r < 0)
            return r;
        m->broadcast = !!group;
        m->hdr = memdup(new_msg, new_msg->nlmsg_len);
        if (!m->hdr)
            return -ENOMEM;
        r = sd_netlink_message_rewind(m);
        if (r < 0)
            return r;
        if (first)
            m->next = first;
        first = TAKE_PTR(m);
    }
    if (len > 0)
        log_debug("sd-netlink: discarding %zu bytes of incoming message", len);
    if (!first)
        return 0;
    if (!multi_part || done)
    {
        r = rtnl_rqueue_make_room(rtnl);
        if (r < 0)
            return r;
        rtnl->rqueue[rtnl->rqueue_size++] = TAKE_PTR(first);
        if (multi_part && (i < rtnl->rqueue_partial_size))
        {
            memmove(rtnl->rqueue_partial + i, rtnl->rqueue_partial + i + 1,
                    sizeof(sd_netlink_message*) *
                        (rtnl->rqueue_partial_size - i - 1));
            rtnl->rqueue_partial_size--;
        }
        return 1;
    }
    else
    {
        if (i < rtnl->rqueue_partial_size)
            rtnl->rqueue_partial[i] = TAKE_PTR(first);
        else
        {
            r = rtnl_rqueue_partial_make_room(rtnl);
            if (r < 0)
                return r;
            rtnl->rqueue_partial[rtnl->rqueue_partial_size++] = TAKE_PTR(first);
        }
        return 0;
    }
}
int socket_read_message ( sd_netlink * rtnl ) { _cleanup_ ( sd_netlink_message_unrefp ) sd_netlink_message * first = NULL ; struct iovec iov = { } ; uint32_t group = 0 ; bool multi_part = false , done = false ; struct nlmsghdr * new_msg ; size_t len ; int r ; unsigned i = 0 ; const NLTypeSystem * type_system_root ; assert ( rtnl ) ; assert ( rtnl -> rbuffer ) ; assert ( rtnl -> rbuffer_allocated >= sizeof ( struct nlmsghdr ) ) ; type_system_root = type_system_get_root ( rtnl -> protocol ) ; r = socket_recv_message ( rtnl -> fd , & iov , NULL , true ) ; if ( r <= 0 ) return r ; else len = ( size_t ) r ; if ( ! greedy_realloc ( ( void * * ) & rtnl -> rbuffer , & rtnl -> rbuffer_allocated , len , sizeof ( uint8_t ) ) ) return - ENOMEM ; iov = IOVEC_MAKE ( rtnl -> rbuffer , rtnl -> rbuffer_allocated ) ; r = socket_recv_message ( rtnl -> fd , & iov , & group , false ) ; if ( r <= 0 ) return r ; else len = ( size_t ) r ; if ( len > rtnl -> rbuffer_allocated ) return - EIO ; if ( NLMSG_OK ( rtnl -> rbuffer , len ) && rtnl -> rbuffer -> nlmsg_flags & NLM_F_MULTI ) { multi_part = true ; for ( i = 0 ; i < rtnl -> rqueue_partial_size ; i ++ ) { if ( rtnl_message_get_serial ( rtnl -> rqueue_partial [ i ] ) == rtnl -> rbuffer -> nlmsg_seq ) { first = rtnl -> rqueue_partial [ i ] ; break ; } } } for ( new_msg = rtnl -> rbuffer ; NLMSG_OK ( new_msg , len ) && ! done ; new_msg = NLMSG_NEXT ( new_msg , len ) ) { _cleanup_ ( sd_netlink_message_unrefp ) sd_netlink_message * m = NULL ; const NLType * nl_type ; if ( ! group && new_msg -> nlmsg_pid != rtnl -> sockaddr . nl . nl_pid ) continue ; if ( new_msg -> nlmsg_type == NLMSG_NOOP ) continue ; if ( new_msg -> nlmsg_type == NLMSG_DONE ) { done = true ; if ( first ) continue ; } r = type_system_get_type ( type_system_root , & nl_type , new_msg -> nlmsg_type ) ; if ( r < 0 ) { if ( r == - EOPNOTSUPP ) log_debug ( " " , new_msg -> nlmsg_type ) ; continue ; } if ( new_msg -> nlmsg_len < NLMSG_LENGTH ( type_get_size ( nl_type ) ) ) { log_debug ( " " ) ; continue ; } r = message_new_empty ( rtnl , & m ) ; if ( r < 0 ) return r ; m -> broadcast = ! ! group ; m -> hdr = memdup ( new_msg , new_msg -> nlmsg_len ) ; if ( ! m -> hdr ) return - ENOMEM ; r = sd_netlink_message_rewind ( m ) ; if ( r < 0 ) return r ; if ( first ) m -> next = first ; first = TAKE_PTR ( m ) ; } if ( len > 0 ) log_debug ( " " , len ) ; if ( ! first ) return 0 ; if ( ! multi_part || done ) { r = rtnl_rqueue_make_room ( rtnl ) ; if ( r < 0 ) return r ; rtnl -> rqueue [ rtnl -> rqueue_size ++ ] = TAKE_PTR ( first ) ; if ( multi_part && ( i < rtnl -> rqueue_partial_size ) ) { memmove ( rtnl -> rqueue_partial + i , rtnl -> rqueue_partial + i + 1 , sizeof ( sd_netlink_message * ) * ( rtnl -> rqueue_partial_size - i - 1 ) ) ; rtnl -> rqueue_partial_size -- ; } return 1 ; } else { if ( i < rtnl -> rqueue_partial_size ) rtnl -> rqueue_partial [ i ] = TAKE_PTR ( first ) ; else { r = rtnl_rqueue_partial_make_room ( rtnl ) ; if ( r < 0 ) return r ; rtnl -> rqueue_partial [ rtnl -> rqueue_partial_size ++ ] = TAKE_PTR ( first ) ; } return 0 ; } }
On success, the number of bytes received is returned and *ret points to the
 received message which has a valid header and the correct size.
On success the number of bytes received is returned and * ret points to the received message which has a valid header and the correct size .
/* read nothing, just get the pending message size */ /* make room for the pending message */ /* read the pending message */ /* message did not fit in read buffer */ /* not broadcast and not for us */ /* silently drop noop messages */ /* finished reading multi-part message */ /* if first is not defined, put NLMSG_DONE into the receive queue.
             */ /* check that we support this message type */ /* check that the size matches the message type */ /* seal and parse the top-level message */ /* push the message onto the multi-part message stack */ /* we got a complete message, push it on the read queue */ /* remove the message form the partial read queue */ /* we only got a partial multi-part message, push it on the
           partial read queue */