Annotation of researchv8dc/sys/chncp/chstream.c, revision 1.1

1.1     ! root        1: #include "../chunix/chsys.h"
        !             2: #include "../chunix/chconf.h"
        !             3: #include "../chaos/chaos.h"
        !             4: 
        !             5: /*
        !             6:  * This file contains code for a stream level (as opposed to packet level)
        !             7:  * interface to the chaosnet. It is written to be general enough to fit into
        !             8:  * various systems where such an interface in desirable.  This has been the
        !             9:  * case both in UNIX and in FEZ, although UNIX also needs its own "tty"
        !            10:  * interface.
        !            11:  *
        !            12:  * Several macros must be supplied in chsys.h(they can do nothing of course):
        !            13:  *     LOCK, UNLOCK    - mask out chaos interrupts (send, receive, clock)
        !            14:  *     NOINPUT         - a LOCK'd hook for indicating that there is no input
        !            15:  *                       available on a channel (used in FEZ...)
        !            16:  *     NOOUTPUT        - a hook for indicating when no output is possible
        !            17:  *                       (window is full) (unused in UNIX, used in FEZ...)
        !            18:  *     CHRCOPY         - read copy routine (from, to, count) which should
        !            19:  *                       return the (to) ptr after copying is done.
        !            20:  *     CHWCOPY         - write copy routine (from, to, count) like CHRCOPY
        !            21:  */
        !            22: 
        !            23: /*
        !            24:  * Stream read routine - given connection, ptr and number of chars
        !            25:  *     As many of the desired characters are transferred as are available
        !            26:  *     in the received packet list.  If any have been read, the number
        !            27:  *     transferred is return.  If none were transferred then if
        !            28:  *     an EOF has been encountered, CHEOF is returned, otherwise if the
        !            29:  *     connection is still open, zero is returned, otherwise CHERROR is
        !            30:  *     returned (connection no longer open).
        !            31:  *     Note that answer (ANSOP) packets read just like data at act like
        !            32:  *     an EOF was encountered after the ANSOP.
        !            33:  *     UNCOP (uncontrolled data) packets are treated just like data packets.
        !            34:  *     An EOF packet just terminates a read that has made some progress
        !            35:  *     and is specifically indicated (by zero chars read) in the next read
        !            36:  *     call.  After this indication a bit (CHEOFSEEN) is set which causes
        !            37:  *     end-of-file indications to be read as long as the connection
        !            38:  *     is open.  If more data packets arrive, this bit is turned off.
        !            39:  */
        !            40: ch_sread(conn, ptr, nchars)
        !            41: register struct connection *conn;
        !            42: char *ptr;
        !            43: unsigned nchars;
        !            44: {
        !            45:        register struct packet *pkt;
        !            46:        register unsigned count;
        !            47:        unsigned ntodo = nchars;
        !            48: 
        !            49:        while (ntodo != 0 && (pkt = conn->cn_rhead) != NOPKT)
        !            50:                switch(pkt->pk_op) {
        !            51:                case EOFOP:
        !            52:                        if (ntodo != nchars)
        !            53:                                return(nchars - ntodo);
        !            54:                        LOCK;
        !            55:                        ch_read(conn);  /* consume it */
        !            56:                        ch_sts(conn);   /* ensure immediately ack */
        !            57:                        UNLOCK;
        !            58:                        conn->cn_flags |= CHEOFSEEN;
        !            59:                        return (CHEOF);
        !            60:                default:
        !            61:                        if (!ISDATOP(pkt)) {
        !            62:                                LOCK;
        !            63:                                ch_read(conn);
        !            64:                                UNLOCK;
        !            65:                                break;
        !            66:                        }
        !            67:                        /* Fall into... */
        !            68:                case ANSOP:
        !            69:                case UNCOP:
        !            70:                        conn->cn_flags &= ~CHEOFSEEN;
        !            71:                        count = pkt->pk_len >= ntodo ? ntodo : pkt->pk_len;
        !            72:                        ptr = CHRCOPY(&pkt->pk_cdata[conn->cn_roffset], ptr, count);
        !            73:                        ntodo -= count;
        !            74:                        if ((pkt->pk_len -= count) == 0) {
        !            75:                                LOCK;
        !            76:                                ch_read(conn);
        !            77:                                UNLOCK;
        !            78:                                conn->cn_roffset = 0;
        !            79:                                if (pkt->pk_op == ANSOP)
        !            80:                                        conn->cn_flags |= CHEOFSEEN;
        !            81:                        } else
        !            82:                                conn->cn_roffset += count;
        !            83:                }
        !            84:        if (ntodo != 0) {
        !            85:                LOCK;
        !            86:                NOINPUT(conn);
        !            87:                UNLOCK;
        !            88:        }
        !            89:        return (ntodo != nchars ? nchars - ntodo :
        !            90:                conn->cn_flags & CHEOFSEEN ? CHEOF :
        !            91:                conn->cn_state == CSOPEN ? 0 : CHERROR);
        !            92: }
        !            93: 
        !            94: /*
        !            95:  * Stream write routine - given connection, ptr and number of characters
        !            96:  *     Characters are written until exhausted or until the window is full.
        !            97:  *     The number of characters not read is returned, unless this connection
        !            98:  *     closes, in which case CHERROR is returned.  If no buffers are avaiable
        !            99:  *     (presumably a temporary condition), CHTEMP is returned.
        !           100:  *     ANS packets are sent if the flag is set.
        !           101:  */
        !           102: ch_swrite(conn, ptr, nchars)
        !           103: register struct connection *conn;
        !           104: char *ptr;
        !           105: unsigned nchars;
        !           106: {
        !           107:        register struct packet *pkt;
        !           108:        register unsigned count;
        !           109:        unsigned ntodo = nchars;
        !           110: 
        !           111:        LOCK;
        !           112:        for (;;) {
        !           113:                if (conn->cn_state != CSOPEN &&
        !           114:                    (conn->cn_state != CSRFCRCVD ||
        !           115:                     (conn->cn_flags & CHANSWER) == 0)) {
        !           116:                        UNLOCK;
        !           117:                        return CHERROR;
        !           118:                }
        !           119:                if (ntodo == 0 || chtfull(conn))
        !           120:                        break;
        !           121:                if ((pkt = conn->cn_toutput) == NOPKT) {
        !           122:                        UNLOCK;
        !           123:                        if ((pkt = pkalloc(CHMAXDATA, 0)) == NOPKT)
        !           124:                                return (ntodo == nchars ? CHTEMP :
        !           125:                                        nchars - ntodo);
        !           126:                        pkt->pk_op = conn->cn_flags & CHANSWER ? ANSOP : DATOP;
        !           127:                        pkt->pk_lenword = 0;
        !           128:                        conn->cn_troom = CHMAXDATA;
        !           129:                } else {
        !           130:                        conn->cn_toutput = NOPKT;
        !           131:                        UNLOCK;
        !           132:                }
        !           133:                count = ntodo > conn->cn_troom ? conn->cn_troom : ntodo;
        !           134:                ptr = CHWCOPY(ptr, &pkt->pk_cdata[pkt->pk_len], count);
        !           135:                pkt->pk_lenword += count;
        !           136:                ntodo -= count;
        !           137:                LOCK;
        !           138:                if ((conn->cn_troom -= count) == 0) {
        !           139:                        if (ch_write(conn, pkt))
        !           140:                                return CHERROR;
        !           141:                } else {
        !           142:                        conn->cn_toutput = pkt;
        !           143:                        pkt->pk_time = Chclock;
        !           144:                }
        !           145:        }
        !           146:        if (ntodo != 0)
        !           147:                NOOUTPUT(conn);
        !           148:        UNLOCK;
        !           149:        return(nchars - ntodo);
        !           150: }
        !           151: /*
        !           152:  * Output flush routine - release the currently-being-filled packet for
        !           153:  * transmission immediately.
        !           154:  * Called at high priority.
        !           155:  * If output window is full, CHTEMP is returned.
        !           156:  * If connection is not open, CHERROR is returned from ch_write.
        !           157:  */
        !           158: ch_sflush(conn)
        !           159: register struct connection *conn;
        !           160: {
        !           161:        register struct packet *pkt;
        !           162: 
        !           163:        if ((pkt = conn->cn_toutput) != NOPKT)
        !           164:                if (chtfull(conn))
        !           165:                        return CHTEMP;
        !           166:                else {
        !           167:                        conn->cn_toutput = NOPKT;
        !           168:                        return ch_write(conn, pkt);
        !           169:                }
        !           170:        return 0;
        !           171: }

unix.superglobalmegacorp.com

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