Annotation of researchv8dc/sys/chncp/chstream.c, revision 1.1.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.