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

📄 passfslib.c

📁 VXWORKS源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    pStat->st_mtime = unixbuf.st_mtime;		/* file modified time */    /* Set file type in mode field, mark whole volume (raw mode) as directory */    pStat->st_mode = 0;				/* clear field */    if (unixbuf.st_mode & 0x4000)		/* if directory */	{	pStat->st_mode |= S_IFDIR;		/*  set bits in mode field */	}    else if (unixbuf.st_mode & 0x8000)		/* if reg file */	{	pStat->st_mode |= S_IFREG;		/*  it is a regular file */	}    pStat->st_mode |= unixbuf.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);    return (OK);    }		/********************************************************************************* passFsInit - prepare to use the passFs library** This routine initializes the passFs library.  It must be called exactly once,* before any other routines in the library.  The argument specifies the number* of passFs devices that may be open at once.  This routine installs* passFsLib as a driver in the I/O system driver table, allocates and sets * up the necessary memory structures, and initializes semaphores.** Normally this routine is called from the root task, usrRoot(),* in usrConfig().  This initialization is enabled when the* configuration macro INCLUDE_PASSFS is defined.** NOTE* Maximum number of pass-through file systems is 1.** RETURNS: OK, or ERROR.*/STATUS passFsInit    (    int nPassfs	/* number of pass-through file systems */    )    {    if (passFsDrvNum != 0)	return (ERROR);			/* can't call more than once */    /* Install passFsLib routines in I/O system driver table */    passFsDrvNum = iosDrvInstall ((FUNCPTR) passFsCreate, passFsDelete, 			         (FUNCPTR) passFsOpen, passFsClose, 			         passFsRead, passFsWrite, passFsIoctl);    if (passFsDrvNum == ERROR)	return (ERROR);				/* can't install as driver */    if (nPassfs < 0 || nPassfs > 1)	return (ERROR);				/* can't install as driver */    if ((passVolume = calloc (nPassfs, sizeof (VOL_DESC))) == NULL)	return (ERROR);    return (OK);    }/********************************************************************************* passFsIoctl - do device specific control function** This routine performs the following ioctl() functions:** .CS*    FIODISKINIT:   Initialize the disk volume.  This routine does not*                   format the disk, that must be done by the driver.*    FIORENAME:     Rename the file to the string pointed to by arg.*    FIOSEEK:       Sets the file's current byte position to*                   the position specified by arg.*    FIOWHERE:      Returns the current byte position in the file.*    FIOFLUSH:      Flush file output buffer.*                   Guarantees that any output that has been requested*                   is actually written to the device.*    FIONREAD:      Return in arg the number of unread bytes.*    FIODISKCHANGE: Indicate media change.  See passFsReadyChange().*    FIOUNMOUNT:    Unmount disk volume.  See passFsVolUnmount().*    FIONFREE:	    Return amount of free space on volume.*    FIOMKDIR:	    Create a new directory.*    FIORMDIR:	    Remove a directory.*    FIOLABELGET:   Get volume label (located in root directory).*    FIOLABELSET:   Set volume label.*    FIOATTRIBSET:  Set file attribute.*    FIOCONTIG:	    Allocate contiguous disk space for file or directory.*    FIOSYNC:	    Write all modified files and data structures to device.*    FIOREADDIR:    Read next directory entry, uses DIR directory descriptor.*    FIOFSTATGET:   Get file status info (directory enty data).* .CE** Any other ioctl function codes are passed to the block device driver* for handling.** If an ioctl fails, the task's status (see errnoGet()) indicates* the nature of the error.** RETURNS: OK, or ERROR if function failed or driver returned error, or*   current byte pointer for FIOWHERE.*/LOCAL STATUS passFsIoctl    (    PASS_FILE_DESC	*pPassFd,	/* file descriptor of file to control */    int			function,	/* function code */    int			arg		/* some argument */    )    {    int	retValue = OK;    int whereCur;	/* current byte position in file, could include cache */    int where;		/* exact current byte position in file */    int end;        switch (function)	{	case FIODISKINIT:	    break;	case FIORENAME:	    if (u_rename (pPassFd->passName, (char *)arg) == -1)		retValue = ERROR;	    break;	case FIOSEEK:	    /* invalidate any read cache */	    pPassFd->cacheBytes = 0;    	    pPassFd->cacheOffset = 0;	    /* do a lseek with offset arg0 from beginning of file */	    if (u_lseek (pPassFd->unixFd, (int)arg, 0) == -1)		retValue = ERROR;	    break;	case FIOWHERE:	    /* do a lseek with offset 0 from current to get current offset */	    retValue = u_lseek (pPassFd->unixFd, 0, 1/*SEEK_CUR*/);	    /* Adjust since we cache ahead, so LSEEK returns too far */	    if (retValue > 0 && pPassFd->cacheBytes != 0)		retValue -= (pPassFd->cacheBytes - pPassFd->cacheOffset);	    break;	case FIOSYNC:	case FIOFLUSH:	    break;	case FIONREAD:	    /* 	     * compute the number of bytes between the current location and	     * the end of this file.	     * We uses this method rather than a call to :	     * u_ioctl (pPassFd->unixFd, U_FIONREAD, 0);	     * because FIONREAD is not officially supported on Solaris and it	     * does not work on Solaris 2.5. (SPR #22476 & 23615).	     */	    	    whereCur = u_lseek (pPassFd->unixFd, 0, 1/*SEEK_CUR*/);	    if (whereCur == ERROR)	    	retValue = ERROR;	    else	    	{		/* Adjust since we cache ahead, so LSEEK returns too far */		if (pPassFd->cacheBytes != 0)		    where = whereCur - 		    	(pPassFd->cacheBytes - pPassFd->cacheOffset);		else		   where = whereCur;			    	end = u_lseek (pPassFd->unixFd, 0, 2/*SEEK_END*/);		if (end	== ERROR)		    retValue = ERROR;			else		    {		    /* go back to the current location */		    if (u_lseek (pPassFd->unixFd, whereCur, 0/*SEEK_SET*/) 		    	== ERROR)			retValue = ERROR;	 	    else		    	        *((int *) arg) = end - where;		    }		    	}	    break;	case FIODISKCHANGE:	    break;	case FIOUNMOUNT:	    break;	case FIONFREE:	    /* this is hard to do on a UNIX file system - lie */	    *((int *) arg) = 0x1000000;	    break;	case FIOMKDIR:	    if (passFsDirMake (pPassFd->passVdptr, (char *) arg, FALSE) 	    		== ERROR)		retValue = ERROR;	    break;	case FIORMDIR:	    if (u_rmdir (pPassFd->passName) == -1)		retValue = ERROR;	    break;	case FIOLABELGET:	    strcpy ((char *)arg, passVolume->passDevName);	    break;	case FIOLABELSET:	    break;	case FIOATTRIBSET:	    break;	case FIOCONTIG:	    break;	case FIOREADDIR:	    retValue = passFsDirRead (pPassFd, (DIR *) arg);	    break;	case FIOFSTATGET:	    retValue = passFsFileStatGet (pPassFd, (struct stat *) arg);	    break;	case FIOSETOPTIONS:	    /* XXX usually trying to set OPT_TERMINAL -- just ignore */	    break;	default:	    printErr ("passFsLib: unknown ioctl = %#x\n", function);	    retValue = ERROR;	    break;	}    return (retValue);    }/********************************************************************************* passFsOpen - open a file on a passFs volume** This routine opens the file <name> with the specified mode * (READ/WRITE/UPDATE/CREATE/TRUNC).  The directory structure is * searched, and if the file is found a passFs file descriptor * is initialized for it.** RETURNS: A pointer to a passFs file descriptor, or ERROR *   if the volume is not available *   or there are no available passFs file descriptors *   or there is no such file.*/LOCAL PASS_FILE_DESC *passFsOpen    (    VOL_DESC	*vdptr,		/* pointer to volume descriptor	*/    char	*name,		/* passFs full path/filename */    int		flags,		/* file open flags */    int		mode		/* file open permissions (mode) */    )    {    PASS_FILE_DESC	*pPassFd;	/* file descriptor pointer */    /* Check if creating dir */    if ((flags & O_CREAT)  &&  (mode & FSTAT_DIR))        {	return (passFsDirCreate (vdptr, name));	}    /* Get a free file descriptor */    if ((pPassFd = (PASS_FILE_DESC *) calloc (1, sizeof (PASS_FILE_DESC)))								== NULL)	{	return ((PASS_FILE_DESC *) ERROR);	}    if ((pPassFd->unixFd = u_open (name, ARCHCVTFLAGS(flags), mode)) == -1)	{	free (pPassFd);	return ((PASS_FILE_DESC *) ERROR);	}    strcpy (pPassFd->passName, name);    pPassFd->passDir     = (UNIX_DIR *)0;    pPassFd->readCache   = (char *)0;    pPassFd->cacheBytes  = 0;    pPassFd->cacheOffset = 0;    pPassFd->passVdptr   = vdptr;    return (pPassFd);    }/********************************************************************************* passFsRead - read from a passFs file** This routine reads from the file specified by the file descriptor* (returned by passFsOpen()) into the specified buffer.* <maxbytes> bytes will be read, if there is that much data in the file* and the file I/O buffer is large enough.** RETURNS: Number of bytes actually read, or 0 if end of file, or*    ERROR if <maxbytes> is <= 0 or unable to get next cluster.*/LOCAL int passFsRead    (    PASS_FILE_DESC	*pPassFd,	/* file descriptor pointer */    char		*pBuf,		/* addr of input buffer	*/    int			maxBytes	/* maximum bytes to read into buffer */    )    {    int ret;    int bytesRead = 0;    int readableCacheBytes;    char *cachePtr;    /* attempt to service the read from cache first */    if (pPassFd->cacheBytes)	{        readableCacheBytes = pPassFd->cacheBytes - pPassFd->cacheOffset;	cachePtr = pPassFd->readCache + pPassFd->cacheOffset;	/* if we have more cached data than asked for */	if (readableCacheBytes > maxBytes) {	   readableCacheBytes = maxBytes;	   pPassFd->cacheOffset += readableCacheBytes;	} else {	   /* invalidate cache since its all going to be read */	   pPassFd->cacheBytes = 0;	   pPassFd->cacheOffset = 0;	}	bcopy (cachePtr, pBuf, readableCacheBytes);	/* if we are done, bail now */	if (readableCacheBytes == maxBytes)		return (maxBytes);	maxBytes -= readableCacheBytes;	bytesRead += readableCacheBytes;	pBuf += readableCacheBytes;	}    /* initialize read cache if first read */    if (pPassFd->readCache == (char *)0)	{	if ((pPassFd->readCache = (char*)calloc (1, CACHE_SIZE)) == (char *)0)	    return (ERROR);	}    /* ok, here we know the cache is allocated and invalidated */    /* caching can't help if they want a huge chunk */    if (maxBytes >= CACHE_SIZE)	{    	if ((ret = u_read (pPassFd->unixFd, pBuf, maxBytes)) == -1)	    return (bytesRead ? bytesRead : ERROR);	bytesRead += ret;	}    else	{	ret = u_read (pPassFd->unixFd,pPassFd->readCache, CACHE_SIZE);        if ( ret == -1)	    return (bytesRead ? bytesRead : ERROR);	pPassFd->cacheBytes = ret;	/* If there wasn't as much as asked for */	if (ret < maxBytes)	    maxBytes = ret;	bcopy (pPassFd->readCache, pBuf, maxBytes);	bytesRead += maxBytes;	pPassFd->cacheOffset = maxBytes;	}    return (bytesRead);    }/********************************************************************************* passFsWrite - write to a passFs file** This routine writes to the file specified by the file descriptor* (returned by passFsOpen()) from the specified buffer. ** RETURNS: Number of bytes written (error if != nBytes), or ERROR if *    nBytes < 0, or no more space for the file, or can't write cluster.*/LOCAL int passFsWrite     (    PASS_FILE_DESC	*pPassFd,	/* file descriptor pointer */    char		*pBuf,		/* data to be written */    int			maxBytes	/* number of bytes to write */    )    {    int nBytes;    /* invalidate read cache */    pPassFd->cacheBytes = 0;    pPassFd->cacheOffset = 0;    if ((nBytes = u_write (pPassFd->unixFd, pBuf, maxBytes)) == -1)	return (ERROR);    return (nBytes);    }#endif /* (CPU_FAMILY==SIMSPARCSUNOS || CPU_FAMILY==SIMHPPA || CPU_FAMILY==SIMSPARCSOLARIS) */

⌨️ 快捷键说明

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