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

unix.superglobalmegacorp.com

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