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

📄 dosfslib.c

📁 vxworks源码源码解读是学习vxworks的最佳途径
💻 C
📖 第 1 页 / 共 5 页
字号:
    if( pVolDesc->mounted )    	return OK;    return ERROR;    } /* dosFsVolMount() *//***************************************************************************** dosFsFdFree - free a file descriptor** This routine marks a file descriptor as free and decreases* reference count of a referenced file handle.** RETURNS: N/A.*/LOCAL void dosFsFdFree    (    DOS_FILE_DESC_ID	pFd    )    {    DOS_VOLUME_DESC_ID	pVolDesc = pFd->pVolDesc;    assert( pFd != NULL );        DBG_MSG( 600, "pFd = %p\n", pFd ,0,0,0,0,0,0,0);        semTake( & pFd->pVolDesc->devSem, WAIT_FOREVER );        assert( pFd->pFileHdl->nRef != 0 );    pFd->pFileHdl->nRef --;    pFd->busy = 0;    semGive( & pVolDesc->devSem );    } /* dosFsFdFree() */    /***************************************************************************** dosFsFdGet - get an available file descriptor** This routine obtains a free dosFs file descriptor.** RETURNS: Pointer to file descriptor, or NULL, if none available.** ERRNO:* S_dosFsLib_NO_FREE_FILE_DESCRIPTORS**/LOCAL DOS_FILE_DESC_ID dosFsFdGet    (    DOS_VOLUME_DESC_ID	pVolDesc    )    {    FAST DOS_FILE_DESC_ID	pFd = pVolDesc->pFdList;    FAST DOS_FILE_DESC_ID	pFdFree = NULL;    FAST DOS_FILE_HDL_ID	pFileHdl = pVolDesc->pFhdlList;    FAST DOS_FILE_HDL_ID	pFileHdlFree = NULL;        if( semTake( & pVolDesc->devSem, WAIT_FOREVER ) == ERROR )    	return NULL;        /* allocate file descriptor */        for( pFd = pVolDesc->pFdList;         pFd < pVolDesc->pFdList + pVolDesc->maxFiles; pFd++ )    	{    	if( ! pFd->busy )    	    {    	    pFdFree = pFd;    	    break;    	    }    	}    if( pFdFree == NULL )    	{    	errnoSet( S_dosFsLib_NO_FREE_FILE_DESCRIPTORS );    	pFd = NULL;    	goto ret;    	}    DBG_MSG( 600, "pFdFree = %p\n", pFdFree ,0,0,0,0,0,0,0);        bzero( (char *)pFdFree, sizeof( *pFdFree ) );    pFdFree->pVolDesc = pVolDesc;    pFdFree->busy = TRUE;    pFdFree->pVolDesc->nBusyFd ++;        /* allocate file handle */        for( pFileHdl = pVolDesc->pFhdlList;         pFileHdl < pVolDesc->pFhdlList + pVolDesc->maxFiles;         pFileHdl++ )    	{    	if( pFileHdl->nRef == 0 )    	    {    	    pFileHdlFree = pFileHdl;    	    break;    	    }    	}        assert( pFileHdlFree != NULL );        bzero( (char *)pFileHdlFree, sizeof( *pFileHdlFree ) );        pFileHdlFree->nRef = 1;    pFdFree->pFileHdl = pFileHdlFree;        DBG_MSG( 600, "pFileHdlFree = %p\n", pFileHdlFree,0,0,0,0,0,0,0 );    ret:    semGive( & pVolDesc->devSem );    return pFdFree;    } /* dosFsFdGet() *//***************************************************************************** dosFsHdlDeref - unify file descriptors of the same file.** All file descriptors, that are opened for one file* have to share the same file handle in order to* prevent confusion when file is changed and accessed through* several file descriptors simultaneously.** This routine lookups throw list of file handles and* references <pFd> to the file handle, that already describes the* same file, if such exists. File handle, that has been used* by <pFd> is freed.** RETURNS: N/A.*/LOCAL void dosFsHdlDeref    (    DOS_FILE_DESC_ID	pFd    )    {    FAST DOS_VOLUME_DESC_ID	pVolDesc = pFd->pVolDesc;    FAST DOS_DIR_HDL_ID		pDirHdlFd = & pFd->pFileHdl->dirHdl;    					/* dir handle ptr */    FAST DOS_FILE_HDL_ID	pFhdlLCur = pVolDesc->pFhdlList;    					/* loop file handle */    FAST DOS_DIR_HDL_ID		pDirHdlCur = NULL;    					/* dir handle of the */    					/* loop file handle */    FAST int	i;	/* loop counter */        semTake( & pVolDesc->devSem, WAIT_FOREVER );        /* loop by file handles list */        for( i = 0; i < pVolDesc->maxFiles; i++, pFhdlLCur++ )    	{    	if( pFhdlLCur->nRef == 0 || pFhdlLCur == pFd->pFileHdl ||    	    pFhdlLCur->deleted || pFhdlLCur->obsolet )    	    {    	    continue;    	    }    	    	/* compare directory handles */    	    	pDirHdlCur = & pFhdlLCur->dirHdl;    	    	if( pDirHdlCur->sector == pDirHdlFd->sector &&    	    pDirHdlCur->offset == pDirHdlFd->offset )    	    {    	    /* the same directory entry */    	        	    assert( pDirHdlCur->parDirStartCluster ==     	            pDirHdlFd->parDirStartCluster );    	    DBG_MSG( 600, " use %p instead of %p\n",    	    	     pFhdlLCur, pFd->pFileHdl,0,0,0,0,0,0 );    	        	    /* free file handle in <pFd> */    	        	    assert( pFd->pFileHdl->nRef == 1 );    	    bzero( (char *)pFd->pFileHdl, sizeof( *pFd->pFileHdl ) );    	        	    /* deference <pFd> */    	        	    pFd->pFileHdl = pFhdlLCur;    	    pFhdlLCur->nRef ++;    	    break;    	    }    	}    semGive( & pVolDesc->devSem );    } /* dosFsHdlDeref() */    /***************************************************************************** dosFsSeek - change file's current character position** This routine sets the specified file's current character position to* the specified position.  This only changes the pointer, doesn't affect* the hardware at all.** If the new offset pasts the end-of-file (EOF), attempts to read data* at this location will fail (return 0 bytes).** For a write if the seek is done past EOF, then use dosFsFillGap* to fill the remaining space in the file.** RETURNS: OK, or ERROR if invalid file position.** ERRNO:* S_dosFsLib_NOT_FILE**/ LOCAL STATUS dosFsSeek    (    DOS_FILE_DESC_ID	pFd,	/* file descriptor pointer */    fsize_t		newPos	/* ptr to desired character */    				/* position in file */    )    {    fsize_t	sizeBuf = pFd->pFileHdl->size; /* backup directory size */    u_int	nSec;		/* sector offset of new position */    				/* from seek start sector */    u_int	startSec;	/* cluster number to count clusters from */    STATUS	retStat = ERROR;        DBG_MSG( 500, "pFd = %p: newPos = %lu, "    		  "current pos = %lu, size = %lu\n",    		pFd, newPos, pFd->pos, pFd->pFileHdl->size,0,0,0,0 );    pFd->seekOutPos = 0;     if( newPos == pFd->pos )	/* nothing to do ? */    	return OK;            /*  there is no field storing actual directory length */        if( pFd->pFileHdl->attrib & DOS_ATTR_DIRECTORY )    	{    	pFd->pFileHdl->size = DOS_MAX_FSIZE;    	}        /* in case of seek passed EOF, only store the new position */        if( newPos > pFd->pFileHdl->size )    	{    	pFd->seekOutPos = newPos;    	return OK;    	}    /*     * to very simplify all process, let us pose at start     * of current cluster     */    if( pFd->curSec > 0 )	/* file is not just open */    	{    	/*     	 * now provide special support to the extreme case,    	 * when contiguous block have been passed and position    	 * stopped directly following it. In this case let return    	 * one cluster back. It may be important, when    	 * seek is called from close() in order to stand to    	 * the last file position.    	 */    	if( pFd->nSec == 0 )	/* contiguous block exhausted */    	    {    	    pFd->nSec	 = 1;    	    pFd->curSec	-= 1;    	    pFd->pos	-= pFd->nSec <<    	    		   pFd->pVolDesc->secSizeShift;    	    }    	else	/* goto start of the current sector */    	    {    	    pFd->pos	-= OFFSET_IN_SEC( pFd->pVolDesc, pFd->pos );    	    }    	} /* if( pFd->curSec > 0 ) */    /*     * count number of sectors to move and     * check for seek within current contiguous block     */    if( newPos < pFd->pos || pFd->curSec == 0 )	/* backward */    	{    	/* number of sector from file start to move to */    	    	nSec = NSECTORS( pFd->pVolDesc,                        min( newPos, pFd->pFileHdl->size - 1 ) );    	    	/* begin seeking from file start */    	    	startSec = FH_FILE_START;    	DBG_MSG(550, "SEEK_SET : startClust = %lu\n",     		pFd->pFileHdl->startClust ,0,0,0,0,0,0,0);    	}    else 	/* forward */    	{    	/*    	 * count number of sectors from current position.    	 * If newPos == size, temporary move into (size-1), that is         * last valid byte in file.         */    	nSec = min( newPos, pFd->pFileHdl->size - 1 ) - pFd->pos;    	nSec = NSECTORS( pFd->pVolDesc, nSec );    	if( nSec < pFd->nSec )	/* within current block ? */    	    {    	    pFd->nSec	-= nSec;    	    pFd->curSec	+= nSec;	    DBG_MSG(500, "within current cluster group\n", 0,0,0,0,0,0,0,0 );    	    goto retOK;    	    }    	    	/* begin seeking from current sector */    	    	startSec = pFd->curSec;    	DBG_MSG(550, "SEEK_CUR : startSec = %lu\n", startSec,0,0,0,0,0,0,0 );    	}        /* go ! */        if( pFd->pVolDesc->pFatDesc->seek( pFd, startSec, nSec ) == ERROR )    	{    	goto ret;    	}retOK:    pFd->pos = newPos;    retStat = OK;        /*     * special case, when the seek is done into the file last position,     * and this position is also first position in sector.     * Remember, that if newPos == size, we actually have moved     * into (size-1)     */    if( newPos == pFd->pFileHdl->size &&        OFFSET_IN_SEC( pFd->pVolDesc, newPos ) == 0 )    	{    	pFd->nSec --;    	pFd->curSec ++;    	}ret:    pFd->pFileHdl->size = sizeBuf;    return retStat;    } /* dosFsSeek() *//***************************************************************************** dosFsSeekDir - set current offset in directory.** This routine sets current offset in directory.  It takes special* care of contiguous root.** File semaphore should be taken prior calling this routine.** RETURNS: OK or ERROR, if seek is out of directory chain.*/LOCAL STATUS dosFsSeekDir    (    DOS_FILE_DESC_ID	pFd,	/* pointer to file descriptor */    DIR *	pDir	/* seek for dd_cookie position */    )    {    fsize_t	newOffset = DD_COOKIE_TO_POS( pDir );    if( pFd->pos == newOffset ) /* at the place */    	return OK;    /* special process for contiguous root */    if( IS_ROOT( pFd ) && pFd->pVolDesc->pDirDesc->rootNSec > 0 )    	{    	/* check for seek out of root */    	    	if( newOffset >= ( pFd->pVolDesc->pDirDesc->rootNSec <<			   pFd->pVolDesc->secSizeShift ) )    	    {    	    errnoSet( S_dosFsLib_INVALID_PARAMETER );    	    return ERROR;    	    }    	    	pFd->pos = newOffset;    	newOffset = NSECTORS( pFd->pVolDesc, newOffset );    	pFd->curSec = pFd->pVolDesc->pDirDesc->rootStartSec +     	    	      newOffset;    	pFd->nSec = pFd->pVolDesc->pDirDesc->rootNSec - newOffset;    	    	return OK;    	}    	    /* regular directory */    return dosFsSeek( pFd, (fsize_t)newOffset );    } /* dosFsSeekDir() *//***************************************************************************** dosFsIsDirEmpty - check if directory is empty.** This routine checks if directory is not a root directory and* whether it contains entries unless "." and "..".** RETURNS: OK if directory is empty and not root, else ERROR.** ERRNO:* S_dosFsLib_DIR_NOT_EMPTY**/LOCAL STATUS dosFsIsDirEmpty    (    DOS_FILE

⌨️ 快捷键说明

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