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

📄 tclmacchan.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  * tclMacChan.c * *	Channel drivers for Macintosh channels for the *	console fds. * * Copyright (c) 1996-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: @(#) tclMacChan.c 1.43 97/06/20 11:27:48 */#include "tclInt.h"#include "tclPort.h"#include "tclMacInt.h"#include <Aliases.h>#include <Errors.h>#include <Files.h>#include <Gestalt.h>#include <Processes.h>#include <Strings.h>#include <FSpCompat.h>#include <MoreFiles.h>#include <MoreFilesExtras.h>/* * The following variable is used to tell whether this module has been * initialized. */static int initialized = 0;/* * The following are flags returned by GetOpenMode.  They * are or'd together to determine how opening and handling * a file should occur. */#define TCL_RDONLY		(1<<0)#define TCL_WRONLY		(1<<1)#define TCL_RDWR		(1<<2)#define TCL_CREAT		(1<<3)#define TCL_TRUNC		(1<<4)#define TCL_APPEND		(1<<5)#define TCL_ALWAYS_APPEND	(1<<6)#define TCL_EXCL		(1<<7)#define TCL_NOCTTY		(1<<8)#define TCL_NONBLOCK		(1<<9)#define TCL_RW_MODES 		(TCL_RDONLY|TCL_WRONLY|TCL_RDWR)/* * This structure describes per-instance state of a  * macintosh file based channel. */typedef struct FileState {    short fileRef;		/* Macintosh file reference number. */    Tcl_Channel fileChan;	/* Pointer to the channel for this file. */    int watchMask;		/* OR'ed set of flags indicating which events    				 * are being watched. */    int appendMode;		/* Flag to tell if in O_APPEND mode or not. */    int volumeRef;		/* Flag to tell if in O_APPEND mode or not. */    int pending;		/* 1 if message is pending on queue. */    struct FileState *nextPtr;	/* Pointer to next registered file. */} FileState;/* * The following pointer refers to the head of the list of files managed * that are being watched for file events. */static FileState *firstFilePtr;/* * The following structure is what is added to the Tcl event queue when * file events are generated. */typedef struct FileEvent {    Tcl_Event header;		/* Information that is standard for				 * all events. */    FileState *infoPtr;		/* Pointer to file info structure.  Note				 * that we still have to verify that the				 * file exists before dereferencing this				 * pointer. */} FileEvent;/* * Static routines for this file: */static int		CommonGetHandle _ANSI_ARGS_((ClientData instanceData,		            int direction, ClientData *handlePtr));static void		CommonWatch _ANSI_ARGS_((ClientData instanceData,		            int mask));static int		FileBlockMode _ANSI_ARGS_((ClientData instanceData,			    int mode));static void		FileChannelExitHandler _ANSI_ARGS_((		            ClientData clientData));static void		FileCheckProc _ANSI_ARGS_((ClientData clientData,			    int flags));static int		FileClose _ANSI_ARGS_((ClientData instanceData,			    Tcl_Interp *interp));static int		FileEventProc _ANSI_ARGS_((Tcl_Event *evPtr,			    int flags));static void		FileInit _ANSI_ARGS_((void));static int		FileInput _ANSI_ARGS_((ClientData instanceData,			    char *buf, int toRead, int *errorCode));static int		FileOutput _ANSI_ARGS_((ClientData instanceData,			    char *buf, int toWrite, int *errorCode));static int		FileSeek _ANSI_ARGS_((ClientData instanceData,			    long offset, int mode, int *errorCode));static void		FileSetupProc _ANSI_ARGS_((ClientData clientData,			    int flags));static int		GetOpenMode _ANSI_ARGS_((Tcl_Interp *interp,        		    char *string));static Tcl_Channel	OpenFileChannel _ANSI_ARGS_((char *fileName, int mode, 			    int permissions, int *errorCodePtr));static int		StdIOBlockMode _ANSI_ARGS_((ClientData instanceData,			    int mode));static int		StdIOClose _ANSI_ARGS_((ClientData instanceData,			    Tcl_Interp *interp));static int		StdIOInput _ANSI_ARGS_((ClientData instanceData,			    char *buf, int toRead, int *errorCode));static int		StdIOOutput _ANSI_ARGS_((ClientData instanceData,			    char *buf, int toWrite, int *errorCode));static int		StdIOSeek _ANSI_ARGS_((ClientData instanceData,			    long offset, int mode, int *errorCode));static int		StdReady _ANSI_ARGS_((ClientData instanceData,		            int mask));/* * This structure describes the channel type structure for file based IO: */static Tcl_ChannelType consoleChannelType = {    "file",			/* Type name. */    StdIOBlockMode,		/* Set blocking/nonblocking mode.*/    StdIOClose,			/* Close proc. */    StdIOInput,			/* Input proc. */    StdIOOutput,		/* Output proc. */    StdIOSeek,			/* Seek proc. */    NULL,			/* Set option proc. */    NULL,			/* Get option proc. */    CommonWatch,		/* Initialize notifier. */    CommonGetHandle		/* Get OS handles out of channel. */};/* * This variable describes the channel type structure for file based IO. */static Tcl_ChannelType fileChannelType = {    "file",			/* Type name. */    FileBlockMode,		/* Set blocking or                                 * non-blocking mode.*/    FileClose,			/* Close proc. */    FileInput,			/* Input proc. */    FileOutput,			/* Output proc. */    FileSeek,			/* Seek proc. */    NULL,			/* Set option proc. */    NULL,			/* Get option proc. */    CommonWatch,		/* Initialize notifier. */    CommonGetHandle		/* Get OS handles out of channel. */};/* * Hack to allow Mac Tk to override the TclGetStdChannels function. */ typedef void (*TclGetStdChannelsProc) _ANSI_ARGS_((Tcl_Channel *stdinPtr,	Tcl_Channel *stdoutPtr, Tcl_Channel *stderrPtr));	TclGetStdChannelsProc getStdChannelsProc = NULL;/* * Static variables to hold channels for stdin, stdout and stderr. */static Tcl_Channel stdinChannel = NULL;static Tcl_Channel stdoutChannel = NULL;static Tcl_Channel stderrChannel = NULL;/* *---------------------------------------------------------------------- * * FileInit -- * *	This function initializes the file channel event source. * * Results: *	None. * * Side effects: *	Creates a new event source. * *---------------------------------------------------------------------- */static voidFileInit(){    initialized = 1;    firstFilePtr = NULL;    Tcl_CreateEventSource(FileSetupProc, FileCheckProc, NULL);    Tcl_CreateExitHandler(FileChannelExitHandler, NULL);}/* *---------------------------------------------------------------------- * * FileChannelExitHandler -- * *	This function is called to cleanup the channel driver before *	Tcl is unloaded. * * Results: *	None. * * Side effects: *	Destroys the communication window. * *---------------------------------------------------------------------- */static voidFileChannelExitHandler(    ClientData clientData)	/* Old window proc */{    Tcl_DeleteEventSource(FileSetupProc, FileCheckProc, NULL);    initialized = 0;}/* *---------------------------------------------------------------------- * * FileSetupProc -- * *	This procedure is invoked before Tcl_DoOneEvent blocks waiting *	for an event. * * Results: *	None. * * Side effects: *	Adjusts the block time if needed. * *---------------------------------------------------------------------- */voidFileSetupProc(    ClientData data,		/* Not used. */    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */{    FileState *infoPtr;    Tcl_Time blockTime = { 0, 0 };    if (!(flags & TCL_FILE_EVENTS)) {	return;    }        /*     * Check to see if there is a ready file.  If so, poll.     */    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {	if (infoPtr->watchMask) {	    Tcl_SetMaxBlockTime(&blockTime);	    break;	}    }}/* *---------------------------------------------------------------------- * * FileCheckProc -- * *	This procedure is called by Tcl_DoOneEvent to check the file *	event source for events.  * * Results: *	None. * * Side effects: *	May queue an event. * *---------------------------------------------------------------------- */static voidFileCheckProc(    ClientData data,		/* Not used. */    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */{    FileEvent *evPtr;    FileState *infoPtr;    int sentMsg = 0;    Tcl_Time blockTime = { 0, 0 };    if (!(flags & TCL_FILE_EVENTS)) {	return;    }        /*     * Queue events for any ready files that don't already have events     * queued (caused by persistent states that won't generate WinSock     * events).     */    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {	if (infoPtr->watchMask && !infoPtr->pending) {	    infoPtr->pending = 1;	    evPtr = (FileEvent *) ckalloc(sizeof(FileEvent));	    evPtr->header.proc = FileEventProc;	    evPtr->infoPtr = infoPtr;	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);	}    }}/*---------------------------------------------------------------------- * * FileEventProc -- * *	This function is invoked by Tcl_ServiceEvent when a file event *	reaches the front of the event queue.  This procedure invokes *	Tcl_NotifyChannel on the file. * * Results: *	Returns 1 if the event was handled, meaning it should be removed *	from the queue.  Returns 0 if the event was not handled, meaning *	it should stay on the queue.  The only time the event isn't *	handled is if the TCL_FILE_EVENTS flag bit isn't set. * * Side effects: *	Whatever the notifier callback does. * *---------------------------------------------------------------------- */static intFileEventProc(    Tcl_Event *evPtr,		/* Event to service. */    int flags)			/* Flags that indicate what events to				 * handle, such as TCL_FILE_EVENTS. */{    FileEvent *fileEvPtr = (FileEvent *)evPtr;    FileState *infoPtr;    if (!(flags & TCL_FILE_EVENTS)) {	return 0;    }    /*     * Search through the list of watched files for the one whose handle     * matches the event.  We do this rather than simply dereferencing     * the handle in the event so that files can be deleted while the     * event is in the queue.     */    for (infoPtr = firstFilePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {	if (fileEvPtr->infoPtr == infoPtr) {	    infoPtr->pending = 0;	    Tcl_NotifyChannel(infoPtr->fileChan, infoPtr->watchMask);	    break;	}    }    return 1;}/* *---------------------------------------------------------------------- * * StdIOBlockMode -- * *	Set blocking or non-blocking mode on channel. * * Results: *	0 if successful, errno when failed. * * Side effects: *	Sets the device into blocking or non-blocking mode. * *---------------------------------------------------------------------- */static intStdIOBlockMode(    ClientData instanceData,		/* Unused. */    int mode)				/* The mode to set. */{    /*     * Do not allow putting stdin, stdout or stderr into nonblocking mode.     */        if (mode == TCL_MODE_NONBLOCKING) {	return EFAULT;    }        return 0;}/* *---------------------------------------------------------------------- * * StdIOClose -- * *	Closes the IO channel. * * Results: *	0 if successful, the value of errno if failed. * * Side effects: *	Closes the physical channel * *---------------------------------------------------------------------- */static intStdIOClose(    ClientData instanceData,	/* Unused. */    Tcl_Interp *interp)		/* Unused. */{    int fd, errorCode = 0;    /*     * Invalidate the stdio cache if necessary.  Note that we assume that     * the stdio file and channel pointers will become invalid at the same     * time.     */    fd = (int) ((FileState*)instanceData)->fileRef;    if (fd == 0) {	fd = 0;	stdinChannel = NULL;    } else if (fd == 1) {	stdoutChannel = NULL;    } else if (fd == 2) {	stderrChannel = NULL;    } else {	panic("recieved invalid std file");    }    if (close(fd) < 0) {	errorCode = errno;    }

⌨️ 快捷键说明

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