diff options
Diffstat (limited to 'unix/tclUnixTest.c')
-rw-r--r-- | unix/tclUnixTest.c | 498 |
1 files changed, 288 insertions, 210 deletions
diff --git a/unix/tclUnixTest.c b/unix/tclUnixTest.c index d556a2b..4b0f369 100644 --- a/unix/tclUnixTest.c +++ b/unix/tclUnixTest.c @@ -1,4 +1,4 @@ -/* +/* * tclUnixTest.c -- * * Contains platform specific test commands for the Unix platform. @@ -6,31 +6,31 @@ * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright (c) 1998 by Scriptics Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. - * - * RCS: @(#) $Id: tclUnixTest.c,v 1.11 1999/10/13 00:32:50 hobbs Exp $ + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ +#ifndef USE_TCL_STUBS +# define USE_TCL_STUBS +#endif #include "tclInt.h" -#include "tclPort.h" /* - * The headers are needed for the testalarm command that verifies the - * use of SA_RESTART in signal handlers. + * The headers are needed for the testalarm command that verifies the use of + * SA_RESTART in signal handlers. */ #include <signal.h> #include <sys/resource.h> /* - * The following macros convert between TclFile's and fd's. The conversion + * The following macros convert between TclFile's and fd's. The conversion * simple involves shifting fd's up by one to ensure that no valid fd is ever - * the same as NULL. Note that this code is duplicated from tclUnixPipe.c + * the same as NULL. Note that this code is duplicated from tclUnixPipe.c */ -#define MakeFile(fd) ((TclFile)((fd)+1)) -#define GetFd(file) (((int)file)-1) +#define MakeFile(fd) ((TclFile)INT2PTR(((int)(fd))+1)) +#define GetFd(file) (PTR2INT(file)-1) /* * The stuff below is used to keep track of file handlers created and @@ -38,16 +38,15 @@ */ typedef struct Pipe { - TclFile readFile; /* File handle for reading from the - * pipe. NULL means pipe doesn't exist yet. */ - TclFile writeFile; /* File handle for writing from the - * pipe. */ - int readCount; /* Number of times the file handler for - * this file has triggered and the file - * was readable. */ - int writeCount; /* Number of times the file handler for - * this file has triggered and the file - * was writable. */ + TclFile readFile; /* File handle for reading from the pipe. NULL + * means pipe doesn't exist yet. */ + TclFile writeFile; /* File handle for writing from the pipe. */ + int readCount; /* Number of times the file handler for this + * file has triggered and the file was + * readable. */ + int writeCount; /* Number of times the file handler for this + * file has triggered and the file was + * writable. */ } Pipe; #define MAX_PIPES 10 @@ -57,40 +56,32 @@ static Pipe testPipes[MAX_PIPES]; * The stuff below is used by the testalarm and testgotsig ommands. */ -static char *gotsig = "0"; +static const char *gotsig = "0"; /* - * Forward declarations of procedures defined later in this file: + * Forward declarations of functions defined later in this file: */ -static void TestFileHandlerProc _ANSI_ARGS_((ClientData clientData, - int mask)); -static int TestfilehandlerCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static int TestfilewaitCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static int TestfindexecutableCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static int TestgetopenfileCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static int TestgetdefencdirCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static int TestsetdefencdirCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp)); -static int TestalarmCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static int TestgotsigCmd _ANSI_ARGS_((ClientData dummy, - Tcl_Interp *interp, int argc, char **argv)); -static void AlarmHandler _ANSI_ARGS_(()); +static Tcl_CmdProc TestalarmCmd; +static Tcl_CmdProc TestchmodCmd; +static Tcl_CmdProc TestfilehandlerCmd; +static Tcl_CmdProc TestfilewaitCmd; +static Tcl_CmdProc TestfindexecutableCmd; +static Tcl_ObjCmdProc TestforkObjCmd; +static Tcl_CmdProc TestgetdefencdirCmd; +static Tcl_CmdProc TestgetopenfileCmd; +static Tcl_CmdProc TestgotsigCmd; +static Tcl_CmdProc TestsetdefencdirCmd; +static Tcl_FileProc TestFileHandlerProc; +static void AlarmHandler(int signum); /* *---------------------------------------------------------------------- * * TclplatformtestInit -- * - * Defines commands that test platform specific functionality for - * Unix platforms. + * Defines commands that test platform specific functionality for Unix + * platforms. * * Results: * A standard Tcl result. @@ -102,25 +93,29 @@ static void AlarmHandler _ANSI_ARGS_(()); */ int -TclplatformtestInit(interp) - Tcl_Interp *interp; /* Interpreter to add commands to. */ +TclplatformtestInit( + Tcl_Interp *interp) /* Interpreter to add commands to. */ { + Tcl_CreateCommand(interp, "testchmod", TestchmodCmd, + NULL, NULL); Tcl_CreateCommand(interp, "testfilehandler", TestfilehandlerCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); Tcl_CreateCommand(interp, "testfilewait", TestfilewaitCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); Tcl_CreateCommand(interp, "testfindexecutable", TestfindexecutableCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); + Tcl_CreateObjCommand(interp, "testfork", TestforkObjCmd, + NULL, NULL); Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); Tcl_CreateCommand(interp, "testgetdefenc", TestgetdefencdirCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); Tcl_CreateCommand(interp, "testsetdefenc", TestsetdefencdirCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); Tcl_CreateCommand(interp, "testalarm", TestalarmCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); Tcl_CreateCommand(interp, "testgotsig", TestgotsigCmd, - (ClientData) 0, (Tcl_CmdDeleteProc *) NULL); + NULL, NULL); return TCL_OK; } @@ -129,9 +124,8 @@ TclplatformtestInit(interp) * * TestfilehandlerCmd -- * - * This procedure implements the "testfilehandler" command. It is - * used to test Tcl_CreateFileHandler, Tcl_DeleteFileHandler, and - * TclWaitForFile. + * This function implements the "testfilehandler" command. It is used to + * test Tcl_CreateFileHandler, Tcl_DeleteFileHandler, and TclWaitForFile. * * Results: * A standard Tcl result. @@ -143,11 +137,11 @@ TclplatformtestInit(interp) */ static int -TestfilehandlerCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestfilehandlerCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { Pipe *pipePtr; int i, mask, timeout; @@ -159,7 +153,7 @@ TestfilehandlerCmd(clientData, interp, argc, argv) * NOTE: When we make this code work on Windows also, the following * variable needs to be made Unix-only. */ - + if (!initialized) { for (i = 0; i < MAX_PIPES; i++) { testPipes[i].readFile = NULL; @@ -169,7 +163,7 @@ TestfilehandlerCmd(clientData, interp, argc, argv) if (argc < 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], - " option ... \"", (char *) NULL); + " option ... \"", NULL); return TCL_ERROR; } pipePtr = NULL; @@ -178,7 +172,7 @@ TestfilehandlerCmd(clientData, interp, argc, argv) return TCL_ERROR; } if (i >= MAX_PIPES) { - Tcl_AppendResult(interp, "bad index ", argv[2], (char *) NULL); + Tcl_AppendResult(interp, "bad index ", argv[2], NULL); return TCL_ERROR; } pipePtr = &testPipes[i]; @@ -196,39 +190,38 @@ TestfilehandlerCmd(clientData, interp, argc, argv) } else if (strcmp(argv[1], "clear") == 0) { if (argc != 3) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " clear index\"", (char *) NULL); + argv[0], " clear index\"", NULL); return TCL_ERROR; } pipePtr->readCount = pipePtr->writeCount = 0; } else if (strcmp(argv[1], "counts") == 0) { char buf[TCL_INTEGER_SPACE * 2]; - + if (argc != 3) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " counts index\"", (char *) NULL); + argv[0], " counts index\"", NULL); return TCL_ERROR; } sprintf(buf, "%d %d", pipePtr->readCount, pipePtr->writeCount); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_AppendResult(interp, buf, NULL); } else if (strcmp(argv[1], "create") == 0) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " create index readMode writeMode\"", - (char *) NULL); + argv[0], " create index readMode writeMode\"", NULL); return TCL_ERROR; } if (pipePtr->readFile == NULL) { if (!TclpCreatePipe(&pipePtr->readFile, &pipePtr->writeFile)) { Tcl_AppendResult(interp, "couldn't open pipe: ", - Tcl_PosixError(interp), (char *) NULL); + Tcl_PosixError(interp), NULL); return TCL_ERROR; } #ifdef O_NONBLOCK fcntl(GetFd(pipePtr->readFile), F_SETFL, O_NONBLOCK); fcntl(GetFd(pipePtr->writeFile), F_SETFL, O_NONBLOCK); #else - Tcl_SetResult(interp, "can't make pipes non-blocking", - TCL_STATIC); + Tcl_AppendResult(interp, "can't make pipes non-blocking", + NULL); return TCL_ERROR; #endif } @@ -237,75 +230,71 @@ TestfilehandlerCmd(clientData, interp, argc, argv) if (strcmp(argv[3], "readable") == 0) { Tcl_CreateFileHandler(GetFd(pipePtr->readFile), TCL_READABLE, - TestFileHandlerProc, (ClientData) pipePtr); + TestFileHandlerProc, pipePtr); } else if (strcmp(argv[3], "off") == 0) { Tcl_DeleteFileHandler(GetFd(pipePtr->readFile)); } else if (strcmp(argv[3], "disabled") == 0) { Tcl_CreateFileHandler(GetFd(pipePtr->readFile), 0, - TestFileHandlerProc, (ClientData) pipePtr); + TestFileHandlerProc, pipePtr); } else { - Tcl_AppendResult(interp, "bad read mode \"", argv[3], "\"", - (char *) NULL); + Tcl_AppendResult(interp, "bad read mode \"", argv[3], "\"", NULL); return TCL_ERROR; } if (strcmp(argv[4], "writable") == 0) { Tcl_CreateFileHandler(GetFd(pipePtr->writeFile), TCL_WRITABLE, - TestFileHandlerProc, (ClientData) pipePtr); + TestFileHandlerProc, pipePtr); } else if (strcmp(argv[4], "off") == 0) { Tcl_DeleteFileHandler(GetFd(pipePtr->writeFile)); } else if (strcmp(argv[4], "disabled") == 0) { Tcl_CreateFileHandler(GetFd(pipePtr->writeFile), 0, - TestFileHandlerProc, (ClientData) pipePtr); + TestFileHandlerProc, pipePtr); } else { - Tcl_AppendResult(interp, "bad read mode \"", argv[4], "\"", - (char *) NULL); + Tcl_AppendResult(interp, "bad read mode \"", argv[4], "\"", NULL); return TCL_ERROR; } } else if (strcmp(argv[1], "empty") == 0) { if (argc != 3) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " empty index\"", (char *) NULL); + argv[0], " empty index\"", NULL); return TCL_ERROR; } while (read(GetFd(pipePtr->readFile), buffer, 4000) > 0) { - /* Empty loop body. */ + /* Empty loop body. */ } } else if (strcmp(argv[1], "fill") == 0) { if (argc != 3) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " empty index\"", (char *) NULL); + argv[0], " fill index\"", NULL); return TCL_ERROR; } - memset((VOID *) buffer, 'a', 4000); + memset(buffer, 'a', 4000); while (write(GetFd(pipePtr->writeFile), buffer, 4000) > 0) { - /* Empty loop body. */ + /* Empty loop body. */ } } else if (strcmp(argv[1], "fillpartial") == 0) { char buf[TCL_INTEGER_SPACE]; - + if (argc != 3) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " empty index\"", (char *) NULL); + argv[0], " fillpartial index\"", NULL); return TCL_ERROR; } - memset((VOID *) buffer, 'b', 10); + memset(buffer, 'b', 10); TclFormatInt(buf, write(GetFd(pipePtr->writeFile), buffer, 10)); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + Tcl_AppendResult(interp, buf, NULL); } else if (strcmp(argv[1], "oneevent") == 0) { Tcl_DoOneEvent(TCL_FILE_EVENTS|TCL_DONT_WAIT); } else if (strcmp(argv[1], "wait") == 0) { if (argc != 5) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", - argv[0], " wait index readable/writable timeout\"", - (char *) NULL); + argv[0], " wait index readable|writable timeout\"", NULL); return TCL_ERROR; } if (pipePtr->readFile == NULL) { - Tcl_AppendResult(interp, "pipe ", argv[2], " doesn't exist", - (char *) NULL); + Tcl_AppendResult(interp, "pipe ", argv[2], " doesn't exist", NULL); return TCL_ERROR; } if (strcmp(argv[3], "readable") == 0) { @@ -329,20 +318,20 @@ TestfilehandlerCmd(clientData, interp, argc, argv) Tcl_DoOneEvent(TCL_WINDOW_EVENTS|TCL_DONT_WAIT); } else { Tcl_AppendResult(interp, "bad option \"", argv[1], - "\": must be close, clear, counts, create, empty, fill, ", - "fillpartial, oneevent, wait, or windowevent", - (char *) NULL); + "\": must be close, clear, counts, create, empty, fill, " + "fillpartial, oneevent, wait, or windowevent", NULL); return TCL_ERROR; } return TCL_OK; } -static void TestFileHandlerProc(clientData, mask) - ClientData clientData; /* Points to a Pipe structure. */ - int mask; /* Indicates which events happened: +static void +TestFileHandlerProc( + ClientData clientData, /* Points to a Pipe structure. */ + int mask) /* Indicates which events happened: * TCL_READABLE or TCL_WRITABLE. */ { - Pipe *pipePtr = (Pipe *) clientData; + Pipe *pipePtr = clientData; if (mask & TCL_READABLE) { pipePtr->readCount++; @@ -357,8 +346,8 @@ static void TestFileHandlerProc(clientData, mask) * * TestfilewaitCmd -- * - * This procedure implements the "testfilewait" command. It is - * used to test TclUnixWaitForFile. + * This function implements the "testfilewait" command. It is used to + * test TclUnixWaitForFile. * * Results: * A standard Tcl result. @@ -370,11 +359,11 @@ static void TestFileHandlerProc(clientData, mask) */ static int -TestfilewaitCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestfilewaitCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { int mask, result, timeout; Tcl_Channel channel; @@ -383,7 +372,7 @@ TestfilewaitCmd(clientData, interp, argc, argv) if (argc != 4) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], - " file readable|writable|both timeout\"", (char *) NULL); + " file readable|writable|both timeout\"", NULL); return TCL_ERROR; } channel = Tcl_GetChannel(interp, argv[1], NULL); @@ -398,16 +387,16 @@ TestfilewaitCmd(clientData, interp, argc, argv) mask = TCL_WRITABLE|TCL_READABLE; } else { Tcl_AppendResult(interp, "bad argument \"", argv[2], - "\": must be readable, writable, or both", (char *) NULL); + "\": must be readable, writable, or both", NULL); return TCL_ERROR; } - if (Tcl_GetChannelHandle(channel, + if (Tcl_GetChannelHandle(channel, (mask & TCL_READABLE) ? TCL_READABLE : TCL_WRITABLE, (ClientData*) &data) != TCL_OK) { - Tcl_SetResult(interp, "couldn't get channel file", TCL_STATIC); + Tcl_AppendResult(interp, "couldn't get channel file", NULL); return TCL_ERROR; } - fd = (int) data; + fd = PTR2INT(data); if (Tcl_GetInt(interp, argv[3], &timeout) != TCL_OK) { return TCL_ERROR; } @@ -426,8 +415,8 @@ TestfilewaitCmd(clientData, interp, argc, argv) * * TestfindexecutableCmd -- * - * This procedure implements the "testfindexecutable" command. It is - * used to test Tcl_FindExecutable. + * This function implements the "testfindexecutable" command. It is used + * to test TclpFindExecutable. * * Results: * A standard Tcl result. @@ -439,39 +428,28 @@ TestfilewaitCmd(clientData, interp, argc, argv) */ static int -TestfindexecutableCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestfindexecutableCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { - char *oldName; - char *oldNativeName; + Tcl_Obj *saveName; if (argc != 2) { Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0], - " argv0\"", (char *) NULL); + " argv0\"", NULL); return TCL_ERROR; } - oldName = tclExecutableName; - oldNativeName = tclNativeExecutableName; - - tclExecutableName = NULL; - tclNativeExecutableName = NULL; + saveName = TclGetObjNameOfExecutable(); + Tcl_IncrRefCount(saveName); - Tcl_FindExecutable(argv[1]); - if (tclExecutableName != NULL) { - Tcl_SetResult(interp, tclExecutableName, TCL_VOLATILE); - ckfree(tclExecutableName); - } - if (tclNativeExecutableName != NULL) { - ckfree(tclNativeExecutableName); - } - - tclExecutableName = oldName; - tclNativeExecutableName = oldNativeName; + TclpFindExecutable(argv[1]); + Tcl_SetObjResult(interp, TclGetObjNameOfExecutable()); + TclSetObjNameOfExecutable(saveName, NULL); + Tcl_DecrRefCount(saveName); return TCL_OK; } @@ -480,8 +458,8 @@ TestfindexecutableCmd(clientData, interp, argc, argv) * * TestgetopenfileCmd -- * - * This procedure implements the "testgetopenfile" command. It is - * used to get a FILE * value from a registered channel. + * This function implements the "testgetopenfile" command. It is used to + * get a FILE * value from a registered channel. * * Results: * A standard Tcl result. @@ -493,28 +471,26 @@ TestfindexecutableCmd(clientData, interp, argc, argv) */ static int -TestgetopenfileCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestgetopenfileCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { ClientData filePtr; if (argc != 3) { - Tcl_AppendResult(interp, - "wrong # args: should be \"", argv[0], - " channelName forWriting\"", - (char *) NULL); + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " channelName forWriting\"", NULL); return TCL_ERROR; } if (Tcl_GetOpenFile(interp, argv[1], atoi(argv[2]), 1, &filePtr) - == TCL_ERROR) { + == TCL_ERROR) { return TCL_ERROR; } - if (filePtr == (ClientData) NULL) { + if (filePtr == NULL) { Tcl_AppendResult(interp, - "Tcl_GetOpenFile succeeded but FILE * NULL!", (char *) NULL); + "Tcl_GetOpenFile succeeded but FILE * NULL!", NULL); return TCL_ERROR; } return TCL_OK; @@ -525,8 +501,8 @@ TestgetopenfileCmd(clientData, interp, argc, argv) * * TestsetdefencdirCmd -- * - * This procedure implements the "testsetdefenc" command. It is - * used to set the value of tclDefaultEncodingDir. + * This function implements the "testsetdefenc" command. It is used to + * test Tcl_SetDefaultEncodingDir(). * * Results: * A standard Tcl result. @@ -538,29 +514,64 @@ TestgetopenfileCmd(clientData, interp, argc, argv) */ static int -TestsetdefencdirCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestsetdefencdirCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { if (argc != 2) { - Tcl_AppendResult(interp, - "wrong # args: should be \"", argv[0], - " defaultDir\"", - (char *) NULL); + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " defaultDir\"", NULL); return TCL_ERROR; } - if (tclDefaultEncodingDir != NULL) { - ckfree(tclDefaultEncodingDir); - tclDefaultEncodingDir = NULL; + Tcl_SetDefaultEncodingDir(argv[1]); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TestforkObjCmd -- + * + * This function implements the "testfork" command. It is used to + * fork the Tcl process for specific test cases. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +TestforkObjCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const *objv) /* Argument strings. */ +{ + pid_t pid; + + if (objc != 1) { + Tcl_WrongNumArgs(interp, 1, objv, ""); + return TCL_ERROR; } - if (*argv[1] != '\0') { - tclDefaultEncodingDir = (char *) - ckalloc((unsigned) strlen(argv[1]) + 1); - strcpy(tclDefaultEncodingDir, argv[1]); + pid = fork(); + if (pid == -1) { + Tcl_AppendResult(interp, + "Cannot fork", NULL); + return TCL_ERROR; } + /* Only needed when pthread_atfork is not present, + * should not hurt otherwise. */ + if (pid==0) { + Tcl_InitNotifier(); + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(pid)); return TCL_OK; } @@ -569,8 +580,8 @@ TestsetdefencdirCmd(clientData, interp, argc, argv) * * TestgetdefencdirCmd -- * - * This procedure implements the "testgetdefenc" command. It is - * used to get the value of tclDefaultEncodingDir. + * This function implements the "testgetdefenc" command. It is used to + * test Tcl_GetDefaultEncodingDir(). * * Results: * A standard Tcl result. @@ -582,32 +593,29 @@ TestsetdefencdirCmd(clientData, interp, argc, argv) */ static int -TestgetdefencdirCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestgetdefencdirCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { if (argc != 1) { - Tcl_AppendResult(interp, - "wrong # args: should be \"", argv[0], - (char *) NULL); + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], NULL); return TCL_ERROR; } - if (tclDefaultEncodingDir != NULL) { - Tcl_AppendResult(interp, tclDefaultEncodingDir, (char *) NULL); - } + Tcl_AppendResult(interp, Tcl_GetDefaultEncodingDir(), NULL); return TCL_OK; } /* *---------------------------------------------------------------------- + * * TestalarmCmd -- * - * Test that EINTR is handled correctly by generating and - * handling a signal. This requires using the SA_RESTART - * flag when registering the signal handler. + * Test that EINTR is handled correctly by generating and handling a + * signal. This requires using the SA_RESTART flag when registering the + * signal handler. * * Results: * None. @@ -619,11 +627,11 @@ TestgetdefencdirCmd(clientData, interp, argc, argv) */ static int -TestalarmCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestalarmCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { #ifdef SA_RESTART unsigned int sec; @@ -636,24 +644,24 @@ TestalarmCmd(clientData, interp, argc, argv) } /* - * Setup the signal handling that automatically retries - * any interupted I/O system calls. + * Setup the signal handling that automatically retries any interrupted + * I/O system calls. */ + action.sa_handler = AlarmHandler; - memset((void *)&action.sa_mask, 0, sizeof(sigset_t)); + memset((void *) &action.sa_mask, 0, sizeof(sigset_t)); action.sa_flags = SA_RESTART; if (sigaction(SIGALRM, &action, NULL) < 0) { Tcl_AppendResult(interp, "sigaction: ", Tcl_PosixError(interp), NULL); return TCL_ERROR; } - if (alarm(sec) < 0) { - Tcl_AppendResult(interp, "alarm: ", Tcl_PosixError(interp), NULL); - return TCL_ERROR; - } + (void) alarm(sec); return TCL_OK; #else - Tcl_AppendResult(interp, "warning: sigaction SA_RESTART not support on this platform", NULL); + Tcl_AppendResult(interp, + "warning: sigaction SA_RESTART not support on this platform", + NULL); return TCL_ERROR; #endif } @@ -675,13 +683,15 @@ TestalarmCmd(clientData, interp, argc, argv) */ static void -AlarmHandler() +AlarmHandler( + int signum) { gotsig = "1"; } /* *---------------------------------------------------------------------- + * * TestgotsigCmd -- * * Verify the signal was handled after the testalarm command. @@ -696,13 +706,81 @@ AlarmHandler() */ static int -TestgotsigCmd(clientData, interp, argc, argv) - ClientData clientData; /* Not used. */ - Tcl_Interp *interp; /* Current interpreter. */ - int argc; /* Number of arguments. */ - char **argv; /* Argument strings. */ +TestgotsigCmd( + ClientData clientData, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ { - Tcl_AppendResult(interp, gotsig, (char *) NULL); + Tcl_AppendResult(interp, gotsig, NULL); gotsig = "0"; return TCL_OK; } + +/* + *--------------------------------------------------------------------------- + * + * TestchmodCmd -- + * + * Implements the "testchmod" cmd. Used when testing "file" command. + * The only attribute used by the Windows platform is the user write + * flag; if this is not set, the file is made read-only. Otehrwise, the + * file is made read-write. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * Changes permissions of specified files. + * + *--------------------------------------------------------------------------- + */ + +static int +TestchmodCmd( + ClientData dummy, /* Not used. */ + Tcl_Interp *interp, /* Current interpreter. */ + int argc, /* Number of arguments. */ + const char **argv) /* Argument strings. */ +{ + int i, mode; + char *rest; + + if (argc < 2) { + usage: + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " mode file ?file ...?", NULL); + return TCL_ERROR; + } + + mode = (int) strtol(argv[1], &rest, 8); + if ((rest == argv[1]) || (*rest != '\0')) { + goto usage; + } + + for (i = 2; i < argc; i++) { + Tcl_DString buffer; + const char *translated; + + translated = Tcl_TranslateFileName(interp, argv[i], &buffer); + if (translated == NULL) { + return TCL_ERROR; + } + if (chmod(translated, (unsigned) mode) != 0) { + Tcl_AppendResult(interp, translated, ": ", Tcl_PosixError(interp), + NULL); + return TCL_ERROR; + } + Tcl_DStringFree(&buffer); + } + return TCL_OK; +} + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * tab-width: 8 + * End: + */ |