From: Stephen D. <sd...@us...> - 2005-10-22 12:50:51
|
Update of /cvsroot/naviserver/naviserver/nsd In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5911/nsd Modified Files: tclcmds.c tclenv.c Log Message: * nsd/tclcmds.c: * nsd/tclenv.c: * tests/ns_env.test: Untabify and reformat code, convert to Tcl objects. Fix bugs with -nocomplain switch and unset command. (Bug# 1333280) Index: tclcmds.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclcmds.c,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** tclcmds.c 21 Oct 2005 10:07:26 -0000 1.23 --- tclcmds.c 22 Oct 2005 12:50:39 -0000 1.24 *************** *** 79,82 **** --- 79,83 ---- NsTclDeleteCookieObjCmd, NsTclDummyObjCmd, + NsTclEnvObjCmd, NsTclFTruncateObjCmd, NsTclGetAddrObjCmd, *************** *** 198,202 **** NsTclConfigSectionsCmd, NsTclEncodingForCharsetCmd, - NsTclEnvCmd, NsTclHrefsCmd, NsTclLibraryCmd, --- 199,202 ---- *************** *** 229,233 **** static Cmd basicCmds[] = { ! {"env", NsTclEnvCmd, NULL}, {"keyldel", TclX_KeyldelObjCmd, NULL}, {"keylget", TclX_KeylgetObjCmd, NULL}, --- 229,233 ---- static Cmd basicCmds[] = { ! {"env", NULL, NsTclEnvObjCmd}, {"keyldel", TclX_KeyldelObjCmd, NULL}, {"keylget", TclX_KeylgetObjCmd, NULL}, *************** *** 258,262 **** {"ns_crypt", NULL, NsTclCryptObjCmd}, {"ns_encodingforcharset", NsTclEncodingForCharsetCmd, NULL}, ! {"ns_env", NsTclEnvCmd, NULL}, {"ns_event", NULL, NsTclCondObjCmd}, {"ns_ftruncate", NULL, NsTclFTruncateObjCmd}, --- 258,262 ---- {"ns_crypt", NULL, NsTclCryptObjCmd}, {"ns_encodingforcharset", NsTclEncodingForCharsetCmd, NULL}, ! {"ns_env", NULL, NsTclEnvObjCmd}, {"ns_event", NULL, NsTclCondObjCmd}, {"ns_ftruncate", NULL, NsTclFTruncateObjCmd}, Index: tclenv.c =================================================================== RCS file: /cvsroot/naviserver/naviserver/nsd/tclenv.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** tclenv.c 10 Jun 2005 17:58:40 -0000 1.2 --- tclenv.c 22 Oct 2005 12:50:39 -0000 1.3 *************** *** 32,36 **** * tclenv.c -- * ! * Implement the "ns_env" command. */ --- 32,36 ---- * tclenv.c -- * ! * Implement the "ns_env" command. */ *************** *** 40,45 **** - static int PutEnv(Tcl_Interp *interp, char *name, char *value); - static Ns_Mutex lock; #ifdef HAVE__NSGETENVIRON #include <crt_externs.h> --- 40,43 ---- *************** *** 48,51 **** --- 46,91 ---- #endif + /* + * Local functions defined in this file. + */ + + static int PutEnv(Tcl_Interp *interp, char *name, char *value); + + /* + * Loca variables defined in this file. + */ + + static Ns_Mutex lock; + + + /* + *---------------------------------------------------------------------- + * + * Ns_GetEnviron -- + * + * Return the environment vector. + * + * Results: + * Pointer to environment. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + char ** + Ns_GetEnviron(void) + { + char **envp; + + #ifdef HAVE__NSGETENVIRON + envp = *_NSGetEnviron(); + #else + envp = environ; + #endif + return envp; + } + /* *************** *** 54,65 **** * Ns_CopyEnviron -- * ! * Copy the environment to the given dstring along with ! * an argv vector. * * Results: ! * Pointer to dsPtr->string. * * Side effects: ! * None. * *---------------------------------------------------------------------- --- 94,105 ---- * Ns_CopyEnviron -- * ! * Copy the environment to the given dstring along with ! * an argv vector. * * Results: ! * Pointer to dsPtr->string. * * Side effects: ! * None. * *---------------------------------------------------------------------- *************** *** 75,81 **** envp = Ns_GetEnviron(); for (i = 0; (s = envp[i]) != NULL; ++i) { ! Ns_DStringAppendArg(dsPtr, s); } Ns_MutexUnlock(&lock); return Ns_DStringAppendArgv(dsPtr); } --- 115,122 ---- envp = Ns_GetEnviron(); for (i = 0; (s = envp[i]) != NULL; ++i) { ! Ns_DStringAppendArg(dsPtr, s); } Ns_MutexUnlock(&lock); + return Ns_DStringAppendArgv(dsPtr); } *************** *** 87,101 **** * NsTclEnvCmd -- * ! * Implement the "env" command. Read the code to see what it does. ! * NOTE: The getenv() and putenv() routines are assumed MT safe ! * and there's no attempt to avoid the race condition between ! * finding a variable and using it. The reason is it's assumed ! * the environment would only be modified, if ever, at startup. * * Results: ! * A standard Tcl result. * * Side effects: ! * Environment variables may be updated. * *---------------------------------------------------------------------- --- 128,141 ---- * NsTclEnvCmd -- * ! * Implements the ns_env command. No attempt is made to avoid the ! * race condition between finding a variable and using it as it is ! * assumed the environment would only be modified, if ever, at ! * startup. * * Results: ! * Tcl result. * * Side effects: ! * Environment variables may be updated. * *---------------------------------------------------------------------- *************** *** 103,195 **** int ! NsTclEnvCmd(ClientData dummy, Tcl_Interp *interp, int argc, char **argv) { ! char *name, *value, **envp; ! int status, i; ! Tcl_DString ds; ! if (argc < 2) { ! Tcl_AppendResult(interp, "wrong # args: should be \"", ! argv[0], " command ?args ...?\"", NULL); ! return TCL_ERROR; } ! status = TCL_OK; Ns_MutexLock(&lock); - if (STREQ(argv[1], "names")) { - if (argc != 2) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " names\"", NULL); - status = TCL_ERROR; - } else { - Tcl_DStringInit(&ds); - envp = Ns_GetEnviron(); - for (i = 0; envp[i] != NULL; ++i) { - name = envp[i]; - value = strchr(name, '='); - Tcl_DStringAppend(&ds, name, value ? value - name : -1); - Tcl_AppendElement(interp, ds.string); - Tcl_DStringTrunc(&ds, 0); - } - Tcl_DStringFree(&ds); - } - - } else if (STREQ(argv[1], "exists")) { - if (argc != 3) { - Tcl_AppendResult(interp, "wrong # args: should be \"", - argv[0], " exists name\"", NULL); - status = TCL_ERROR; - } else { - Tcl_SetResult(interp, getenv(argv[2]) ? "1" : "0", TCL_STATIC); - } ! } else if (STREQ(argv[1], "get")) { ! if ((argc != 3 && argc != 4) || ! (argc == 4 && !STREQ(argv[2], "-nocomplain"))) { ! badargs: ! Tcl_AppendResult(interp, "wrong # args: should be \"", ! argv[0], " ", argv[1], " ?-nocomplain? name\"", NULL); ! status = TCL_ERROR; ! } ! name = argv[argc-1]; ! value = getenv(name); ! if (value != NULL) { ! Tcl_SetResult(interp, value, TCL_VOLATILE); ! } else if (argc == 4) { ! Tcl_AppendResult(interp, "no such environment variable: ", ! argv[argc-1], NULL); ! status = TCL_ERROR; ! } ! } else if (STREQ(argv[1], "set")) { ! if (argc != 4) { ! Tcl_AppendResult(interp, "wrong # args: should be \"", ! argv[0], " set name value\"", NULL); ! status = TCL_ERROR; ! } else { ! status = PutEnv(interp, argv[2], argv[3]); ! } ! } else if (STREQ(argv[1], "unset")) { ! if ((argc != 3 && argc != 4) || ! (argc == 4 && !STREQ(argv[2], "-nocomplain"))) { ! goto badargs; ! } ! name = argv[argc-1]; ! if (argc == 3 && getenv(name) == NULL) { ! Tcl_AppendResult(interp, "no such environment variable: ", name, ! NULL); ! status = TCL_ERROR; ! } else { ! status = PutEnv(interp, name, ""); ! } ! } else { ! Tcl_AppendResult(interp, "unknown command \"", ! argv[1], "\": should be exists, names, get, set, or unset", NULL); ! status = TCL_ERROR; } Ns_MutexUnlock(&lock); return status; } --- 143,227 ---- int ! NsTclEnvObjCmd(ClientData arg, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { ! char *name, *value, **envp; ! int status, i, opt; ! Tcl_Obj *result; ! static CONST char *opts[] = { ! "exists", "names", "get", "set", "unset", NULL ! }; ! enum { ! IExistsIdx, INamesIdx, IGetIdx, ISetIdx, IUnsetIdx ! }; ! ! if (objc < 2) { ! Tcl_WrongNumArgs(interp, 1, objv, "command ?args ...?"); ! return TCL_ERROR; ! } ! if (Tcl_GetIndexFromObj(interp, objv[1], opts, "command", 0, ! &opt) != TCL_OK) { ! return TCL_ERROR; } ! status = TCL_ERROR; Ns_MutexLock(&lock); ! switch (opt) { ! case IExistsIdx: ! if (objc != 3) { ! Tcl_WrongNumArgs(interp, 2, objv, "name"); ! goto done; ! } ! Tcl_SetBooleanObj(Tcl_GetObjResult(interp), getenv(Tcl_GetString(objv[2])) ? 1 : 0); ! break; ! case INamesIdx: ! envp = Ns_GetEnviron(); ! result = Tcl_GetObjResult(interp); ! for (i = 0; envp[i] != NULL; ++i) { ! name = envp[i]; ! value = strchr(name, '='); ! Tcl_ListObjAppendElement(interp, result, ! Tcl_NewStringObj(name, value ? value - name : -1)); ! } ! break; ! case ISetIdx: ! if (objc != 4) { ! Tcl_WrongNumArgs(interp, 2, objv, "name value"); ! goto done; ! } ! if (PutEnv(interp, Tcl_GetString(objv[2]), Tcl_GetString(objv[3])) ! != NS_OK) { ! goto done; ! } ! break; ! case IGetIdx: ! case IUnsetIdx: ! if ((objc != 3 && objc != 4) ! || (objc == 4 && !STREQ(Tcl_GetString(objv[2]), "-nocomplain"))) { ! Tcl_WrongNumArgs(interp, 2, objv, "?-nocomplain? name"); ! goto done; ! } ! name = Tcl_GetString(objv[2]); ! value = getenv(name); ! if (value == NULL && objc != 4) { ! Tcl_SetResult(interp, "no such environment variable", TCL_STATIC); ! goto done; ! } ! if (opt == IUnsetIdx && PutEnv(interp, name, NULL) != NS_OK) { ! goto done; ! } else { ! Tcl_SetResult(interp, value, TCL_VOLATILE); ! } ! break; } + status = TCL_OK; + done: Ns_MutexUnlock(&lock); + return status; } *************** *** 201,211 **** * PutEnv -- * ! * NsTclEnvCmd helper routine to update an environment variable. * * Results: ! * TCL_OK or TCL_ERROR. * * Side effects: ! * Environment variable is set. * *---------------------------------------------------------------------- --- 233,243 ---- * PutEnv -- * ! * NsTclEnvCmd helper routine to update an environment variable. * * Results: ! * TCL_OK or TCL_ERROR. * * Side effects: ! * Environment variable is set. * *---------------------------------------------------------------------- *************** *** 215,273 **** PutEnv(Tcl_Interp *interp, char *name, char *value) { ! char *s; ! size_t len; len = strlen(name); if (value != NULL) { ! len += strlen(value) + 1; } /* NB: Use malloc() directly as putenv() would expect. */ s = malloc(len + 1); if (s == NULL) { ! Tcl_SetResult(interp, ! "could not allocate memory for new env entry", TCL_STATIC); ! return TCL_ERROR; } strcpy(s, name); if (value != NULL) { ! strcat(s, "="); ! strcat(s, value); } if (putenv(s) != 0) { ! Tcl_AppendResult(interp, "could not put environment entry \"", ! s, "\": ", Tcl_PosixError(interp), NULL); ! free(s); ! return TCL_ERROR; } - return TCL_OK; - } - - - /* - *---------------------------------------------------------------------- - * - * Ns_GetEnviron -- - * - * Return the environment vector. - * - * Results: - * Pointer to environment. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ ! char ** ! Ns_GetEnviron(void) ! { ! char **envp; ! ! #ifdef HAVE__NSGETENVIRON ! envp = *_NSGetEnviron(); ! #else ! envp = environ; ! #endif ! return envp; } --- 247,276 ---- PutEnv(Tcl_Interp *interp, char *name, char *value) { ! char *s; ! size_t len; len = strlen(name); if (value != NULL) { ! len += strlen(value) + 1; } /* NB: Use malloc() directly as putenv() would expect. */ s = malloc(len + 1); if (s == NULL) { ! Tcl_SetResult(interp, ! "could not allocate memory for new env entry", TCL_STATIC); ! return TCL_ERROR; } strcpy(s, name); if (value != NULL) { ! strcat(s, "="); ! strcat(s, value); } if (putenv(s) != 0) { ! Tcl_AppendResult(interp, "could not put environment entry \"", ! s, "\": ", Tcl_PosixError(interp), NULL); ! free(s); ! return TCL_ERROR; } ! return TCL_OK; } |