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

📄 tclunixchan.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * tclUnixChan.c * *	Common channel driver for Unix channels based on files, command *	pipes and TCP sockets. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclUnixChan.c 1.207 97/11/04 14:45:29 */#include	"tclInt.h"	/* Internal definitions for Tcl. */#include	"tclPort.h"	/* Portability features for Tcl. *//* * sys/ioctl.h has already been included by tclPort.h.  Including termios.h * or termio.h causes a bunch of warning messages because some duplicate * (but not contradictory) #defines exist in termios.h and/or termio.h */#undef NL0#undef NL1#undef CR0#undef CR1#undef CR2#undef CR3#undef TAB0#undef TAB1#undef TAB2#undef XTABS#undef BS0#undef BS1#undef FF0#undef FF1#undef ECHO#undef NOFLSH#undef TOSTOP#undef FLUSHO#undef PENDIN#ifdef USE_TERMIOS#   include <termios.h>#else	/* !USE_TERMIOS */#ifdef USE_TERMIO#   include <termio.h>#else	/* !USE_TERMIO */#ifdef USE_SGTTY#   include <sgtty.h>#endif	/* USE_SGTTY */#endif	/* !USE_TERMIO */#endif	/* !USE_TERMIOS *//* * The following structure is used to set or get the serial port * attributes in a platform-independant manner. */ typedef struct TtyAttrs {    int baud;    int parity;    int data;    int stop;} TtyAttrs;/* * This structure describes per-instance state of a file based channel. */typedef struct FileState {    Tcl_Channel channel;	/* Channel associated with this file. */    int fd;			/* File handle. */    int validMask;		/* OR'ed combination of TCL_READABLE,				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates				 * which operations are valid on the file. */    struct FileState *nextPtr;	/* Pointer to next file in list of all				 * file channels. */} FileState;/* * List of all file channels currently open. */static FileState *firstFilePtr = NULL;/* * This structure describes per-instance state of a tcp based channel. */typedef struct TcpState {    Tcl_Channel channel;	/* Channel associated with this file. */    int fd;			/* The socket itself. */    int flags;			/* ORed combination of the bitfields				 * defined below. */    Tcl_TcpAcceptProc *acceptProc;				/* Proc to call on accept. */    ClientData acceptProcData;	/* The data for the accept proc. */} TcpState;/* * These bits may be ORed together into the "flags" field of a TcpState * structure. */#define TCP_ASYNC_SOCKET	(1<<0)	/* Asynchronous socket. */#define TCP_ASYNC_CONNECT	(1<<1)	/* Async connect in progress. *//* * The following defines the maximum length of the listen queue. This is * the number of outstanding yet-to-be-serviced requests for a connection * on a server socket, more than this number of outstanding requests and * the connection request will fail. */#ifndef	SOMAXCONN#define SOMAXCONN	100#endif#if	(SOMAXCONN < 100)#undef	SOMAXCONN#define	SOMAXCONN	100#endif/* * The following defines how much buffer space the kernel should maintain * for a socket. */#define SOCKET_BUFSIZE	4096/* * Static routines for this file: */static TcpState *	CreateSocket _ANSI_ARGS_((Tcl_Interp *interp,			    int port, char *host, int server,			    char *myaddr, int myport, int async));static int		CreateSocketAddress _ANSI_ARGS_(			    (struct sockaddr_in *sockaddrPtr,			    char *host, int port));static int		FileBlockModeProc _ANSI_ARGS_((    			    ClientData instanceData, int mode));static int		FileCloseProc _ANSI_ARGS_((ClientData instanceData,			    Tcl_Interp *interp));static int		FileGetHandleProc _ANSI_ARGS_((ClientData instanceData,		            int direction, ClientData *handlePtr));static int		FileInputProc _ANSI_ARGS_((ClientData instanceData,		            char *buf, int toRead, int *errorCode));static int		FileOutputProc _ANSI_ARGS_((			    ClientData instanceData, char *buf, int toWrite,                            int *errorCode));static int		FileSeekProc _ANSI_ARGS_((ClientData instanceData,			    long offset, int mode, int *errorCode));static void		FileWatchProc _ANSI_ARGS_((ClientData instanceData,		            int mask));static void		TcpAccept _ANSI_ARGS_((ClientData data, int mask));static int		TcpBlockModeProc _ANSI_ARGS_((ClientData data,        		    int mode));static int		TcpCloseProc _ANSI_ARGS_((ClientData instanceData,			    Tcl_Interp *interp));static int		TcpGetHandleProc _ANSI_ARGS_((ClientData instanceData,		            int direction, ClientData *handlePtr));static int		TcpGetOptionProc _ANSI_ARGS_((ClientData instanceData,			    Tcl_Interp *interp, char *optionName,			    Tcl_DString *dsPtr));static int		TcpInputProc _ANSI_ARGS_((ClientData instanceData,		            char *buf, int toRead,  int *errorCode));static int		TcpOutputProc _ANSI_ARGS_((ClientData instanceData,		            char *buf, int toWrite, int *errorCode));static void		TcpWatchProc _ANSI_ARGS_((ClientData instanceData,		            int mask));static int		TtyParseMode _ANSI_ARGS_((Tcl_Interp *interp,			    CONST char *mode, int *speedPtr, int *parityPtr,			    int *dataPtr, int *stopPtr));static void		TtyGetAttributes _ANSI_ARGS_((int fd,			    TtyAttrs *ttyPtr));static int		TtyGetOptionProc _ANSI_ARGS_((ClientData instanceData,			    Tcl_Interp *interp, char *optionName,			    Tcl_DString *dsPtr));static void		TtyInit _ANSI_ARGS_((int fd));static void		TtySetAttributes _ANSI_ARGS_((int fd,			    TtyAttrs *ttyPtr));static int		TtySetOptionProc _ANSI_ARGS_((ClientData instanceData,			    Tcl_Interp *interp, char *optionName, 			    char *value));static int		WaitForConnect _ANSI_ARGS_((TcpState *statePtr,		            int *errorCodePtr));/* * This structure describes the channel type structure for file based IO: */static Tcl_ChannelType fileChannelType = {    "file",				/* Type name. */    FileBlockModeProc,			/* Set blocking/nonblocking mode.*/    FileCloseProc,			/* Close proc. */    FileInputProc,			/* Input proc. */    FileOutputProc,			/* Output proc. */    FileSeekProc,			/* Seek proc. */    NULL,				/* Set option proc. */    NULL,				/* Get option proc. */    FileWatchProc,			/* Initialize notifier. */    FileGetHandleProc,			/* Get OS handles out of channel. */};/* * This structure describes the channel type structure for serial IO. * Note that this type is a subclass of the "file" type. */static Tcl_ChannelType ttyChannelType = {    "tty",				/* Type name. */    FileBlockModeProc,			/* Set blocking/nonblocking mode.*/    FileCloseProc,			/* Close proc. */    FileInputProc,			/* Input proc. */    FileOutputProc,			/* Output proc. */    NULL,				/* Seek proc. */    TtySetOptionProc,			/* Set option proc. */    TtyGetOptionProc,			/* Get option proc. */    FileWatchProc,			/* Initialize notifier. */    FileGetHandleProc,			/* Get OS handles out of channel. */};/* * This structure describes the channel type structure for TCP socket * based IO: */static Tcl_ChannelType tcpChannelType = {    "tcp",				/* Type name. */    TcpBlockModeProc,			/* Set blocking/nonblocking mode.*/    TcpCloseProc,			/* Close proc. */    TcpInputProc,			/* Input proc. */    TcpOutputProc,			/* Output proc. */    NULL,				/* Seek proc. */    NULL,				/* Set option proc. */    TcpGetOptionProc,			/* Get option proc. */    TcpWatchProc,			/* Initialize notifier. */    TcpGetHandleProc,			/* Get OS handles out of channel. */};/* *---------------------------------------------------------------------- * * FileBlockModeProc -- * *	Helper procedure to set blocking and nonblocking modes on a *	file based channel. Invoked by generic IO level code. * * Results: *	0 if successful, errno when failed. * * Side effects: *	Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */	/* ARGSUSED */static intFileBlockModeProc(instanceData, mode)    ClientData instanceData;		/* File state. */    int mode;				/* The mode to set. Can be one of                                         * TCL_MODE_BLOCKING or                                         * TCL_MODE_NONBLOCKING. */{    FileState *fsPtr = (FileState *) instanceData;    int curStatus;#ifndef USE_FIONBIO    curStatus = fcntl(fsPtr->fd, F_GETFL);    if (mode == TCL_MODE_BLOCKING) {	curStatus &= (~(O_NONBLOCK));    } else {	curStatus |= O_NONBLOCK;    }    if (fcntl(fsPtr->fd, F_SETFL, curStatus) < 0) {	return errno;    }    curStatus = fcntl(fsPtr->fd, F_GETFL);#else    if (mode == TCL_MODE_BLOCKING) {	curStatus = 0;    } else {	curStatus = 1;    }    if (ioctl(fsPtr->fd, (int) FIONBIO, &curStatus) < 0) {	return errno;    }#endif    return 0;}/* *---------------------------------------------------------------------- * * FileInputProc -- * *	This procedure is invoked from the generic IO level to read *	input from a file based channel. * * Results: *	The number of bytes read is returned or -1 on error. An output *	argument contains a POSIX error code if an error occurs, or zero. * * Side effects: *	Reads input from the input device of the channel. * *---------------------------------------------------------------------- */static intFileInputProc(instanceData, buf, toRead, errorCodePtr)    ClientData instanceData;		/* File state. */    char *buf;				/* Where to store data read. */    int toRead;				/* How much space is available                                         * in the buffer? */    int *errorCodePtr;			/* Where to store error code. */{    FileState *fsPtr = (FileState *) instanceData;    int bytesRead;			/* How many bytes were actually                                         * read from the input device? */    *errorCodePtr = 0;        /*     * Assume there is always enough input available. This will block     * appropriately, and read will unblock as soon as a short read is     * possible, if the channel is in blocking mode. If the channel is     * nonblocking, the read will never block.     */    bytesRead = read(fsPtr->fd, buf, (size_t) toRead);    if (bytesRead > -1) {        return bytesRead;    }    *errorCodePtr = errno;    return -1;}/* *---------------------------------------------------------------------- * * FileOutputProc-- * *	This procedure is invoked from the generic IO level to write *	output to a file channel. * * Results: *	The number of bytes written is returned or -1 on error. An *	output argument	contains a POSIX error code if an error occurred, *	or zero. * * Side effects: *	Writes output on the output device of the channel. * *---------------------------------------------------------------------- */static intFileOutputProc(instanceData, buf, toWrite, errorCodePtr)    ClientData instanceData;		/* File state. */    char *buf;				/* The data buffer. */    int toWrite;			/* How many bytes to write? */    int *errorCodePtr;			/* Where to store error code. */{    FileState *fsPtr = (FileState *) instanceData;    int written;    *errorCodePtr = 0;    written = write(fsPtr->fd, buf, (size_t) toWrite);    if (written > -1) {        return written;    }    *errorCodePtr = errno;    return -1;}/* *---------------------------------------------------------------------- * * FileCloseProc -- * *	This procedure is called from the generic IO level to perform *	channel-type-specific cleanup when a file based channel is closed. * * Results: *	0 if successful, errno if failed. * * Side effects: *	Closes the device of the channel. * *---------------------------------------------------------------------- */static intFileCloseProc(instanceData, interp)    ClientData instanceData;	/* File state. */    Tcl_Interp *interp;		/* For error reporting - unused. */{    FileState *fsPtr = (FileState *) instanceData;    FileState **nextPtrPtr;    int errorCode = 0;    Tcl_DeleteFileHandler(fsPtr->fd);    if (!TclInExit()	    || ((fsPtr->fd != 0) && (fsPtr->fd != 1) && (fsPtr->fd != 2))) {	if (close(fsPtr->fd) < 0) {	    errorCode = errno;	}    }    for (nextPtrPtr = &firstFilePtr; (*nextPtrPtr) != NULL;	 nextPtrPtr = &((*nextPtrPtr)->nextPtr)) {	if ((*nextPtrPtr) == fsPtr) {	    (*nextPtrPtr) = fsPtr->nextPtr;	    break;	}    }    ckfree((char *) fsPtr);    return errorCode;}/* *---------------------------------------------------------------------- * * FileSeekProc -- * *	This procedure is called by the generic IO level to move the *	access point in a file based channel. * * Results: *	-1 if failed, the new position if successful. An output *	argument contains the POSIX error code if an error occurred, *	or zero. * * Side effects: *	Moves the location at which the channel will be accessed in *	future operations. * *---------------------------------------------------------------------- */static intFileSeekProc(instanceData, offset, mode, errorCodePtr)    ClientData instanceData;			/* File state. */    long offset;				/* Offset to seek to. */    int mode;					/* Relative to where                                                 * should we seek? Can be                                                 * one of SEEK_START,                                                 * SEEK_SET or SEEK_END. */    int *errorCodePtr;				/* To store error code. */{    FileState *fsPtr = (FileState *) instanceData;    int newLoc;    newLoc = lseek(fsPtr->fd, offset, mode);    *errorCodePtr = (newLoc == -1) ? errno : 0;    return newLoc;}/* *---------------------------------------------------------------------- * * FileWatchProc -- * *	Initialize the notifier to watch the fd from this channel. * * Results: *	None. *

⌨️ 快捷键说明

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