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

📄 tclwinpipe.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
/*  * tclWinPipe.c -- * *	This file implements the Windows-specific exec pipeline functions, *	the "pipe" channel driver, and the "pid" Tcl command. * * Copyright (c) 1996-1997 by 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: @(#) tclWinPipe.c 1.49 97/11/06 17:33:03 */#include "tclWinInt.h"#include <dos.h>#include <fcntl.h>#include <io.h>#include <sys/stat.h>/* * The following variable is used to tell whether this module has been * initialized. */static int initialized = 0;/* * The following defines identify the various types of applications that  * run under windows.  There is special case code for the various types. */#define APPL_NONE	0#define APPL_DOS	1#define APPL_WIN3X	2#define APPL_WIN32	3/* * The following constants and structures are used to encapsulate the state * of various types of files used in a pipeline. */#define WIN32S_PIPE 1		/* Win32s emulated pipe. */#define WIN32S_TMPFILE 2	/* Win32s emulated temporary file. */#define WIN_FILE 3		/* Basic Win32 file. *//* * This structure encapsulates the common state associated with all file * types used in a pipeline. */typedef struct WinFile {    int type;			/* One of the file types defined above. */    HANDLE handle;		/* Open file handle. */} WinFile;/* * The following structure is used to keep track of temporary files under * Win32s and delete the disk file when the open handle is closed. * The type field will be WIN32S_TMPFILE. */typedef struct TmpFile {    WinFile file;		/* Common part. */    char name[MAX_PATH];	/* Name of temp file. */} TmpFile;/* * The following structure represents a synchronous pipe under Win32s. * The type field will be WIN32S_PIPE.  The handle field will refer to * an open file when Tcl is reading from the "pipe", otherwise it is * INVALID_HANDLE_VALUE. */typedef struct WinPipe {    WinFile file;		/* Common part. */    struct WinPipe *otherPtr;	/* Pointer to the WinPipe structure that				 * corresponds to the other end of this 				 * pipe. */    char *fileName;		/* The name of the staging file that gets 				 * the data written to this pipe.  Malloc'd.				 * and shared by both ends of the pipe.  Only				 * when both ends are freed will fileName be				 * freed and the file it refers to deleted. */} WinPipe;/* * This list is used to map from pids to process handles. */typedef struct ProcInfo {    HANDLE hProcess;    DWORD dwProcessId;    struct ProcInfo *nextPtr;} ProcInfo;static ProcInfo *procList;/* * State flags used in the PipeInfo structure below. */#define PIPE_PENDING	(1<<0)	/* Message is pending in the queue. */#define PIPE_ASYNC	(1<<1)	/* Channel is non-blocking. *//* * This structure describes per-instance data for a pipe based channel. */typedef struct PipeInfo {    Tcl_Channel channel;	/* Pointer to channel structure. */    int validMask;		/* OR'ed combination of TCL_READABLE,				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates				 * which operations are valid on the file. */    int watchMask;		/* OR'ed combination of TCL_READABLE,				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates				 * which events should be reported. */    int flags;			/* State flags, see above for a list. */    TclFile readFile;		/* Output from pipe. */    TclFile writeFile;		/* Input from pipe. */    TclFile errorFile;		/* Error output from pipe. */    int numPids;		/* Number of processes attached to pipe. */    Tcl_Pid *pidPtr;		/* Pids of attached processes. */    struct PipeInfo *nextPtr;	/* Pointer to next registered pipe. */} PipeInfo;/* * The following pointer refers to the head of the list of pipes * that are being watched for file events. */static PipeInfo *firstPipePtr;/* * The following structure is what is added to the Tcl event queue when * pipe events are generated. */typedef struct PipeEvent {    Tcl_Event header;		/* Information that is standard for				 * all events. */    PipeInfo *infoPtr;		/* Pointer to pipe info structure.  Note				 * that we still have to verify that the				 * pipe exists before dereferencing this				 * pointer. */} PipeEvent;/* * Declarations for functions used only in this file. */static int	ApplicationType(Tcl_Interp *interp, const char *fileName,		    char *fullName);static void	BuildCommandLine(int argc, char **argv, Tcl_DString *linePtr);static void	CopyChannel(HANDLE dst, HANDLE src);static BOOL	HasConsole(void);static TclFile	MakeFile(HANDLE handle);static char *	MakeTempFile(Tcl_DString *namePtr);static int	PipeBlockModeProc(ClientData instanceData, int mode);static void	PipeCheckProc _ANSI_ARGS_((ClientData clientData,		    int flags));static int	PipeCloseProc(ClientData instanceData, Tcl_Interp *interp);static int	PipeEventProc(Tcl_Event *evPtr, int flags);static void	PipeExitHandler(ClientData clientData);static int	PipeGetHandleProc(ClientData instanceData, int direction,		    ClientData *handlePtr);static void	PipeInit(void);static int	PipeInputProc(ClientData instanceData, char *buf, int toRead,		    int *errorCode);static int	PipeOutputProc(ClientData instanceData, char *buf, int toWrite,		    int *errorCode);static void	PipeWatchProc(ClientData instanceData, int mask);static void	PipeSetupProc _ANSI_ARGS_((ClientData clientData,		    int flags));static int	TempFileName(char name[MAX_PATH]);/* * This structure describes the channel type structure for command pipe * based IO. */static Tcl_ChannelType pipeChannelType = {    "pipe",			/* Type name. */    PipeBlockModeProc,		/* Set blocking or non-blocking mode.*/    PipeCloseProc,		/* Close proc. */    PipeInputProc,		/* Input proc. */    PipeOutputProc,		/* Output proc. */    NULL,			/* Seek proc. */    NULL,			/* Set option proc. */    NULL,			/* Get option proc. */    PipeWatchProc,		/* Set up notifier to watch the channel. */    PipeGetHandleProc,		/* Get an OS handle from channel. */};/* *---------------------------------------------------------------------- * * PipeInit -- * *	This function initializes the static variables for this file. * * Results: *	None. * * Side effects: *	Creates a new event source. * *---------------------------------------------------------------------- */static voidPipeInit(){    initialized = 1;    firstPipePtr = NULL;    procList = NULL;    Tcl_CreateEventSource(PipeSetupProc, PipeCheckProc, NULL);    Tcl_CreateExitHandler(PipeExitHandler, NULL);}/* *---------------------------------------------------------------------- * * PipeExitHandler -- * *	This function is called to cleanup the pipe module before *	Tcl is unloaded. * * Results: *	None. * * Side effects: *	Removes the pipe event source. * *---------------------------------------------------------------------- */static voidPipeExitHandler(clientData)    ClientData clientData;	/* Old window proc */{    Tcl_DeleteEventSource(PipeSetupProc, PipeCheckProc, NULL);    initialized = 0;}/* *---------------------------------------------------------------------- * * PipeSetupProc -- * *	This procedure is invoked before Tcl_DoOneEvent blocks waiting *	for an event. * * Results: *	None. * * Side effects: *	Adjusts the block time if needed. * *---------------------------------------------------------------------- */voidPipeSetupProc(data, flags)    ClientData data;		/* Not used. */    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */{    PipeInfo *infoPtr;    Tcl_Time blockTime = { 0, 0 };    if (!(flags & TCL_FILE_EVENTS)) {	return;    }        /*     * Check to see if there is a watched pipe.  If so, poll.     */    for (infoPtr = firstPipePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {	if (infoPtr->watchMask) {	    Tcl_SetMaxBlockTime(&blockTime);	    break;	}    }}/* *---------------------------------------------------------------------- * * PipeCheckProc -- * *	This procedure is called by Tcl_DoOneEvent to check the pipe *	event source for events.  * * Results: *	None. * * Side effects: *	May queue an event. * *---------------------------------------------------------------------- */static voidPipeCheckProc(data, flags)    ClientData data;		/* Not used. */    int flags;			/* Event flags as passed to Tcl_DoOneEvent. */{    PipeInfo *infoPtr;    PipeEvent *evPtr;    if (!(flags & TCL_FILE_EVENTS)) {	return;    }        /*     * Queue events for any watched pipes that don't already have events     * queued.     */    for (infoPtr = firstPipePtr; infoPtr != NULL; infoPtr = infoPtr->nextPtr) {	if (infoPtr->watchMask && !(infoPtr->flags & PIPE_PENDING)) {	    infoPtr->flags |= PIPE_PENDING;	    evPtr = (PipeEvent *) ckalloc(sizeof(PipeEvent));	    evPtr->header.proc = PipeEventProc;	    evPtr->infoPtr = infoPtr;	    Tcl_QueueEvent((Tcl_Event *) evPtr, TCL_QUEUE_TAIL);	}    }}/* *---------------------------------------------------------------------- * * MakeFile -- * *	This function constructs a new TclFile from a given data and *	type value. * * Results: *	Returns a newly allocated WinFile as a TclFile. * * Side effects: *	None. * *---------------------------------------------------------------------- */static TclFileMakeFile(handle)    HANDLE handle;		/* Type-specific data. */{    WinFile *filePtr;    filePtr = (WinFile *) ckalloc(sizeof(WinFile));    filePtr->type = WIN_FILE;    filePtr->handle = handle;    return (TclFile)filePtr;}/* *---------------------------------------------------------------------- * * TclpMakeFile -- * *	Make a TclFile from a channel. * * Results: *	Returns a new TclFile or NULL on failure. * * Side effects: *	None. * *---------------------------------------------------------------------- */TclFileTclpMakeFile(channel, direction)    Tcl_Channel channel;	/* Channel to get file from. */    int direction;		/* Either TCL_READABLE or TCL_WRITABLE. */{    HANDLE handle;    if (Tcl_GetChannelHandle(channel, direction, 	    (ClientData *) &handle) == TCL_OK) {	return MakeFile(handle);    } else {	return (TclFile) NULL;    }}/* *---------------------------------------------------------------------- * * TempFileName -- * *	Gets a temporary file name and deals with the fact that the *	temporary file path provided by Windows may not actually exist *	if the TMP or TEMP environment variables refer to a  *	non-existent directory. * * Results:     *	0 if error, non-zero otherwise.  If non-zero is returned, the *	name buffer will be filled with a name that can be used to  *	construct a temporary file. * * Side effects: *	None. * *---------------------------------------------------------------------- */static intTempFileName(name)    char name[MAX_PATH];	/* Buffer in which name for temporary 				 * file gets stored. */{    if ((GetTempPath(MAX_PATH, name) == 0) ||	    (GetTempFileName(name, "TCL", 0, name) == 0)) {	name[0] = '.';	name[1] = '\0';	if (GetTempFileName(name, "TCL", 0, name) == 0) {	    return 0;	}    }    return 1;}/* *---------------------------------------------------------------------- * * TclpCreateTempFile -- * *	This function opens a unique file with the property that it *	will be deleted when its file handle is closed.  The temporary *	file is created in the system temporary directory. * * Results: *	Returns a valid TclFile, or NULL on failure. * * Side effects: *	Creates a new temporary file. * *---------------------------------------------------------------------- */TclFileTclpCreateTempFile(contents, namePtr)    char *contents;		/* String to write into temp file, or NULL. */    Tcl_DString *namePtr;	/* If non-NULL, pointer to initialized 				 * DString that is filled with the name of 				 * the temp file that was created. */{    char name[MAX_PATH];    HANDLE handle;    if (TempFileName(name) == 0) {	return NULL;    }    handle = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, NULL,	    CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE,	    NULL);    if (handle == INVALID_HANDLE_VALUE) {	goto error;    }    /*     * Write the file out, doing line translations on the way.

⌨️ 快捷键说明

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