⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netdrv.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 4 页
字号:
	{	errnoSet (S_netDrv_WRITE_ONLY_CANNOT_READ);	return (ERROR);	}    semTake (&pNetFd->netFdSem, WAIT_FOREVER);    /* 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 first character in block */	        bptr = buf + byteCount;	/* move buffer pointer */	        }	    }        }  /* end of while */    status = netSeek (pNetFd, pNetFd->filePtrByte + byteCount);    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 *buffer,               /* buffer being written from */    FAST int nBytes             /* number of bytes to write to file */    )    {    STATUS status;    FAST int byteCount = 0;	/* number of written read so far */    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 */    /* check for valid number of bytes */    if (nBytes < 0)	{	errnoSet (S_netDrv_INVALID_NUMBER_OF_BYTES);	return (ERROR);	}    /* if file opened for O_RDONLY, don't write */    if ((pNetFd->options & FD_MODE) == O_RDONLY)	{	errnoSet (S_netDrv_READ_ONLY_CANNOT_WRITE);	return (ERROR);	}    semTake (&pNetFd->netFdSem, WAIT_FOREVER);    cindex = pNetFd->filePtrByte % DATASIZE;    dptr   = pNetFd->filePtrBlock;    cptr   = &dptr->databuf [cindex];    bptr   = buffer;    while (byteCount < nBytes)	{	if ((nBytes - byteCount) < (DATASIZE - cindex))	    {	    /* almost done writing nBytes. This is the last block to write to */	    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 = buffer + byteCount;	    }	} /* end of while loop */    pNetFd->options |= FD_DIRTY;    status = netSeek (pNetFd, 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:	    return (netSeek (pNetFd, arg));	case FIOWHERE:    	    return (pNetFd->filePtrByte);	case FIONREAD:    	    *((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 & FD_MODE;	    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 the elements of the stat struct that we have */             pStat->st_dev = (ULONG) pNetFd->pNetDev;            pStat->st_mode = S_IFREG;            pStat->st_size = pNetFd->endOfFile;             return (OK);             break; 	default:	    errnoSet (S_netDrv_UNKNOWN_REQUEST);	    return (ERROR);	}    }/********************************************************************************* netSeek - change file's current character position** This routine moves the file pointer by the offset to a new* position.  If the new position is past the end of file, fill the* unused space with 0's.  The end of file pointer gets moved to the* position immediately following the last '0' written.* If the resulting file pointer would be negative, ERROR is returned.** Called only by the I/O system.** INTERNAL* There is deliberate co-recursion between netSeek and netWrite.** RETURNS: OK or ERROR.*/LOCAL int netSeek    (    FAST NET_FD *pNetFd,    FAST int newPos    )    {    FAST DATABLOCK *saveFilePtrBlock;    FAST int saveFilePtrByte;    int endOfFile;    int newBlock;    int curBlock;    char *buf;    DATABLOCK *dptr;    int nbytes;    if (newPos < 0)	{	errnoSet (S_netDrv_BAD_SEEK);	return (ERROR);	}    saveFilePtrBlock = pNetFd->filePtrBlock;    saveFilePtrByte  = pNetFd->filePtrByte;    endOfFile        = pNetFd->endOfFile;    newBlock         = newPos / DATASIZE;    curBlock         = pNetFd->filePtrByte / DATASIZE;    /* if new position is past end of file */    if (newPos > endOfFile)	{	/* put 0's at the end of the file */	if ((buf = (char *) malloc ((unsigned) (newPos - endOfFile))) == NULL)	    {	    return (ERROR);	    }	bzero (buf, newPos - endOfFile);	/* move file pointer to end of file before writing 0's */	pNetFd->filePtrBlock = (DATABLOCK *) lstLast (&pNetFd->dataLst);	pNetFd->filePtrByte = endOfFile;	/* netWrite will update the file pointer and end of file pointer */	nbytes = netWrite (pNetFd, buf, (newPos - endOfFile));	if (nbytes != (newPos - endOfFile))	    {	    if (nbytes != ERROR)	    	errnoSet (S_netDrv_SEEK_PAST_EOF_ERROR);	    pNetFd->filePtrBlock = saveFilePtrBlock;	    pNetFd->filePtrByte = saveFilePtrByte;	    free (buf);	    return (ERROR);	    }	free (buf);	}    else	/* else, new position is within current file size */	{    	/* point to new block */	/* system error if we go out of range of the datablocks */	dptr = (DATABLOCK *) lstNStep ((NODE *) pNetFd->filePtrBlock,				       newBlock - curBlock);	if (dptr == NULL)	    {	    errnoSet (S_netDrv_SEEK_FATAL_ERROR);	    return (ERROR);	    }	pNetFd->filePtrBlock = dptr;	/* point to new byte */    	pNetFd->filePtrByte = newPos;	}    return (OK);    }/********************************************************************************* moveEndOfFile - moves end of file pointer to new position** Adds a new datablock to the end of the datablock list if necessary.* Assumes that end of file moves at most to the first position of* the next datablock.** RETURNS: OK or ERROR.*/LOCAL STATUS moveEndOfFile    (    FAST NET_FD *pNetFd,    FAST int newPos    )    {    FAST DATABLOCK *dptr;	/* pointer to new datablock */    /*    *  As soon as system error handling is implemented, a message should    *  be put here.    *    *  If the new position is before the current end of file,    *  OR more than one datablock ahead,    *  OR further away than the first byte of the next datablock,    *  this is a system error ....looks awful, I know    */    if ((newPos <= pNetFd->endOfFile)				||	((newPos - pNetFd->endOfFile) > DATASIZE)		||	((newPos % DATASIZE < pNetFd->endOfFile % DATASIZE)	&&	(newPos % DATASIZE != 0)))	{	errnoSet (S_netDrv_BAD_EOF_POSITION);	return (ERROR);	}    /* if new position is in datablock after end of file,    *  add another datablock to the file    */    if ((newPos / DATASIZE) > (pNetFd->endOfFile / DATASIZE))	{	/* current datablock is full.	*  New position is in the block after the current	*  end of file.	*/	((DATABLOCK *) lstLast (&pNetFd->dataLst))->used = DATASIZE;	if ((dptr = (DATABLOCK *) malloc (sizeof (DATABLOCK))) == NULL)	    return (ERROR);    	dptr->used = 0;	lstAdd (&pNetFd->dataLst, (NODE *) dptr);	}    else	((DATABLOCK *) lstLast (&pNetFd->dataLst))->used = newPos % DATASIZE;    pNetFd->endOfFile = newPos;    return (OK);    }/********************************************************************************* releaseNetFd - free up NetFd*/LOCAL void releaseNetFd    (    FAST NET_FD *pNetFd    )    {    lstFree (&pNetFd->dataLst);			/* free up data list */    semTerminate (&pNetFd->netFdSem);		/* terminate netFdSem */    free ((char *) pNetFd);			/* deallocate network fd */    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -