Re: porting recvmsg()

From: Wim Deprez (wim.deprez+google_at_student.luc.ac.be)
Date: 07/25/04

  • Next message: boa: "Re: porting recvmsg()"
    Date: 25 Jul 2004 08:38:36 -0700
    
    

    Lev Walkin <vlm@lionet.info> wrote:

    [...]

    > No. You have to reconstruct a big buffer out of two small ones. Like that
    > :
    >
    > ssize t
    > fake recvmsg(int sd, struct msghdr *msg, int flags) {
    > ssize t bytes read;
    > size t expected recv size;
    > ssize t left2move;
    > char *tmp buf;
    > char *tmp;
    > int i;
    >
    > assert(msg->msg iov);
    >
    > expected recv size = 0;
    > for(i = 0; i < msg->msg iovlen; i++)
    > expected recv size += msg->msg iov[i].iov len;
    > tmp buf = malloc(expected recv size);
    > if(!tmp buf)
    > return -1;
    >
    > left2move = bytes read = recvfrom(sd,
    > tmp buf, expected recv size,
    > flags,
    > (struct sockaddr *)msg->msg name,
    > msg->msg namelen
    > );
    >
    > for(tmp = tmp buf, i = 0; i < msg->msg iovlen; i++) {
    > if(left2move <= 0) break;
    > assert(msg->msg iov[i].iov base);
    > memcpy(msg->msg iov[i].iov base, tmp,
    > MIN(msg->msg iov[i].iov len, left2move);
    > left2move -= msg->msg iov[i].iov len;
    > tmp += msg->msg iov[i].iov len;
    > }
    >
    > free(tmp buf);
    >
    > return bytes read;
    > }

    ok great, just for the threads-sake, i'll post my version of sendmsg()
    then:

    ssize_t fake_sendmsg(int sd, struct msghdr *msg, int flags)
    {
        ssize_t bytes_send;
        size_t expected_send_size;
        size_t left2move;
        char *tmp_buf;
        char *tmp;
        int i;

        assert(msg->msg_iov);

        expected_send_size = 0;
        for(i = 0; i < msg->msg_iovlen; i++)
            expected_send_size += msg->msg_iov[i].iov_len;
        tmp_buf = malloc(expected_send_size);
        if(!tmp_buf)
            return -1;

        for(tmp = tmp_buf, left2move = expected_send_size, i = 0; i <
    msg->msg_iovlen; i++)
        {
            if(left2move <= 0) break;
            assert(msg->msg_iov[i].iov_base);
            memcpy(
                            tmp,
                            msg->msg_iov[i].iov_base,
                                MIN(msg->msg_iov[i].iov_len,left2move));
            left2move -= msg->msg_iov[i].iov_len;
            tmp += msg->msg_iov[i].iov_len;
        }

        bytes_send = sendto(sd,
            tmp_buf,
            expected_send_size,
            flags,
            (struct sockaddr *)msg->msg_name,
            msg->msg_namelen
        );

        free(tmp_buf);

        return bytes_send;
    }

    guess that's quite ok... any comments are welcome of course :-)

    Thanks a lot Lev, you really guided me in the right direction :-)

    Many kind greetings,

       --wim


  • Next message: boa: "Re: porting recvmsg()"