📄 ioslib.c
字号:
} iosUnlock (); return (pBestDevHdr); }/********************************************************************************* iosNextDevGet - get the next device in the device list** This routine gets the next device in the device list.* If the passed pointer is NULL, it starts at the top of the list.** RETURNS: Pointer to a device, or NULL if <pDev> is* the last device in the device list.** NOTE: This routine was public in 4.0.2 but is obsolete. It is made* no-manual in 5.0 and should be removed in the next major release.** NOMANUAL*/DEV_HDR *iosNextDevGet ( DEV_HDR *pDev ) { if (pDev == NULL) return ((DEV_HDR *) DLL_FIRST (&iosDvList)); else return ((DEV_HDR *) DLL_NEXT (&pDev->node)); }/********************************************************************************* iosFdValue - validate an open file descriptor and return the driver-specific value** This routine checks to see if a file descriptor is valid and* returns the driver-specific value.** RETURNS: The driver-specific value, or ERROR if the file descriptor is * invalid.*/int iosFdValue ( FAST int fd /* file descriptor to check */ ) { int xfd = STD_MAP (fd); if (xfd >= 0 && xfd < maxFiles && fdTable[xfd].inuse) return (fdTable[xfd].value); else { errnoSet (S_iosLib_INVALID_FILE_DESCRIPTOR); return (ERROR); } }/********************************************************************************* iosFdDevFind - verify if open file descriptor is valid and return a pointer to DEV_HDR** NOMANUAL*/DEV_HDR *iosFdDevFind ( FAST int fd ) { int xfd = STD_MAP (fd); if (xfd >= 0 && xfd < maxFiles && fdTable[xfd].inuse) return (fdTable[xfd].pDevHdr); else { errnoSet (S_iosLib_INVALID_FILE_DESCRIPTOR); return (NULL); } }/********************************************************************************* iosFdFree - free an file descriptor entry in the file descriptor table** This routine frees a file descriptor table entry.** NOMANUAL*/void iosFdFree ( int fd /* fd to free up */ ) { FAST FD_ENTRY *pFdEntry; FAST int xfd = STD_MAP(fd); if ((pFdEntry = FD_CHECK (xfd)) != NULL) { if (pFdEntry->name != NULL) { /* free name unless it is just the device name */ if (pFdEntry->name != pFdEntry->pDevHdr->name) free (pFdEntry->name); pFdEntry->name = NULL; } if (iosFdFreeHookRtn != NULL) (* iosFdFreeHookRtn) (fd); pFdEntry->inuse = FALSE; } }/********************************************************************************* iosFdSet - record file descriptor specifics in file descriptor table** This routine records the passed information about an file descriptor * into the file descriptor table.** The file name should NOT have been malloc'd prior to calling this routine.* The file name is now treated as follows:* if no file name is specified (NULL),* then the name pointer in the file descriptor entry is left NULL.* if the file name is the same as the device name,* then the name pointer in the file descriptor entry is set to point * to the device name* otherwise* space is malloc'd for the file name and it is copied to that space** This routine and iosFdFree ensure that the proper free'ing is done in each* of the cases.** This name handling eliminates the malloc/free in cases where the file name* is the device name (i.e. sockets, pipes, serial devices, etc).** NOMANUAL*/STATUS iosFdSet ( int fd, /* file descriptor */ DEV_HDR *pDevHdr, /* associated driver header */ char *name, /* name of file */ int value /* arbitrary driver info */ ) { FAST FD_ENTRY *pFdEntry = &fdTable [STD_UNFIX(fd)]; STATUS returnVal = OK; int error = 0; /* free name unless it is just the device name */ if ((pFdEntry->name != NULL) && (pFdEntry->name != pDevHdr->name)) free (pFdEntry->name); /* if no name specified, set it NULL; * if name is same as device name, make fd name point to device name; * otherwise malloc and copy file name */ if (name == NULL) pFdEntry->name = NULL; else if (strcmp (name, pDevHdr->name) == 0) pFdEntry->name = pDevHdr->name; else { if ((pFdEntry->name = (char *) malloc ((unsigned) (strlen (name) + 1))) == NULL) { error = 1; goto handleError; } strcpy (pFdEntry->name, name); } pFdEntry->pDevHdr = pDevHdr; pFdEntry->value = value; return returnVal; handleError: if (error > 0) { returnVal = ERROR; } return returnVal; }/********************************************************************************* iosFdNew - allocate and initialize a new fd** This routine gets the index of a free entry in the file descriptor table. * The entry is marked as reserved and will not be available again until it is* explicitly freed with iosFdFree().** RETURNS: The file descriptor or ERROR.** NOMANUAL*/int iosFdNew ( DEV_HDR *pDevHdr, /* associated driver header */ char *name, /* name of file */ int value /* arbitrary driver info */ ) { FAST int fd; FAST FD_ENTRY *pFdEntry = NULL; FAST int error = 0; iosLock (); for (fd = 0; fd < maxFiles; fd++) { if (!fdTable[fd].inuse) { pFdEntry = &fdTable[fd]; pFdEntry->inuse = TRUE; /* reserve this entry */ pFdEntry->name = NULL; break; } } iosUnlock (); fd = STD_FIX(fd); if (fd >= maxFiles) { errnoSet (S_iosLib_TOO_MANY_OPEN_FILES); error = 1; goto handleError; } if ((iosFdSet (fd, pDevHdr, name, value)) == ERROR) { error = 1; goto handleError; } if (iosFdNewHookRtn != NULL) { (* iosFdNewHookRtn) (fd); } return fd; handleError: if (error > 0) { if (pFdEntry != NULL) { pFdEntry->inuse = FALSE; pFdEntry->name = NULL; } fd = (int)ERROR; } return (fd); }/********************************************************************************* iosCreat - invoke driver to open file** RETURNS: OK if there is no create routine, or a driver-specific value.** NOMANUAL*/int iosCreate ( DEV_HDR *pDevHdr, char *fileName, int mode ) { FUNCPTR drvCreate = drvTable [pDevHdr->drvNum].de_create; if (drvCreate != NULL) return ((*drvCreate)(pDevHdr, fileName, mode)); else return (OK); }/********************************************************************************* iosDelete - invoke driver to delete file** RETURNS: OK if there is no delete routine, or a driver-specific value.** NOMANUAL*/int iosDelete ( DEV_HDR *pDevHdr, char *fileName ) { FUNCPTR drvDelete = drvTable [pDevHdr->drvNum].de_delete; if (drvDelete != NULL) return ((*drvDelete)(pDevHdr, fileName)); else return (OK); }/********************************************************************************* iosOpen - invoke driver to open file** RETURNS:* OK if the driver has no open routine, or* whatever the driver's open routine returns.** NOMANUAL*/int iosOpen ( DEV_HDR *pDevHdr, char *fileName, int flags, int mode ) { FUNCPTR drvOpen = drvTable [pDevHdr->drvNum].de_open; if (drvOpen != NULL) return ((*drvOpen)(pDevHdr, fileName, flags, mode)); else return (OK); }/********************************************************************************* iosClose - invoke driver to close file** RETURNS:* OK if the driver has no close routine, or* whatever the driver's close routine returns, or* ERROR if the file descriptor is invalid.** NOMANUAL*/STATUS iosClose ( int fd ) { STATUS status; FUNCPTR drvClose; FD_ENTRY *pFdEntry; FAST int xfd = STD_MAP(fd); if ((pFdEntry = FD_CHECK (xfd)) == NULL) status = ERROR; /* status set when bad fd */ else { drvClose = drvTable [pFdEntry->pDevHdr->drvNum].de_close; if (drvClose != NULL) status = (*drvClose)(pFdEntry->value); else status = OK; iosFdFree (STD_FIX(xfd)); } return (status); }/********************************************************************************* iosRead - invoke driver read routine** RETURNS:* Whatever the driver's read routine returns (number of bytes read), or* ERROR if the file descriptor is invalid or if the driver has no read * routine. If the driver has no read routine, errno is set to ENOTSUP.** NOMANUAL*/int iosRead ( int fd, char *buffer, int maxbytes ) { FUNCPTR drvRead; FAST FD_ENTRY *pFdEntry; FAST int xfd = STD_MAP(fd); if ((pFdEntry = FD_CHECK (xfd)) == NULL) return (ERROR); drvRead = drvTable [pFdEntry->pDevHdr->drvNum].de_read; if (drvRead == NULL) { errno = ENOTSUP; return (ERROR); } else return ((* drvRead) (pFdEntry->value, buffer, maxbytes)); }/********************************************************************************* iosWrite - invoke driver write routine** RETURNS:* Whatever the driver's write routine returns (number of bytes written), or* ERROR if the file descriptor is invalid or if the driver has no write* routine. If the driver has no write routine, errno is set to ENOTSUP.** NOMANUAL*/int iosWrite ( int fd, char *buffer, int nbytes ) { FUNCPTR drvWrite; FAST FD_ENTRY *pFdEntry; FAST int xfd = STD_MAP(fd); if ((pFdEntry = FD_CHECK (xfd)) == NULL) return (ERROR); drvWrite = drvTable [pFdEntry->pDevHdr->drvNum].de_write; if (drvWrite == NULL) { errno = ENOTSUP; return (ERROR); } else return ((* drvWrite) (pFdEntry->value, buffer, nbytes)); }/********************************************************************************* iosIoctl - invoke driver ioctl routine** RETURNS:* OK if the function is FIOGETNAME (and arg set to name), or* if driver has no ioctl routine and* function is FIONREAD then 0 otherwise ERROR, or* whatever driver ioctl routine returns, or* ERROR if invalid file descriptor** NOMANUAL*/int iosIoctl ( int fd, int function, int arg ) { FUNCPTR drvIoctl; FAST FD_ENTRY *pFdEntry; FAST int xfd = STD_MAP(fd); if ((pFdEntry = FD_CHECK (xfd)) == NULL) return (ERROR); if (function == FIOGETNAME) { strcpy ((char *) arg, pFdEntry->name); return (OK); } drvIoctl = drvTable [pFdEntry->pDevHdr->drvNum].de_ioctl; if (drvIoctl == NULL) { if (function == FIONREAD) { * (char *) arg = 0; return (OK); } else { errnoSet (S_ioLib_UNKNOWN_REQUEST); return (ERROR); } } else { return ((* drvIoctl) (pFdEntry->value, function, arg)); } }/********************************************************************************* iosLock - get exclusive use of I/O data structures** This routine takes exclusive use of the I/O system's data structures,* by taking the semaphore used for that purpose. If the semaphore* is already taken, the calling task will suspend until the* semaphore is available.*/LOCAL void iosLock (void) { semTake (&iosSemaphore, WAIT_FOREVER); }/********************************************************************************* iosUnlock - release exclusive use of I/O data structures** This routine releases the semaphore which had been checked out by iosLock.* This routine should only be called by a task which currently has the* semaphore.*/LOCAL void iosUnlock (void) { semGive (&iosSemaphore); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -