📄 hpcfsdrv.c
字号:
* receives the results.*** This routine is also used to create files and directories. After the file* or directory is created, it is opened and a valid device handle is handed* back to the caller.** Note, when creating a directory, the mode argument (O_RDWR, O_RDONLY...)* is not necessary, except to indicate O_CREAT. It is illegal in most file* systems, including all of VxWorks' file systems, to open a directory in* any mode other than O_RDONLY. Because the directory is created, as well* as opened in this routine, it is unreasonable to expect that the mode be* O_RDONLY in order to succeed. After all, the user wants to create the* directory, not open it. This is confused by our implementation of mkdir,* where open is used to do the creation. To resolve the problem here, the* mode is coerced to O_RDONLY when a directory is being created. Opening a* directory (not creating it too) will rightfully fail if the mode is* anything other than O_RDONLY.** NOMANUAL** RETURNS: hpcfsDev handle*/static int hpcfsOpen ( HPCFS_DEV *pDev, /* I/O system device entry */ char *name, /* name of file to open */ int mode, /* VxWorks open mode */ int perm /* permission bits */){ HPCFS_CHANNEL_DESC * pFileHandle; /* File handle */ int pmode = 0; /* portable open mode */ int pperm; /* portable open permission-word */ int result; /* Create a file descriptor */ pFileHandle = (HPCFS_CHANNEL_DESC*) malloc(sizeof(HPCFS_CHANNEL_DESC)); if (pFileHandle == NULL) { errno = hpcfsErrnoMap(ENOMEM); return ERROR; } /* Map between VxWorks modes and HPCFS modes */ if (mode & O_CREAT) { pmode |= HPCFS_O_CREAT; mode &= ~O_CREAT; } if (mode & O_TRUNC) { pmode |= HPCFS_O_TRUNC; mode &= ~O_TRUNC; } if (mode & O_APPEND) { pmode |= HPCFS_O_APPEND; mode &= ~O_APPEND; } if (mode & O_EXCL) { pmode |= HPCFS_O_EXCL; mode &= ~O_EXCL; } if (mode & HPCFS_O_TEXT) { pmode |= HPCFS_O_TEXT; mode &= ~HPCFS_O_TEXT; } switch (mode) { case O_RDONLY: pmode |= HPCFS_O_RDONLY; break; case O_RDWR: pmode |= HPCFS_O_RDWR; break; case O_WRONLY: pmode |= HPCFS_O_WRONLY; break; } /* Map to permission word */ pperm = perm; if (pmode & HPCFS_O_CREAT) { if (perm & FSTAT_DIR) { pperm &= ~FSTAT_DIR; pperm |= HPCFS_S_IFDIR; } else { pperm &= ~FSTAT_REG; pperm |= HPCFS_S_IFREG; } } pFileHandle->mode = pmode; pFileHandle->perm = pperm; /* Issue the open call */ result = hpcfsFuncOpen(pmode, pperm, name, &pFileHandle->channel); if (result == OK) { errno = 0; return (int) pFileHandle; } errno = hpcfsErrnoMap(result); return ERROR;}/********************************************************************************* hpcfsDelete - delete a file via the target server** RETURNS: status* NOMANUAL*/static int hpcfsDelete ( HPCFS_DEV * pDev, /* I/O system device entry */ char * name /* name of file to destroy */ ) { int result; result = hpcfsFuncDel(name); if (result == OK) { errno = 0; return OK; } errno = hpcfsErrnoMap(result); return ERROR;}/******************************************************************************** hpcfsClose - close a HPCFS file** RETURNS: status* NOMANUAL*/ static STATUS hpcfsClose ( HPCFS_CHANNEL_DESC * pChannel /* channel handle */ ) { int result; result = hpcfsFuncClose(pChannel->channel); if (result != OK) { errno = hpcfsErrnoMap(result); } free(pChannel); return result;}/********************************************************************************* hpcfsRead - read from a HPCFS file** RETURNS: the number of bytes read if successful, or ERROR with errno set * to indicate the error.* NOMANUAL*/static int hpcfsRead ( HPCFS_CHANNEL_DESC * pChannel, /* channel handle */ char * buf, /* buffer to receive data */ int maxBytes /* max bytes to transfer */ ) { int result; int actuallyRead; result = hpcfsFuncRead(pChannel->channel, buf, maxBytes, &actuallyRead); if (result == OK) { errno = 0; return actuallyRead; } errno = hpcfsErrnoMap(result); return ERROR;}/******************************************************************************** hpcfsWrite - write to a HPCFS file** RETURNS: the number of bytes written if successful, or ERROR with errno * set to indicate the error.* NOMANUAL*/static int hpcfsWrite ( HPCFS_CHANNEL_DESC * pChannel, /* channel handle */ char * buf, /* buffer of data to be sent */ int maxBytes /* max bytes to transfer */ ) { int result; int actWritten; result = hpcfsFuncWrite(pChannel->channel, buf, maxBytes, &actWritten); if (result == OK) { errno = 0; return actWritten; } errno = hpcfsErrnoMap(result); return ERROR;}/******************************************************************************** hpcfsIoctl - special device control** RETURNS: status* NOMANUAL*/static STATUS hpcfsIoctl ( HPCFS_CHANNEL_DESC * pChannel, /* device to control */ int request, /* request code */ int arg /* some argument */ ) { int result; int prequest; int resultArg; char * pShortPath; /* for same */ switch (request) { case FIOSEEK: prequest = HPCFS_IOCTL_FIOSEEK; break; case FIOWHERE: prequest = HPCFS_IOCTL_FIOWHERE; break; case FIONREAD: prequest = HPCFS_IOCTL_FIONREAD; break; case FIORENAME: prequest = HPCFS_IOCTL_FIORENAME; /* * If the new name starts with the device name, strip the * device name first. If it doesn't just continue. */ if ((pShortPath = strstr ((char *) arg, hpcfsDev.devHdr.name)) != NULL) { /* * If the device name is in the path, but not the first * element of the path, use the whole path. Otherwise * remove the device name. For example, /tgtsvr/foo/goo * should yield /foo/goo, but /foo/tgtsvr/goo should * remain /foo/tgtsvr/goo (/tgtsvr is the dev name). */ if (pShortPath != (char *) arg) pShortPath = (char *) arg; else pShortPath = (char *) arg + strlen (hpcfsDev.devHdr.name); } else { pShortPath = (char *) arg; } /*@@*/ break; case FIOGETFL: /* this one is handled locally. */ *((int *) arg) = pChannel->mode; return (OK); /* don't pass unknown ioctl's up to target server. */ default: errno = hpcfsErrnoMap (HPC_INVALID_OP); return ERROR; } /*@@ needs work */ result = hpcfsFuncIoctl(pChannel->channel, prequest, arg, &resultArg); if (result != OK) errno = hpcfsErrnoMap(result); /* * Some ioctl() requests require us to fill in data pointed to by arg. * If so we take care of that here. */ switch (request) { case FIONREAD: *((int*)arg) = resultArg; break; } return result;}/******************************************************************************** hpcfsErrnoMap - map errnos returned from host to vxWorks' errnos** This routine maps from the portable errno values defined in hpcFs.h for* the HPCFS, to errnos defined on the target. All POSIX errnos are passed* through this mapping without change. ** INTERNAL* Errnos that are not defined as portable. This includes POSIX errnos, but* is may include more if some get through the cracks.** RETURNS: vxWorks' errno, or zero (0) if passed zero (0) * * NOMANUAL*/static int hpcfsErrnoMap ( int hostErrno ){ int wverr; switch (hostErrno) { case HPCFS_ERRNO_ENOTEMPTY: wverr = ENOTEMPTY; break; case HPCFS_ERRNO_EDEADLK: wverr = EDEADLK; break; case HPCFS_ERRNO_ENOLCK: wverr = ENOLCK; break; case HPCFS_ERRNO_EMSGSIZE: wverr = EMSGSIZE; break; case HPCFS_ERRNO_EOPNOTSUPP: wverr = EOPNOTSUPP; break; case HPCFS_ERRNO_EADDRNOTAVAIL: wverr = EADDRNOTAVAIL; break; case HPCFS_ERRNO_ENOTSOCK: wverr = ENOTSOCK; break; case HPCFS_ERRNO_ENETRESET: wverr = ENETRESET; break; case HPCFS_ERRNO_ECONNABORTED: wverr = ECONNABORTED; break; case HPCFS_ERRNO_ECONNRESET: wverr = ECONNRESET; break; case HPCFS_ERRNO_ECONNREFUSED: wverr = ECONNREFUSED; break; case HPCFS_ERRNO_ENOBUFS: wverr = ENOBUFS; break; case HPCFS_ERRNO_ENOTCONN: wverr = ENOTCONN; break; case HPCFS_ERRNO_ESHUTDOWN: wverr = ESHUTDOWN; break; case HPCFS_ERRNO_ETIMEDOUT: wverr = ETIMEDOUT; break; case HPCFS_ERRNO_EINPROGRESS: wverr = EINPROGRESS; break; case HPCFS_ERRNO_EWOULDBLOCK: wverr = EWOULDBLOCK; break; case HPCFS_ERRNO_ENOSR: wverr = ENOSR; break; case HPCFS_ERRNO_ELOOP: wverr = ELOOP; break; case HPCFS_ERRNO_ENAMETOOLONG: wverr = ENAMETOOLONG; break; case HPCFS_ERRNO_EBADMSG: wverr = EBADMSG; break; default: wverr = hostErrno; } return wverr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -