/* * DNRead.C */ #include "lib.h" long DNRead(_chan, _buf, bytes) void *_chan; void *_buf; long bytes; { CHANN *chan = (CHANN *)_chan; char *buf = (char *)_buf; IOSTD *ior; int len = 0; long n; if (chan->eof) return(-1); while (bytes && ((ior = (IOSTD *)RemHead(&chan->rdylist)) || (ior = (IOSTD *)GetMsg(&chan->port)))) { #ifdef DEBUG printf("IOR %08lx cmd %d len %d act %d\n", ior, ior->io_Command, ior->io_Length, ior->io_Actual); #endif if (ior->io_Message.mn_Node.ln_Type == NT_REPLYMSG) { if (!chan->queued) #ifdef DEBUG puts("DNRead: Software Error"); #else ; #endif else --chan->queued; if (ior->io_Length) FreeMem(ior->io_Data, ior->io_Length); FreeMem(ior, sizeof(IOSTD)); continue; } switch(ior->io_Command) { case DNCMD_CLOSE: case DNCMD_EOF: chan->eof = 1; ReplyMsg((MSG *)ior); break; case DNCMD_IOCTL: if (ior->io_Message.mn_Node.ln_Type == NT_REQUEUE) AddHead(&chan->rdylist, (NODE *)ior); else AddTail(&chan->rdylist, (NODE *)ior); ior->io_Message.mn_Node.ln_Type = NT_REQUEUE; if (len == 0) len = -2; goto done; case DNCMD_WRITE: #ifdef DEBUG printf("IOR LEN/ACT %ld/%ld\n", ior->io_Length, ior->io_Actual); #endif n = ior->io_Length - ior->io_Actual; #ifdef DEBUG if (n < 0) puts("len fail"); #endif if (n <= bytes) { BMov((char *)ior->io_Data + ior->io_Actual, buf, n); bytes -= n; len += n; buf += n; ReplyMsg((MSG *)ior); } else { BMov((char *)ior->io_Data + ior->io_Actual, buf, bytes); len += bytes; ior->io_Actual += bytes; bytes = 0; if (ior->io_Message.mn_Node.ln_Type == NT_REQUEUE) AddHead(&chan->rdylist, (NODE *)ior); else AddTail(&chan->rdylist, (NODE *)ior); ior->io_Message.mn_Node.ln_Type = NT_REQUEUE; } break; default: ior->io_Error = 1; ReplyMsg((MSG *)ior); } } #ifdef DEBUG puts("DONE1"); #endif done: FixSignal(chan); if (chan->eof) SetSignal(1 << chan->port.mp_SigBit, 1 << chan->port.mp_SigBit); #ifdef DEBUG printf("RETURN %ld\n", len); #endif return(len); }