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

📄 tclenv.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  * tclEnv.c -- * *	Tcl support for environment variables, including a setenv *	procedure.  This file contains the generic portion of the *	environment module.  It is primarily responsible for keeping *	the "env" arrays in sync with the system environment variables. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1996 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: @(#) tclEnv.c 1.54 97/10/27 17:47:52 */#include "tclInt.h"#include "tclPort.h"/* * The structure below is used to keep track of all of the interpereters * for which we're managing the "env" array.  It's needed so that they * can all be updated whenever an environment variable is changed * anywhere. */typedef struct EnvInterp {    Tcl_Interp *interp;		/* Interpreter for which we're managing				 * the env array. */    struct EnvInterp *nextPtr;	/* Next in list of all such interpreters,				 * or zero. */} EnvInterp;static EnvInterp *firstInterpPtr = NULL;				/* First in list of all managed interpreters,				 * or NULL if none. */static int cacheSize = 0;	/* Number of env strings in environCache. */static char **environCache = NULL;				/* Array containing all of the environment				 * strings that Tcl has allocated. */#ifndef USE_PUTENVstatic int environSize = 0;	/* Non-zero means that the environ array was				 * malloced and has this many total entries				 * allocated to it (not all may be in use at				 * once).  Zero means that the environment				 * array is in its original static state. */#endif/* * Declarations for local procedures defined in this file: */static char *		EnvTraceProc _ANSI_ARGS_((ClientData clientData,			    Tcl_Interp *interp, char *name1, char *name2,			    int flags));static int		FindVariable _ANSI_ARGS_((CONST char *name,			    int *lengthPtr));static void		ReplaceString _ANSI_ARGS_((CONST char *oldStr,			    char *newStr));void			TclSetEnv _ANSI_ARGS_((CONST char *name,			    CONST char *value));void			TclUnsetEnv _ANSI_ARGS_((CONST char *name));/* *---------------------------------------------------------------------- * * TclSetupEnv -- * *	This procedure is invoked for an interpreter to make environment *	variables accessible from that interpreter via the "env" *	associative array. * * Results: *	None. * * Side effects: *	The interpreter is added to a list of interpreters managed *	by us, so that its view of envariables can be kept consistent *	with the view in other interpreters.  If this is the first *	call to Tcl_SetupEnv, then additional initialization happens, *	such as copying the environment to dynamically-allocated space *	for ease of management. * *---------------------------------------------------------------------- */voidTclSetupEnv(interp)    Tcl_Interp *interp;		/* Interpreter whose "env" array is to be				 * managed. */{    EnvInterp *eiPtr;    char *p, *p2;    Tcl_DString ds;    int i, sz;#ifdef MAC_TCL    if (environ == NULL) {	environSize = TclMacCreateEnv();    }#endif    /*     * Next, initialize the DString we are going to use for copying     * the names of the environment variables.     */    Tcl_DStringInit(&ds);        /*     * Next, add the interpreter to the list of those that we manage.     */    eiPtr = (EnvInterp *) ckalloc(sizeof(EnvInterp));    eiPtr->interp = interp;    eiPtr->nextPtr = firstInterpPtr;    firstInterpPtr = eiPtr;    /*     * Store the environment variable values into the interpreter's     * "env" array, and arrange for us to be notified on future     * writes and unsets to that array.     */    (void) Tcl_UnsetVar2(interp, "env", (char *) NULL, TCL_GLOBAL_ONLY);    for (i = 0; ; i++) {	p = environ[i];	if (p == NULL) {	    break;	}	for (p2 = p; *p2 != '='; p2++) {	    if (*p2 == 0) {		/*		 * This condition doesn't seem like it should ever happen,		 * but it does seem to happen occasionally under some		 * versions of Solaris; ignore the entry.		 */		goto nextEntry;	    }	}        sz = p2 - p;        Tcl_DStringSetLength(&ds, 0);        Tcl_DStringAppend(&ds, p, sz);	(void) Tcl_SetVar2(interp, "env", Tcl_DStringValue(&ds),                p2+1, TCL_GLOBAL_ONLY);	nextEntry:	continue;    }    Tcl_TraceVar2(interp, "env", (char *) NULL,	    TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS,	    EnvTraceProc, (ClientData) NULL);    /*     * Finally clean up the DString.     */    Tcl_DStringFree(&ds);}/* *---------------------------------------------------------------------- * * TclSetEnv -- * *	Set an environment variable, replacing an existing value *	or creating a new variable if there doesn't exist a variable *	by the given name.  This procedure is intended to be a *	stand-in for the  UNIX "setenv" procedure so that applications *	using that procedure will interface properly to Tcl.  To make *	it a stand-in, the Makefile must define "TclSetEnv" to "setenv". * * Results: *	None. * * Side effects: *	The environ array gets updated, as do all of the interpreters *	that we manage. * *---------------------------------------------------------------------- */voidTclSetEnv(name, value)    CONST char *name;		/* Name of variable whose value is to be				 * set. */    CONST char *value;		/* New value for variable. */{    int index, length, nameLength;    char *p, *oldValue;    EnvInterp *eiPtr;#ifdef MAC_TCL    if (environ == NULL) {	environSize = TclMacCreateEnv();    }#endif    /*     * Figure out where the entry is going to go.  If the name doesn't     * already exist, enlarge the array if necessary to make room.  If     * the name exists, free its old entry.     */    index = FindVariable(name, &length);    if (index == -1) {#ifndef USE_PUTENV	if ((length+2) > environSize) {	    char **newEnviron;	    newEnviron = (char **) ckalloc((unsigned)		    ((length+5) * sizeof(char *)));	    memcpy((VOID *) newEnviron, (VOID *) environ,		    length*sizeof(char *));	    if (environSize != 0) {		ckfree((char *) environ);	    }	    environ = newEnviron;	    environSize = length+5;	}	index = length;	environ[index+1] = NULL;#endif	oldValue = NULL;	nameLength = strlen(name);    } else {	/*	 * Compare the new value to the existing value.  If they're	 * the same then quit immediately (e.g. don't rewrite the	 * value or propagate it to other interpreters).  Otherwise,	 * when there are N interpreters there will be N! propagations	 * of the same value among the interpreters.	 */	if (strcmp(value, environ[index]+length+1) == 0) {	    return;	}	oldValue = environ[index];	nameLength = length;    }	    /*     * Create a new entry.     */    p = (char *) ckalloc((unsigned) (nameLength + strlen(value) + 2));    strcpy(p, name);    p[nameLength] = '=';    strcpy(p+nameLength+1, value);    /*     * Update the system environment.     */#ifdef USE_PUTENV    putenv(p);#else    environ[index] = p;#endif    /*     * Replace the old value with the new value in the cache.     */    ReplaceString(oldValue, p);    /*     * Update all of the interpreters.     */    for (eiPtr= firstInterpPtr; eiPtr != NULL; eiPtr = eiPtr->nextPtr) {	(void) Tcl_SetVar2(eiPtr->interp, "env", (char *) name,		(char *) value, TCL_GLOBAL_ONLY);    }}/* *---------------------------------------------------------------------- * * Tcl_PutEnv -- * *	Set an environment variable.  Similar to setenv except that *	the information is passed in a single string of the form *	NAME=value, rather than as separate name strings.  This procedure *	is intended to be a stand-in for the  UNIX "putenv" procedure *	so that applications using that procedure will interface *	properly to Tcl.  To make it a stand-in, the Makefile will *	define "Tcl_PutEnv" to "putenv". * * Results: *	None. * * Side effects: *	The environ array gets updated, as do all of the interpreters *	that we manage. * *---------------------------------------------------------------------- */intTcl_PutEnv(string)    CONST char *string;		/* Info about environment variable in the				 * form NAME=value. */{    int nameLength;    char *name, *value;    if (string == NULL) {	return 0;    }    /*     * Separate the string into name and value parts, then call     * TclSetEnv to do all of the real work.     */    value = strchr(string, '=');    if (value == NULL) {	return 0;    }    nameLength = value - string;    if (nameLength == 0) {	return 0;    }    name = (char *) ckalloc((unsigned) nameLength+1);    memcpy((VOID *) name, (VOID *) string, (size_t) nameLength);    name[nameLength] = 0;    TclSetEnv(name, value+1);    ckfree(name);    return 0;}/* *---------------------------------------------------------------------- * * TclUnsetEnv -- * *	Remove an environment variable, updating the "env" arrays *	in all interpreters managed by us.  This function is intended *	to replace the UNIX "unsetenv" function (but to do this the *	Makefile must be modified to redefine "TclUnsetEnv" to *	"unsetenv". * * Results: *	None. * * Side effects:

⌨️ 快捷键说明

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