Annotation of previous_trunk/src/slirp/sbuf.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1995 Danny Gasparovski.
        !             3:  * 
        !             4:  * Please read the file COPYRIGHT for the 
        !             5:  * terms and conditions of the copyright.
        !             6:  */
        !             7: 
        !             8: #include <stdlib.h>
        !             9: #include <slirp.h>
        !            10: 
        !            11: /* Done as a macro in socket.h */
        !            12: /* int
        !            13:  * sbspace(struct sockbuff *sb) 
        !            14:  * {
        !            15:  *     return SB_DATALEN - sb->sb_cc;
        !            16:  * }
        !            17:  */
        !            18: 
        !            19: void sbfree(struct sbuf *sb)
        !            20: {
        !            21:        free(sb->sb_data);
        !            22: }
        !            23: 
        !            24: void sbdrop(struct sbuf *sb, u_int num)
        !            25: {
        !            26:        /* 
        !            27:         * We can only drop how much we have
        !            28:         * This should never succeed 
        !            29:         */
        !            30:        if(num > sb->sb_cc)
        !            31:                num = sb->sb_cc;
        !            32:        sb->sb_cc -= num;
        !            33:        sb->sb_rptr += num;
        !            34:        if(sb->sb_rptr >= sb->sb_data + sb->sb_datalen)
        !            35:                sb->sb_rptr -= sb->sb_datalen;
        !            36:    
        !            37: }
        !            38: 
        !            39: void sbreserve(struct sbuf *sb, size_t size)
        !            40: {
        !            41:        if (sb->sb_data) {
        !            42:                /* Already alloced, realloc if necessary */
        !            43:                if (sb->sb_datalen != size) {
        !            44:                        sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)realloc(sb->sb_data, size);
        !            45:                        sb->sb_cc = 0;
        !            46:                        if (sb->sb_wptr)
        !            47:                           sb->sb_datalen = size;
        !            48:                        else
        !            49:                           sb->sb_datalen = 0;
        !            50:                }
        !            51:        } else {
        !            52:                sb->sb_wptr = sb->sb_rptr = sb->sb_data = (char *)malloc(size);
        !            53:                sb->sb_cc = 0;
        !            54:                if (sb->sb_wptr)
        !            55:                   sb->sb_datalen = size;
        !            56:                else
        !            57:                   sb->sb_datalen = 0;
        !            58:        }
        !            59: }
        !            60: 
        !            61: /*
        !            62:  * Try and write() to the socket, whatever doesn't get written
        !            63:  * append to the buffer... for a host with a fast net connection,
        !            64:  * this prevents an unnecessary copy of the data
        !            65:  * (the socket is non-blocking, so we won't hang)
        !            66:  */
        !            67: void sbappend(struct socket *so, struct mbuf *m)
        !            68: {
        !            69:        int ret = 0;
        !            70:        
        !            71:        DEBUG_CALL("sbappend");
        !            72:        DEBUG_ARG("so = %lx", (long)so);
        !            73:        DEBUG_ARG("m = %lx", (long)m);
        !            74:        DEBUG_ARG("m->m_len = %zu", m->m_len);
        !            75:        
        !            76:        /* Shouldn't happen, but...  e.g. foreign host closes connection */
        !            77:        if (m->m_len <= 0) {
        !            78:                m_free(m);
        !            79:                return;
        !            80:        }
        !            81:        
        !            82:        /*
        !            83:         * If there is urgent data, call sosendoob
        !            84:         * if not all was sent, sowrite will take care of the rest
        !            85:         * (The rest of this function is just an optimisation)
        !            86:         */
        !            87:        if (so->so_urgc) {
        !            88:                sbappendsb(&so->so_rcv, m);
        !            89:                m_free(m);
        !            90:                sosendoob(so);
        !            91:                return;
        !            92:        }
        !            93:        
        !            94:        /*
        !            95:         * We only write if there's nothing in the buffer,
        !            96:         * ottherwise it'll arrive out of order, and hence corrupt
        !            97:         */
        !            98:        if (!so->so_rcv.sb_cc)
        !            99:           ret = send(so->s, m->m_data, m->m_len, 0);
        !           100:        
        !           101:        if (ret <= 0) {
        !           102:                /* 
        !           103:                 * Nothing was written
        !           104:                 * It's possible that the socket has closed, but
        !           105:                 * we don't need to check because if it has closed,
        !           106:                 * it will be detected in the normal way by soread()
        !           107:                 */
        !           108:                sbappendsb(&so->so_rcv, m);
        !           109:        } else if (ret != m->m_len) {
        !           110:                /*
        !           111:                 * Something was written, but not everything..
        !           112:                 * sbappendsb the rest
        !           113:                 */
        !           114:                m->m_len -= ret;
        !           115:                m->m_data += ret;
        !           116:                sbappendsb(&so->so_rcv, m);
        !           117:        } /* else */
        !           118:        /* Whatever happened, we free the mbuf */
        !           119:        m_free(m);
        !           120: }
        !           121: 
        !           122: /*
        !           123:  * Copy the data from m into sb
        !           124:  * The caller is responsible to make sure there's enough room
        !           125:  */
        !           126: void sbappendsb(struct sbuf *sb, struct mbuf *m)
        !           127: {
        !           128:        int len, n,  nn;
        !           129:        
        !           130:        len = m->m_len;
        !           131: 
        !           132:        if (sb->sb_wptr < sb->sb_rptr) {
        !           133:                n = sb->sb_rptr - sb->sb_wptr;
        !           134:                if (n > len) n = len;
        !           135:                memcpy(sb->sb_wptr, m->m_data, n);
        !           136:        } else {
        !           137:                /* Do the right edge first */
        !           138:                n = sb->sb_data + sb->sb_datalen - sb->sb_wptr;
        !           139:                if (n > len) n = len;
        !           140:                memcpy(sb->sb_wptr, m->m_data, n);
        !           141:                len -= n;
        !           142:                if (len) {
        !           143:                        /* Now the left edge */
        !           144:                        nn = sb->sb_rptr - sb->sb_data;
        !           145:                        if (nn > len) nn = len;
        !           146:                        memcpy(sb->sb_data,m->m_data+n,nn);
        !           147:                        n += nn;
        !           148:                }
        !           149:        }
        !           150: 
        !           151:        sb->sb_cc += n;
        !           152:        sb->sb_wptr += n;
        !           153:        if (sb->sb_wptr >= sb->sb_data + sb->sb_datalen)
        !           154:                sb->sb_wptr -= sb->sb_datalen;
        !           155: }
        !           156: 
        !           157: /*
        !           158:  * Copy data from sbuf to a normal, straight buffer
        !           159:  * Don't update the sbuf rptr, this will be
        !           160:  * done in sbdrop when the data is acked
        !           161:  */
        !           162: void sbcopy(struct sbuf *sb, u_int off, u_int len, char *to)
        !           163: {
        !           164:        char *from;
        !           165:        
        !           166:        from = sb->sb_rptr + off;
        !           167:        if (from >= sb->sb_data + sb->sb_datalen)
        !           168:                from -= sb->sb_datalen;
        !           169: 
        !           170:        if (from < sb->sb_wptr) {
        !           171:                if (len > sb->sb_cc) len = sb->sb_cc;
        !           172:                memcpy(to,from,len);
        !           173:        } else {
        !           174:                /* re-use off */
        !           175:                off = (sb->sb_data + sb->sb_datalen) - from;
        !           176:                if (off > len) off = len;
        !           177:                memcpy(to,from,off);
        !           178:                len -= off;
        !           179:                if (len)
        !           180:                   memcpy(to+off,sb->sb_data,len);
        !           181:        }
        !           182: }
        !           183:                

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.