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

📄 rt11fslib.c

📁 大名鼎鼎的嵌入式操作系统vxworks的完整的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	max_entry.de_date   = rt11FsDate (rt11FsYear, rt11FsMonth, rt11FsDay);	rt11FsNameR50 (name, &max_entry.de_name);	rt11FsPutEntry (vdptr, max_e_num, &max_entry);	(void) rt11FsVolFlush (vdptr);	semGive (vdptr->vd_semId);			/* release volume */	pFd->rfd_dir_entry = max_entry;	pFd->rfd_start	   = max_start;	pFd->rfd_endptr	   = 0;	}    /* initialize rest of file descriptor */    pFd->rfd_mode	= mode;    pFd->rfd_vdptr	= vdptr;    pFd->rfd_curptr	= NONE;    pFd->rfd_newptr	= 0;    pFd->rfd_modified	= FALSE;    return (pFd);    }/********************************************************************************* rt11FsDate - generate RT-11 encoded date** This routine encodes the specified date into RT-1 format.** RETURNS: Encoded date.*/LOCAL int rt11FsDate    (    int year,           /* 72, or 72...03 */    int month,          /* 0, or 1...12 */    int day             /* 0, or 1...31 */    )    {    if ((year -= 72) < 0)	year += 100;    return ((month << 10) | (day << 5) | (year & 0x1f));    }/********************************************************************************* rt11FsDelete - delete RT-11 file** This routine deletes the file <name> from the specified RT-11 volume.** RETURNS:* OK, or* ERROR if file not found or volume not available.**/LOCAL STATUS rt11FsDelete    (    RT_VOL_DESC *vdptr, /* pointer to volume descriptor */    char *name          /* RT-11 filename (ffffff.ttt) */    )    {    int entryNum;    int start;    RT_DIR_ENTRY entry;    /* Set up for re-mount if no disk change notification */    if (vdptr->vd_changeNoWarn == TRUE)	rt11FsReadyChange (vdptr);    semTake (vdptr->vd_semId, WAIT_FOREVER);    /* check that volume is available */    if ((rt11FsCheckVol (vdptr, TRUE) != OK) || (vdptr->vd_status != OK))	{	semGive (vdptr->vd_semId);	errnoSet (S_rt11FsLib_VOLUME_NOT_AVAILABLE);	return (ERROR);	}    if (rt11FsVolMode (vdptr) == O_RDONLY)	{	semGive (vdptr->vd_semId);	errnoSet (S_ioLib_WRITE_PROTECTED);	return (ERROR);	}    /* search for entry with specified name */    if ((entryNum = rt11FsFindEntry (vdptr, name, &start)) == ERROR)	{	semGive (vdptr->vd_semId);		/* release volume */	return (ERROR);	}    rt11FsGetEntry (vdptr, entryNum, &entry);    entry.de_status = DES_EMPTY;    entry.de_date = 0;    rt11FsPutEntry (vdptr, entryNum, &entry);    rt11FsCoalesce (vdptr, entryNum);		/* merge with empty neighbors */    /* make sure directory is written out */    if (rt11FsVolFlush (vdptr) != OK)	{	semGive (vdptr->vd_semId);		/* release volume */	return (ERROR);	}    semGive (vdptr->vd_semId);			/* release volume */    return (OK);    }/********************************************************************************* rt11FsDevInit - initialize the rt11Fs device descriptor** This routine initializes the device descriptor.  The <pBlkDev> parameter is* a pointer to an already-created BLK_DEV device structure.  This structure* contains definitions for various aspects of the physical device format,* as well as pointers to the sector read, sector write, ioctl(), status check,* and reset functions for the device.** The <rt11Fmt> parameter is TRUE if the device is to be accessed using* standard RT-11 skew and interleave.** The device directory will consist of one segment able to contain at* least as many files as specified by <nEntries>.* If <nEntries> is equal to RT_FILES_FOR_2_BLOCK_SEG, strict RT-11* compatibility is maintained.** The <changeNoWarn> parameter is TRUE if the disk may be changed without* announcing the change via rt11FsReadyChange().  Setting <changeNoWarn> to* TRUE causes the disk to be regularly remounted, in case it has been* changed.  This results in a significant performance penalty.** NOTE* An ERROR is returned if <rt11Fmt> is TRUE and the `bd_blksPerTrack'* (sectors per track) field in the BLK_DEV structure is odd.* This is because an odd number of sectors per track is incompatible with the* RT-11 interleaving algorithm.** INTERNAL* The semaphore in the device is given, so the device is available for* use immediately.** RETURNS:* A pointer to the volume descriptor (RT_VOL_DESC), or* NULL if invalid device parameters were specified,* or the routine runs out of memory.*/RT_VOL_DESC *rt11FsDevInit    (    char            *devName,       /* device name */    FAST BLK_DEV    *pBlkDev,       /* pointer to block device info */    BOOL            rt11Fmt,        /* TRUE if RT-11 skew & interleave */    FAST int        nEntries,       /* no. of dir entries incl term entry */    BOOL            changeNoWarn    /* TRUE if no disk change warning */    )    {    FAST RT_VOL_DESC	*vdptr;		/* pointer to volume descriptor */    FAST int		segmentLen;	/* segment length in bytes */    FAST int		i;    /* Return error if no BLK_DEV */    if (pBlkDev == NULL)	{	errnoSet (S_rt11FsLib_NO_BLOCK_DEVICE);	return (NULL);	}    /* Don't allow odd number of sectors/track if RT-11 interleave specified */    if (rt11Fmt && (pBlkDev->bd_blksPerTrack & 1))	{	errnoSet (S_rt11FsLib_INVALID_DEVICE_PARAMETERS);	return (NULL);	}    /* Allocate an RT-11 volume descriptor for device */    if ((vdptr = (RT_VOL_DESC *) calloc (sizeof (RT_VOL_DESC), 1)) == NULL)	return (NULL);				/* no memory */    /* Add device to system device table */    if (iosDevAdd ((DEV_HDR *) vdptr, devName, rt11FsDrvNum) != OK)	{	free ((char *) vdptr);	return (NULL);				/* can't add device */	}    /* Initialize volume descriptor */    vdptr->vd_pBlkDev		= pBlkDev;    vdptr->vd_rtFmt		= rt11Fmt;    vdptr->vd_status		= OK;    vdptr->vd_state		= RT_VD_READY_CHANGED;    vdptr->vd_secBlock		= RT_BYTES_PER_BLOCK /				  pBlkDev->bd_bytesPerBlk;    vdptr->vd_nblocks		= pBlkDev->bd_nBlocks / vdptr->vd_secBlock;    /* Set flag for disk change without warning (removable disks only) */    if (pBlkDev->bd_removable)			/* if removable device */    	vdptr->vd_changeNoWarn = changeNoWarn;	/* get user's flag */    else    	vdptr->vd_changeNoWarn = FALSE;		/* always FALSE for fixed disk*/    /* how many bytes of space are needed for the segment? */    segmentLen = sizeof (RT_DIR_SEG) + (nEntries - 1) * sizeof (RT_DIR_ENTRY);    /* Allocate blocks for the segment.     * The smallest segment is 2 blocks long */    if  ((i = 1 + (segmentLen / RT_BYTES_PER_BLOCK)) < 2)	vdptr->vd_nSegBlocks = 2;    else        vdptr->vd_nSegBlocks = i;    /* allocate segment blocks */    vdptr->vd_dir_seg = (RT_DIR_SEG *)			malloc ((unsigned)				(vdptr->vd_nSegBlocks * RT_BYTES_PER_BLOCK));    if (vdptr->vd_dir_seg == NULL)	return (NULL);    vdptr->vd_semId = semMCreate (rt11FsVolMutexOptions);    if (vdptr->vd_semId == NULL)	return (NULL);				/* could not create semaphore */    return (vdptr);    }/********************************************************************************* rt11FsDirEntry - get info from a directory entry** This routine returns information about a particular directory entry into* the REQ_DIR_ENTRY structure whose pointer is passed as a parameter.* The information put there is the name of the file, its size (in bytes),* and its creation date.  If the specified entry is an empty (keeps* track of empty space on the disk), the name will be an empty string,* the size will be correct, and the date will be meaningless.** Before this routine is called, the field `entryNum' must set in* the REQ_DIR_ENTRY structure pointed to by rdeptr.  That is the entry* whose information will be returned.  Typically, the entries are accessed* sequentially starting with 0 until the terminating entry is reached* (indicated by a return code of ERROR).** RETURNS:* OK, or* ERROR if no such entry.*/LOCAL STATUS rt11FsDirEntry    (    RT_VOL_DESC *vdptr,         /* pointer to volume descriptor */    REQ_DIR_ENTRY *rdeptr       /* ptr to structure into which to put info */    )    {    RT_DIR_ENTRY *deptr;	/* pointer to directory entry in question */    FAST int maxEntries;	/* max number of entries allowed in directory */    /* Set up for re-mount if no disk change notification */    if (vdptr->vd_changeNoWarn == TRUE)	rt11FsReadyChange (vdptr);    semTake (vdptr->vd_semId, WAIT_FOREVER);    if (rt11FsCheckVol (vdptr, TRUE) != OK)	{	semGive (vdptr->vd_semId);	errnoSet (S_rt11FsLib_VOLUME_NOT_AVAILABLE);	return (ERROR);	}    /* what is the maximum number of entries allowed in this directory? */    maxEntries = (vdptr->vd_nSegBlocks * RT_BYTES_PER_BLOCK		- (sizeof (RT_DIR_SEG) - sizeof (RT_DIR_ENTRY)))		/ sizeof (RT_DIR_ENTRY);    if (rdeptr->entryNum >= maxEntries)	{	semGive (vdptr->vd_semId);	errnoSet (S_rt11FsLib_ENTRY_NUMBER_TOO_BIG);	return (ERROR);	}    deptr = &(vdptr->vd_dir_seg->ds_entries[rdeptr->entryNum]);    switch (deptr->de_status)	{	case DES_TENTATIVE:	/* - should indicate tentative somehow? */	case DES_PERMANENT:	    rt11FsNameString (deptr->de_name, rdeptr->name);	    break;	case DES_EMPTY:	    rdeptr->name[0] = EOS;			/* empty, no name */	    break;	default:	    semGive (vdptr->vd_semId);			/* release volume */	    errnoSet (S_rt11FsLib_FILE_NOT_FOUND);	    return (ERROR);				/* no such entry */	}    rdeptr->nChars = deptr->de_nblocks * RT_BYTES_PER_BLOCK;    rdeptr->day = (deptr->de_date >> 5) & 0x001f;    rdeptr->month = (deptr->de_date >> 10) & 0x000f;    rdeptr->year = (deptr->de_date & 0x001f) + 1972;    semGive (vdptr->vd_semId);			/* release volume */    return (OK);    }/********************************************************************************* rt11FsDirRead - read directory and return next file name** This routine support POSIX directory searches.  The directory is read,* and the name of the next file is returned in a "dirent" structure.* This routine is called via an ioctl() call with a function code of* FIOREADDIR.** RETURNS: OK, or ERROR if end of dir (errno = OK) or real error (errno set).*/LOCAL STATUS rt11FsDirRead    (    FAST RT_FILE_DESC   *pFd,           /* ptr to RT-11 file descriptor */    FAST DIR            *pDir           /* ptr to directory descriptor */    )    {    FAST int		entryNum;	/* position within dir */    FAST int		maxEntries;	/* number of entries in dir */    FAST char		*pChar;		/* ptr to char in filename string */    int			nameLen;	/* length of filename string */    FAST RT_DIR_ENTRY	*pEntry;	/* ptr to directory entry in memory */    FAST RT_VOL_DESC	*vdptr = pFd->rfd_vdptr;					/* ptr to volume descriptor */    semTake (vdptr->vd_semId, WAIT_FOREVER);    if (rt11FsCheckVol (vdptr, TRUE) != OK)	{	semGive (vdptr->vd_semId);	errnoSet (S_rt11FsLib_VOLUME_NOT_AVAILABLE);	return (ERROR);	}    /* Check if cookie (entry number) is past end of directory */    entryNum = pDir->dd_cookie;			/* get marker from DIR */    maxEntries = (vdptr->vd_nSegBlocks * RT_BYTES_PER_BLOCK		  - (sizeof (RT_DIR_SEG) - sizeof (RT_DIR_ENTRY)))		 / sizeof (RT_DIR_ENTRY);    /* Read an entry, keep going if empty */    do	{    	if (entryNum >= maxEntries)	    {	    semGive (vdptr->vd_semId);	    return (ERROR);			/* end of directory */	    }    	pEntry = &(vdptr->vd_dir_seg->ds_entries[entryNum]);						/* find entry within dir */	if (pEntry->de_status == DES_END)	    {	    semGive (vdptr->vd_semId);	    return (ERROR);			/* end of directory */	    }	entryNum++;	} while (pEntry->de_status == DES_EMPTY);    /* Copy name to dirent struct */   rt11FsNameString (pEntry->de_name, pDir->dd_dirent.d_name);   /* Cancel trailing blanks or "." */

⌨️ 快捷键说明

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