📄 netdrv.c
字号:
semTake (pNetFd->netFdSem, WAIT_FOREVER); if (pNetFd->pNetDev->bufSize == 0) { FAST DATABLOCK *dptr; /* points to current datablock */ FAST int cindex; /* character index datablock's databuf */ FAST char *cptr; /* points to character being read in the file */ FAST char *bptr; /* points to current position in buffer */ /* if file pointer is at end of file, can't read any characters */ if (pNetFd->filePtrByte == pNetFd->endOfFile) { semGive (pNetFd->netFdSem); return (0); } cindex = pNetFd->filePtrByte % DATASIZE; /* char index in datablock */ dptr = pNetFd->filePtrBlock; cptr = &dptr->databuf [cindex]; /* point to current char in datablock */ bptr = buf; /* point to beginning of read buffer */ /* read until maxBytes characters have been read */ while (byteCount < maxBytes) { if ((maxBytes - byteCount) < (dptr->used - cindex)) { /* stop reading when maxBytes characters have been read. * This is the last block to read from in order to finish * filling up the buffer. */ bcopy (cptr, bptr, maxBytes - byteCount); byteCount = maxBytes; } else { /* copy the rest of the datablock into buffer */ bcopy (cptr, bptr, dptr->used - cindex); byteCount = byteCount + dptr->used - cindex; if (dptr == (DATABLOCK *) lstLast (&pNetFd->dataLst)) { /* this is the last block in the file. Seek to the end. */ status = netSeek (pNetFd, pNetFd->endOfFile); semGive (pNetFd->netFdSem); return (status == ERROR ? ERROR : byteCount); } else /* get next block */ { dptr = (DATABLOCK *) lstNext ((NODE *) dptr); cindex = 0; cptr = dptr->databuf; /* point to 1st char in block */ bptr = buf + byteCount; /* move buffer pointer */ } } } /* end of while */ status = netSeek (pNetFd, pNetFd->filePtrByte + byteCount); } else { FAST int nBytes = 0; FAST int bytes = 0; FAST int bufOffset = 0; /* if it is in the cache, read it from the cache */ if (pNetFd->bufOffset < pNetFd->bufBytes) { if ((pNetFd->bufOffset + maxBytes) <= (pNetFd->bufBytes)) { bcopy (pNetFd->buf + pNetFd->bufOffset, buf, maxBytes); pNetFd->bufOffset += maxBytes; /* move the cache pointer */ pNetFd->filePtrByte += maxBytes; /* move the file pointer */ pNetFd->status[0]++; /* increment read[hit] */ semGive (pNetFd->netFdSem); return (maxBytes); } else { bytes = pNetFd->bufBytes - pNetFd->bufOffset; bcopy (pNetFd->buf + pNetFd->bufOffset, buf, bytes); pNetFd->bufOffset += bytes; /* move the cache pointer */ pNetFd->filePtrByte += bytes; /* move the file pointer */ bufOffset = bytes; /* set the buf offset */ } } while ((nBytes = maxBytes - bufOffset) > 0) { /* read bytes from socket into the cache */ pNetFd->status[1]++; /* increment read[mis] */ byteCount = 0; while ((bytes = pNetFd->pNetDev->bufSize - byteCount) > 0) { bytes = read (pNetFd->dataSock, pNetFd->buf + byteCount, bytes); if (bytes <= 0) break; else byteCount += bytes; } pNetFd->bufOffset = 0; /* set the cache pointer */ pNetFd->bufBytes = byteCount; /* set the cache size */ /* read bytes from the cache */ if (bytes < 0) /* recv error */ { status = ERROR; break; } if (pNetFd->bufBytes == 0) /* the cache is empty, i.e. EOF */ break; else /* the cache is not empty */ { bytes = (pNetFd->bufBytes < nBytes) ? pNetFd->bufBytes : nBytes; bcopy (pNetFd->buf, buf + bufOffset, bytes); pNetFd->bufOffset += bytes; /* move the cache pointer */ pNetFd->filePtrByte += bytes; /* move the file pointer */ bufOffset += bytes; /* move the buf offset */ } } byteCount = bufOffset; /* set the byte count */ } semGive (pNetFd->netFdSem); return (status == ERROR ? ERROR : byteCount); }/********************************************************************************* netWrite - write bytes to remote file** netWrite copies up to the specified number of bytes from the buffer* to the open network file descriptor. Bytes are written starting* at the spot pointed to by the file's block and byte pointers.* The file pointer is updated to point immediately after the last* character that was written.** Called only by the I/O system.** SIDE EFFECTS: moves file pointer** RETURNS:* Number of bytes written (error if != nbytes), or* ERROR if nBytes < 0, or no more space can be allocated.*/LOCAL int netWrite ( FAST NET_FD *pNetFd, /* open file descriptor */ char *buf, /* buffer being written from */ FAST int nBytes /* number of bytes to write to file */ ) { STATUS status = OK; FAST int byteCount = 0; /* number of written read so far */ /* check for valid number of bytes */ if (nBytes < 0) { errno = S_netDrv_INVALID_NUMBER_OF_BYTES; return (ERROR); } /* if file opened for O_RDONLY, don't write */ if ((pNetFd->options & pNetFd->pNetDev->fdMode) == O_RDONLY) { errno = S_netDrv_READ_ONLY_CANNOT_WRITE; return (ERROR); } semTake (pNetFd->netFdSem, WAIT_FOREVER); if (pNetFd->pNetDev->bufSize == 0) { FAST DATABLOCK *dptr; /* points to current datablock */ FAST int cindex; /* character index datablock's databuf */ FAST char *cptr; /* points to char being overwritten in file */ FAST char *bptr; /* points to current position in buffer */ cindex = pNetFd->filePtrByte % DATASIZE; dptr = pNetFd->filePtrBlock; cptr = &dptr->databuf [cindex]; bptr = buf; while (byteCount < nBytes) { if ((nBytes - byteCount) < (DATASIZE - cindex)) { /* almost done writing nBytes. This is the last block */ bcopy (bptr, cptr, nBytes - byteCount); byteCount = nBytes; /* if we wrote past end of file, adjust end of file pointer */ if ((pNetFd->filePtrByte + byteCount > pNetFd->endOfFile) && moveEndOfFile (pNetFd, pNetFd->filePtrByte + byteCount) == ERROR) { semGive (pNetFd->netFdSem); return (ERROR); } } else /* not last block to write to */ { bcopy (bptr, cptr, DATASIZE - cindex); byteCount = byteCount + DATASIZE - cindex; /* if we wrote past end of file, adjust end of file pointer. * If necessary, moveEndOfFile will attach a new datablock * to the end of the data chain. */ if ((pNetFd->filePtrByte + byteCount > pNetFd->endOfFile) && moveEndOfFile (pNetFd, pNetFd->filePtrByte + byteCount) == ERROR) { semGive (pNetFd->netFdSem); return (ERROR); } /* point to first character in next datablock */ dptr = (DATABLOCK *) lstNext ((NODE *) dptr); cindex = 0; cptr = dptr->databuf; /* adjust buffer pointer */ bptr = buf + byteCount; } } /* end of while loop */ pNetFd->options |= FD_DIRTY; status = netSeek (pNetFd, pNetFd->filePtrByte + byteCount); } else { /* write the data to socket */ if ((byteCount = write (pNetFd->dataSock, buf, nBytes)) != nBytes) status = ERROR; pNetFd->filePtrByte += byteCount; } semGive (pNetFd->netFdSem); return (status == ERROR ? ERROR : byteCount); }/********************************************************************************* netIoctl - do device specific control function** Called only by the I/O system.** RETURNS: Whatever the called function returns.*/LOCAL int netIoctl ( FAST NET_FD *pNetFd, /* open network file descriptor */ FAST int function, /* function code */ FAST int arg /* argument for function */ ) { struct stat *pStat; /* pointer to struct for stat() call */ switch (function) { case FIOSEEK: if (pNetFd->pNetDev->bufSize == 0) return (netSeek (pNetFd, arg)); { int status = OK; FAST int bytes = 0; FAST int byteCount = 0; if ((arg < 0) || (pNetFd->options & O_WRONLY)) /* no seek in WR_ONLY mode */ { errno = S_netDrv_BAD_SEEK; return (ERROR); } if (pNetFd->filePtrByte == arg) return (OK); /* forward seek */ if (pNetFd->filePtrByte < arg) { if ((arg - pNetFd->filePtrByte) < (pNetFd->bufBytes - pNetFd->bufOffset)) { /* forward seek in the cache. move the file pointer */ pNetFd->status[2]++; /* increment fseek[hit] */ pNetFd->bufOffset += (arg - pNetFd->filePtrByte); pNetFd->filePtrByte = arg; return (OK); } else { /* forward seek beyond the cache. read the file */ pNetFd->status[3]++; /* increment fseek[mis] */ byteCount = pNetFd->filePtrByte + (pNetFd->bufBytes - pNetFd->bufOffset); } } /* backward seek */ if (pNetFd->filePtrByte > arg) { if ((pNetFd->filePtrByte - arg) < pNetFd->bufOffset) { /* backward seek in the cache. move the file pointer */ pNetFd->status[4]++; /* increment bseek[hit] */ pNetFd->bufOffset -= (pNetFd->filePtrByte - arg); pNetFd->filePtrByte = arg; return (OK); } else { /* backward seek beyond the cache. re-open the file */ if ((netSockClose (pNetFd) == ERROR) || /* close it */ (netSockOpen (pNetFd) == ERROR)) /* reopen it */ return (ERROR); pNetFd->status[5]++; /* increment bseek[mis] */ byteCount = 0; } } /* read until it reaches the new file pointer */ while ((bytes = arg - byteCount) > 0) { bytes = (bytes > pNetFd->pNetDev->bufSize) ? pNetFd->pNetDev->bufSize : bytes; bytes = read (pNetFd->dataSock, pNetFd->buf, bytes); if (bytes <= 0) { pNetFd->filePtrByte = byteCount; return (ERROR); break; } else byteCount += bytes; } /* set the file pointer and flush the cache */ pNetFd->filePtrByte = arg; pNetFd->bufOffset = 0; pNetFd->bufBytes = 0; return (status); } case FIOWHERE: return (pNetFd->filePtrByte); case FIONREAD: if (pNetFd->pNetDev->bufSize > 0) return (ERROR); else { *((int *) arg) = pNetFd->endOfFile - pNetFd->filePtrByte; return (OK); } case FIODIRENTRY: /* this is a kludge for 'ls'. Do the listing, then return ERROR so that 'ls' doesn't try listing an rt-11 device */ netLs (pNetFd); return (ERROR); case FIOGETFL: *((int *) arg) = pNetFd->options & pNetFd->pNetDev->fdMode; return (OK); case FIOFSTATGET: /* get status of a file */ pStat = (struct stat *) arg; /* get file attributes returned in pStat */ /* zero out the pStat structure */ bzero ((char *) pStat, sizeof (*pStat)); /* fill in th
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -