📄 wdbtsfsdrv.c
字号:
* 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: tsfsDev handle*/static int tsfsOpen ( TSFS_DEV * pDev, /* I/O system device entry */ char * name, /* name of file to open */ int mode, /* VxWorks open mode */ int perm /* permission bits */ ) { TSFS_CHANNEL_DESC * pChannel; /* channel handle */ int pmode = 0; /* portable open mode */ int pperm; /* portable open permission-word */ /* create a channel descriptor */ pChannel = (TSFS_CHANNEL_DESC *) malloc (sizeof (TSFS_CHANNEL_DESC)); if (pChannel == NULL) { errno = tsfsErrnoMap (ENOMEM); return ERROR; } /* initialize the channel descriptor */ pChannel->channel = tsfsChanNum++; semMInit (&pChannel->tsfsSem, mutexOptionsTsfsDrv); semBInit (&pChannel->waitSem, binaryOptionsTsfsDrv, SEM_EMPTY); /* initialize our event node */ wdbEventNodeInit (&pChannel->evtNode, tsfsEventGet, tsfsEventDeq, pChannel); /* Now format up an event. */ pChannel->info.info.channel = pChannel->channel; pChannel->info.info.opcode = WDB_TSFS_OPEN; pChannel->info.info.semId = (TGT_ADDR_T) &pChannel->waitSem; pChannel->info.info.pResult = (TGT_ADDR_T) &pChannel->result.value; pChannel->info.info.pErrno = (TGT_ADDR_T) &pChannel->result.errNo; pChannel->info.info.semGiveAddr = (TGT_ADDR_T) &semGive; pChannel->info.extra.open.filename = (TGT_ADDR_T) name; pChannel->info.extra.open.fnameLen = strlen (name); pChannel->openmode = mode; /* Map between VxWorks modes and portable TSFS modes. */ if (mode & O_CREAT) { pmode |= WDB_TSFS_O_CREAT; mode &= ~O_CREAT; } if (mode & O_TRUNC) { pmode |= WDB_TSFS_O_TRUNC; mode &= ~O_TRUNC; } if (mode & O_APPEND) { pmode |= WDB_TSFS_O_APPEND; mode &= ~O_APPEND; } if (mode & O_EXCL) { pmode |= WDB_TSFS_O_EXCL; mode &= ~O_EXCL; } if (mode & WDB_TSFS_O_TEXT) { pmode |= WDB_TSFS_O_TEXT; mode &= ~WDB_TSFS_O_TEXT; } switch (mode) { case O_RDONLY: pmode |= WDB_TSFS_O_RDONLY; break; case O_RDWR: pmode |= WDB_TSFS_O_RDWR; break; case O_WRONLY: pmode |= WDB_TSFS_O_WRONLY; break; } pChannel->info.extra.open.mode = pmode; /* * If we are creating a file, regular or directory, we let the host side * know what type by using the permission word. Here we map between * VxWorks' FSTAT_DIR/REG and the portable TSFS file types. See the * comments above about coercing the mode to O_RDONLY when creating * a directory. This coersion is done in the tgtsvr rather than here. */ pperm = perm; if (pmode & WDB_TSFS_O_CREAT) { if (perm & FSTAT_DIR) { pperm |= WDB_TSFS_S_IFDIR; pperm &= ~FSTAT_DIR; } else { pperm |= WDB_TSFS_S_IFREG; pperm &= ~FSTAT_REG; } } pChannel->info.extra.open.perm = pperm; /* Post the event. */ wdbEventPost (&pChannel->evtNode); /* Wait for the tgtsvr to get back to us with the result. */ semTake (&pChannel->waitSem, WAIT_FOREVER); if (pChannel->result.errNo == OK) { errno = 0; return (int) pChannel; } errno = tsfsErrnoMap (pChannel->result.errNo); free (pChannel); return ERROR; }/********************************************************************************* tsfsDelete - delete a file via the target server** RETURNS: status* NOMANUAL*/static int tsfsDelete ( TSFS_DEV * pDev, /* I/O system device entry */ char * name /* name of file to destroy */ ) { int result; TSFS_CHANNEL_DESC * pChannel; /* channel handle */ /* * for delete, we aren't given a channel to begin with. We'll have * to create one just for this operation. */ pChannel = (TSFS_CHANNEL_DESC *) malloc (sizeof (TSFS_CHANNEL_DESC)); if (pChannel == NULL) { errno = tsfsErrnoMap (ENOMEM); return ERROR; } /* * For non-file requests (i.e., ones like delete, where we don't * have an open file handle before we attempt the request), we * set the channel number to -1. */ pChannel->channel = -1; semBInit (&pChannel->waitSem, binaryOptionsTsfsDrv, SEM_EMPTY); /* initialize our event node */ wdbEventNodeInit (&pChannel->evtNode, tsfsEventGet, tsfsEventDeq, pChannel); /* Now format up an event. */ pChannel->info.info.channel = pChannel->channel; pChannel->info.info.opcode = WDB_TSFS_DELETE; pChannel->info.info.semId = (TGT_ADDR_T) &pChannel->waitSem; pChannel->info.info.pResult = (TGT_ADDR_T) &pChannel->result.value; pChannel->info.info.pErrno = (TGT_ADDR_T) &pChannel->result.errNo; pChannel->info.info.semGiveAddr = (TGT_ADDR_T) &semGive; pChannel->info.extra.remove.filename = (TGT_ADDR_T) name; pChannel->info.extra.remove.fnameLen = strlen (name); /* Post the event. */ wdbEventPost (&pChannel->evtNode); /* Wait for the tgtsvr to get back to us with the result. */ semTake (&pChannel->waitSem, WAIT_FOREVER); result = pChannel->result.value; errno = tsfsErrnoMap (pChannel->result.errNo); /* discard the temporary channel */ semTerminate (&pChannel->waitSem); free (pChannel); return result; }/******************************************************************************** tsfsClose - close a TSFS file** RETURNS: status* NOMANUAL*/ static STATUS tsfsClose ( TSFS_CHANNEL_DESC * pChannel /* channel handle */ ) { int result; semTake (&pChannel->tsfsSem, WAIT_FOREVER); /* prepare the event for transmission */ pChannel->info.info.channel = pChannel->channel; pChannel->info.info.opcode = WDB_TSFS_CLOSE; pChannel->info.info.semId = (TGT_ADDR_T) &pChannel->waitSem; pChannel->info.info.pResult = (TGT_ADDR_T) &pChannel->result.value; pChannel->info.info.pErrno = (TGT_ADDR_T) &pChannel->result.errNo; pChannel->info.info.semGiveAddr = (TGT_ADDR_T) &semGive; /* Post the event. */ wdbEventPost (&pChannel->evtNode); /* Wait for the tgtsvr to get back to us with the result. */ semTake (&pChannel->waitSem, WAIT_FOREVER); if (pChannel->result.errNo != OK) errno = tsfsErrnoMap (pChannel->result.errNo); /* XXX - reexamine this for reentrancy issues */ result = pChannel->result.value; semGive (&pChannel->tsfsSem); semTerminate (&pChannel->tsfsSem); semTerminate (&pChannel->waitSem); free (pChannel); return result; }/********************************************************************************* tsfsRead - read from a TSFS file** RETURNS: the number of bytes read if successful, or ERROR with errno set * to indicate the error.* NOMANUAL*/static int tsfsRead ( TSFS_CHANNEL_DESC * pChannel, /* channel handle */ char * buf, /* buffer to receive data */ int maxBytes /* max bytes to transfer */ ) { int result; semTake (&pChannel->tsfsSem, WAIT_FOREVER); /* prepare the event for transmission */ pChannel->info.info.channel = pChannel->channel; pChannel->info.info.opcode = WDB_TSFS_READ; pChannel->info.info.semId = (TGT_ADDR_T) &pChannel->waitSem; pChannel->info.info.pResult = (TGT_ADDR_T) &pChannel->result.value; pChannel->info.info.pErrno = (TGT_ADDR_T) &pChannel->result.errNo; pChannel->info.info.semGiveAddr = (TGT_ADDR_T) &semGive; pChannel->info.extra.rw.buffer = (TGT_ADDR_T) buf; pChannel->info.extra.rw.nBytes = maxBytes; /* Post the event. */ wdbEventPost (&pChannel->evtNode); /* Wait for the tgtsvr to get back to us with the result. */ semTake (&pChannel->waitSem, WAIT_FOREVER); if (pChannel->result.errNo != OK) errno = tsfsErrnoMap (pChannel->result.errNo); result = pChannel->result.value; semGive (&pChannel->tsfsSem); return result; }/******************************************************************************** tsfsWrite - write to a TSFS file** RETURNS: the number of bytes written if successful, or ERROR with errno * set to indicate the error.* NOMANUAL*/static int tsfsWrite ( TSFS_CHANNEL_DESC * pChannel, /* channel handle */ char * buf, /* buffer of data to be sent */ int maxBytes /* max bytes to transfer */ ) { int result; semTake (&pChannel->tsfsSem, WAIT_FOREVER); /* prepare the event for transmission */ pChannel->info.info.channel = pChannel->channel; pChannel->info.info.opcode = WDB_TSFS_WRITE; pChannel->info.info.semId = (TGT_ADDR_T) &pChannel->waitSem; pChannel->info.info.pResult = (TGT_ADDR_T) &pChannel->result.value; pChannel->info.info.pErrno = (TGT_ADDR_T) &pChannel->result.errNo; pChannel->info.info.semGiveAddr = (TGT_ADDR_T) &semGive; pChannel->info.extra.rw.buffer = (TGT_ADDR_T) buf; pChannel->info.extra.rw.nBytes = maxBytes; /* Post the event. */ wdbEventPost (&pChannel->evtNode); /* Wait for the tgtsvr to get back to us with the result. */ semTake (&pChannel->waitSem, WAIT_FOREVER); if (pChannel->result.errNo != OK) errno = tsfsErrnoMap (pChannel->result.errNo); result = pChannel->result.value; semGive (&pChannel->tsfsSem); return result; }/******************************************************************************** tsfsIoctl - special device control** RETURNS: status* NOMANUAL*/static STATUS tsfsIoctl ( TSFS_CHANNEL_DESC * pChannel, /* device to control */ int request, /* request code */ int arg /* some argument */ ) { int result; DIR * pDir = (DIR *) arg; /* For FIOREADDIR Only */ int pNewChannel; /* for FIOMKDIR */ char * pShortPath; /* for same */ semTake (&pChannel->tsfsSem, WAIT_FOREVER); /* map between VxWorks ioctl codes and supported TSFS codes */ switch (request) { case FIOSEEK: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_FIOSEEK; break; case FIOWHERE: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_FIOWHERE; break; case FIONREAD: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_FIONREAD; break; case FIOFSTATGET: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_FIOFSTATGET; break; case SO_SNDURGB: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_SO_SNDURGB; break; case SO_SETDEBUG: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_SO_SETDEBUG; break; case SO_GETDEBUG: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_SO_GETDEBUG; break; case SO_SETSNDBUF: pChannel->info.extra.ioctl.request = WDB_TSFS_IOCTL_SO_SETSNDBUF; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -