📄 ptydrv.c
字号:
/* ptyDrv.c - pseudo-terminal driver *//* Copyright 1984-2003 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02a,22nov02,pmr SPR 67514: checking for errors in ptyMasterWrite().01z,12oct01,brk added SELECT functionality to Master (SPR #65498) 01y,19oct01,dcb Fix the routine title line to match the coding conventions.01x,14feb01,spm merged from version 01x of tor2_0_x branch (base 01w): added removal of pty device (SPR #28675)01w,12mar99,p_m Fixed SPR 9124 by mentioning that there is no way to delete a pty device.01v,03feb93,jdi documentation cleanup for 5.1.01u,13nov92,dnw added include of semLibP.h01t,21oct92,jdi removed mangen SECTION designation.01s,18jul92,smb Changed errno.h to errnoLib.h.01r,04jul92,jcf scalable/ANSI/cleanup effort.01q,26may92,rrr the tree shuffle01p,19nov91,rrr shut up some ansi warnings.01o,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed includes to have absolute path from h/ -changed VOID to void -changed copyright notice01n,05apr91,jdi documentation -- removed header parens and x-ref numbers; doc review by rdc.01m,27feb91,jaa documentation update.01l,26jun90,jcf changed semaphore type for 5.0. Embedded semaphore.01k,23mar90,dab removed ptyMasterDelete() and ptySlaveDelete().01j,15feb90,dab added ptyMasterDelete() and ptySlaveDelete(). documentation.01i,30may88,dnw changed to v4 names.01h,04may88,jcf changed semaphores to be consistent with new semLib.01g,06nov87,ecs documentation.01f,24oct87,gae added pty{Master,Slave}Close() so that reads on corresponding would return 0/ERROR.01e,20oct87,gae made ptyDrv() return correct status on succesive calls. documentation.01d,25mar87,jlf documentation01c,21dec86,dnw changed to not get include files from default directories.01b,02jul86,jlf documentation01a,01apr86,rdc wrotten.*//*The pseudo-terminal driver provides a tty-like interface between a master andslave process, typically in network applications. The master processsimulates the "hardware" side of the driver (e.g., a USART serial chip), whilethe slave process is the application program that normally talks to the driver.USER-CALLABLE ROUTINESMost of the routines in this driver are accessible only through the I/Osystem. However, the following routines must be called directly: ptyDrv() toinitialize the driver, ptyDevCreate() to create devices, and ptyDevRemove()to remove an existing device.INITIALIZING THE DRIVERBefore using the driver, it must be initialized by calling ptyDrv().This routine must be called before any reads, writes, or calls toptyDevCreate().CREATING PSEUDO-TERMINAL DEVICESBefore a pseudo-terminal can be used, it must be created by callingptyDevCreate():.CS STATUS ptyDevCreate ( char *name, /@ name of pseudo terminal @/ int rdBufSize, /@ size of terminal read buffer @/ int wrtBufSize /@ size of write buffer @/ ).CEFor instance, to create the device pair "/pty/0.M" and "/pty/0.S",with read and write buffer sizes of 512 bytes, the proper call would be:.CS ptyDevCreate ("/pty/0.", 512, 512);.CEWhen ptyDevCreate() is called, two devices are created, a master andslave. One is called <name>M and the other <name>S. They canthen be opened by the master and slave processes. Data written to themaster device can then be read on the slave device, and vice versa. Callsto ioctl() may be made to either device, but they should only apply to theslave side, since the master and slave are the same device.The ptyDevRemove() routine will delete an existing pseudo-terminal deviceand reclaim the associated memory. Any file descriptors associated withthe device will be closed.IOCTL FUNCTIONSPseudo-terminal drivers respond to the same ioctl() functions used bytty devices. These functions are defined in ioLib.h and documented inthe manual entry for tyLib.INCLUDE FILES: ioLib.h, ptyDrv.hSEE ALSO: tyLib,.pG "I/O System"*/#include "vxWorks.h"#include "ioLib.h"#include "iosLib.h"#include "semLib.h"#include "stdlib.h"#include "wdLib.h"#include "selectLib.h"#include "tyLib.h"#include "ptyDrv.h"#include "string.h"#include "errnoLib.h"#include "private/semLibP.h"#include "private/funcBindP.h" IMPORT STATUS tyDevRemove(TY_DEV_ID pTyDev);#define PTY_WRITE_THRESHOLD 20 /* local variables */LOCAL int ptySlaveDrvNum; /* driver number assigned to slave driver */LOCAL int ptyMasterDrvNum; /* driver number assigned to master drv */LOCAL int ptyWrtThreshold = PTY_WRITE_THRESHOLD; /* min bytes free in output buffer *//* forward static functions */static int ptyMasterOpen (PSEUDO_DEV *pPseudoDev, char *name, int mode); static int ptySlaveOpen (PSEUDO_DEV *pPseudoDev, char *name, int mode);static STATUS ptySlaveClose (PSEUDO_DEV *pPseudoDev);static STATUS ptyMasterClose (PSEUDO_DEV *pPseudoDev);static int ptySlaveRead (PSEUDO_DEV *pPseudoDev, char *buffer, int maxbytes);static int ptyMasterRead (PSEUDO_DEV *pPseudoDev, char *buffer, int maxbytes);static int ptySlaveWrite (PSEUDO_DEV *pPseudoDev, char *buffer, int nbytes);static int ptyMasterWrite (PSEUDO_DEV *pPseudoDev, char *buffer, int nbytes);static STATUS ptySlaveIoctl (PSEUDO_DEV *pPseudoDev, int request, int arg);static STATUS ptyMasterIoctl (PSEUDO_DEV *pPseudoDev, int request, int arg);static void ptyMasterStartup (PSEUDO_DEV *pPseudoDev);/********************************************************************************* ptyDrv - initialize the pseudo-terminal driver** This routine initializes the pseudo-terminal driver.* It must be called before any other routine in this module.** RETURNS: OK, or ERROR if the master or slave devices cannot be installed.*/STATUS ptyDrv (void) { static BOOL done; /* FALSE = not done, TRUE = done */ static STATUS status; if (!done) { done = TRUE; ptySlaveDrvNum = iosDrvInstall (ptySlaveOpen, (FUNCPTR) NULL, ptySlaveOpen, ptySlaveClose, ptySlaveRead, ptySlaveWrite, ptySlaveIoctl); ptyMasterDrvNum = iosDrvInstall (ptyMasterOpen, (FUNCPTR) NULL, ptyMasterOpen, ptyMasterClose, ptyMasterRead, ptyMasterWrite, ptyMasterIoctl); status = (ptySlaveDrvNum != ERROR && ptyMasterDrvNum != ERROR) ? OK : ERROR; } return (status); }/********************************************************************************* ptyDevCreate - create a pseudo terminal** This routine creates a master and slave device which can then be opened by* the master and slave processes. The master process simulates the "hardware"* side of the driver, while the slave process is the application program that* normally talks to a tty driver. Data written to the master device can then* be read on the slave device, and vice versa.** RETURNS: OK, or ERROR if memory is insufficient.*/STATUS ptyDevCreate ( char *name, /* name of pseudo terminal */ int rdBufSize, /* size of terminal read buffer */ int wrtBufSize /* size of write buffer */ ) { STATUS status; char nameBuf [MAX_FILENAME_LENGTH]; PSEUDO_DEV *pPseudoDev; if (ptySlaveDrvNum < 1 || ptyMasterDrvNum < 1) { errnoSet (S_ioLib_NO_DRIVER); return (ERROR); } pPseudoDev = (PSEUDO_DEV *) malloc (sizeof (PSEUDO_DEV)); if (pPseudoDev == NULL) return (ERROR); /* initialize device descriptor */ if (tyDevInit ((TY_DEV_ID) pPseudoDev, rdBufSize, wrtBufSize, (FUNCPTR)ptyMasterStartup) != OK) { free ((char *)pPseudoDev); return (ERROR); } /* initialize the select stuff for the master pty fd */ if (_func_selWakeupListInit != NULL) (* _func_selWakeupListInit) (&pPseudoDev->masterSelWakeupList); semBInit (&pPseudoDev->masterReadSyncSem, SEM_Q_PRIORITY, SEM_EMPTY); /* add Slave and Master devices */ strcpy (nameBuf, name); strcat (nameBuf, "S"); status = iosDevAdd (&pPseudoDev->slaveDev, nameBuf, ptySlaveDrvNum); if (status == OK) { strcpy (nameBuf, name); strcat (nameBuf, "M"); status = iosDevAdd ((DEV_HDR *) pPseudoDev, nameBuf, ptyMasterDrvNum); } return (status); }/******************************************************************************** ptyDevRemove - destroy a pseudo terminal** This routine removes an existing master and slave device and releases all* allocated memory. It will close any open files using either device.** RETURNS: OK, or ERROR if terminal not found** INTERNAL* This routine reverses the ptyDevCreate() routine operations.*/STATUS ptyDevRemove ( char * pName /* name of pseudo terminal to remove */ ) { char * pTail = NULL; /* Pointer to tail of device name. */ DEV_HDR * pMasterDev; DEV_HDR * pSlaveDev; char nameBuf [MAX_FILENAME_LENGTH]; PSEUDO_DEV *pPseudoDev; if (ptySlaveDrvNum < 1 || ptyMasterDrvNum < 1) { errnoSet (S_ioLib_NO_DRIVER); return (ERROR); } strcpy (nameBuf, pName); strcat (nameBuf, "M"); pMasterDev = iosDevFind (nameBuf, &pTail); if (pMasterDev == NULL || pTail == nameBuf) /* Device not found? */ return (ERROR); strcpy (nameBuf, pName); strcat (nameBuf, "S"); pSlaveDev = iosDevFind (nameBuf, &pTail); if (pSlaveDev == NULL || pTail == nameBuf) /* Device not found? */ return (ERROR); /* Close any open files and remove the master and slave devices. */ iosDevDelete (pSlaveDev); iosDevDelete (pMasterDev); /* * The master device header is also the header for the ty device and * a pointer to the overall pseudo device structure. Remove those * data structures. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -