summaryrefslogtreecommitdiff
path: root/contrib/tcl/unix/tclUnixTest.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcl/unix/tclUnixTest.c')
-rw-r--r--contrib/tcl/unix/tclUnixTest.c167
1 files changed, 109 insertions, 58 deletions
diff --git a/contrib/tcl/unix/tclUnixTest.c b/contrib/tcl/unix/tclUnixTest.c
index 1fc95e643657e..67717d02b771f 100644
--- a/contrib/tcl/unix/tclUnixTest.c
+++ b/contrib/tcl/unix/tclUnixTest.c
@@ -8,21 +8,30 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * SCCS: @(#) tclUnixTest.c 1.1 96/03/26 12:44:30
+ * SCCS: @(#) tclUnixTest.c 1.4 97/05/14 13:24:29
*/
#include "tclInt.h"
#include "tclPort.h"
/*
+ * 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
+ */
+
+#define MakeFile(fd) ((TclFile)((fd)+1))
+#define GetFd(file) (((int)file)-1)
+
+/*
* The stuff below is used to keep track of file handlers created and
* exercised by the "testfilehandler" command.
*/
typedef struct Pipe {
- Tcl_File readFile; /* File handle for reading from the
+ TclFile readFile; /* File handle for reading from the
* pipe. NULL means pipe doesn't exist yet. */
- Tcl_File writeFile; /* File handle for writing from the
+ 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
@@ -43,6 +52,8 @@ 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 TestgetopenfileCmd _ANSI_ARGS_((ClientData dummy,
Tcl_Interp *interp, int argc, char **argv));
int TclplatformtestInit _ANSI_ARGS_((Tcl_Interp *interp));
@@ -70,6 +81,8 @@ TclplatformtestInit(interp)
{
Tcl_CreateCommand(interp, "testfilehandler", TestfilehandlerCmd,
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateCommand(interp, "testfilewait", TestfilewaitCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "testgetopenfile", TestgetopenfileCmd,
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
@@ -104,15 +117,13 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
int i, mask, timeout;
static int initialized = 0;
char buffer[4000];
- Tcl_File file;
+ TclFile file;
/*
* NOTE: When we make this code work on Windows also, the following
* variable needs to be made Unix-only.
*/
- int fd;
-
if (!initialized) {
for (i = 0; i < MAX_PIPES; i++) {
testPipes[i].readFile = NULL;
@@ -140,26 +151,10 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
if (strcmp(argv[1], "close") == 0) {
for (i = 0; i < MAX_PIPES; i++) {
if (testPipes[i].readFile != NULL) {
- Tcl_DeleteFileHandler(testPipes[i].readFile);
-
- /*
- * NOTE: Unix specific code below.
- */
-
- fd = (int) Tcl_GetFileInfo(testPipes[i].readFile, NULL);
- close(fd);
- Tcl_FreeFile(testPipes[i].readFile);
-
+ TclpCloseFile(testPipes[i].readFile);
testPipes[i].readFile = NULL;
- Tcl_DeleteFileHandler(testPipes[i].writeFile);
-
- /*
- * NOTE: Unix specific code below.
- */
-
- fd = (int) Tcl_GetFileInfo(testPipes[i].writeFile, NULL);
- Tcl_FreeFile(testPipes[i].writeFile);
- close(fd);
+ TclpCloseFile(testPipes[i].writeFile);
+ testPipes[i].writeFile = NULL;
}
}
} else if (strcmp(argv[1], "clear") == 0) {
@@ -170,13 +165,15 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
}
pipePtr->readCount = pipePtr->writeCount = 0;
} else if (strcmp(argv[1], "counts") == 0) {
+ char buf[30];
+
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # arguments: should be \"",
argv[0], " counts index\"", (char *) NULL);
return TCL_ERROR;
}
- sprintf(interp->result, "%d %d", pipePtr->readCount,
- pipePtr->writeCount);
+ sprintf(buf, "%d %d", pipePtr->readCount, pipePtr->writeCount);
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if (strcmp(argv[1], "create") == 0) {
if (argc != 5) {
Tcl_AppendResult(interp, "wrong # arguments: should be \"",
@@ -185,18 +182,17 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
return TCL_ERROR;
}
if (pipePtr->readFile == NULL) {
- if (!TclCreatePipe(&pipePtr->readFile, &pipePtr->writeFile)) {
+ if (!TclpCreatePipe(&pipePtr->readFile, &pipePtr->writeFile)) {
Tcl_AppendResult(interp, "couldn't open pipe: ",
Tcl_PosixError(interp), (char *) NULL);
return TCL_ERROR;
}
#ifdef O_NONBLOCK
- fcntl((int)Tcl_GetFileInfo(pipePtr->readFile, NULL),
- F_SETFL, O_NONBLOCK);
- fcntl((int)Tcl_GetFileInfo(pipePtr->writeFile, NULL),
- F_SETFL, O_NONBLOCK);
+ fcntl(GetFd(pipePtr->readFile), F_SETFL, O_NONBLOCK);
+ fcntl(GetFd(pipePtr->writeFile), F_SETFL, O_NONBLOCK);
#else
- interp->result = "can't make pipes non-blocking";
+ Tcl_SetResult(interp, "can't make pipes non-blocking",
+ TCL_STATIC);
return TCL_ERROR;
#endif
}
@@ -204,12 +200,12 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
pipePtr->writeCount = 0;
if (strcmp(argv[3], "readable") == 0) {
- Tcl_CreateFileHandler(pipePtr->readFile, TCL_READABLE,
+ Tcl_CreateFileHandler(GetFd(pipePtr->readFile), TCL_READABLE,
TestFileHandlerProc, (ClientData) pipePtr);
} else if (strcmp(argv[3], "off") == 0) {
- Tcl_DeleteFileHandler(pipePtr->readFile);
+ Tcl_DeleteFileHandler(GetFd(pipePtr->readFile));
} else if (strcmp(argv[3], "disabled") == 0) {
- Tcl_CreateFileHandler(pipePtr->readFile, 0,
+ Tcl_CreateFileHandler(GetFd(pipePtr->readFile), 0,
TestFileHandlerProc, (ClientData) pipePtr);
} else {
Tcl_AppendResult(interp, "bad read mode \"", argv[3], "\"",
@@ -217,12 +213,12 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
return TCL_ERROR;
}
if (strcmp(argv[4], "writable") == 0) {
- Tcl_CreateFileHandler(pipePtr->writeFile, TCL_WRITABLE,
+ Tcl_CreateFileHandler(GetFd(pipePtr->writeFile), TCL_WRITABLE,
TestFileHandlerProc, (ClientData) pipePtr);
} else if (strcmp(argv[4], "off") == 0) {
- Tcl_DeleteFileHandler(pipePtr->writeFile);
+ Tcl_DeleteFileHandler(GetFd(pipePtr->writeFile));
} else if (strcmp(argv[4], "disabled") == 0) {
- Tcl_CreateFileHandler(pipePtr->writeFile, 0,
+ Tcl_CreateFileHandler(GetFd(pipePtr->writeFile), 0,
TestFileHandlerProc, (ClientData) pipePtr);
} else {
Tcl_AppendResult(interp, "bad read mode \"", argv[4], "\"",
@@ -236,12 +232,7 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
return TCL_ERROR;
}
- /*
- * NOTE: Unix specific code below.
- */
-
- fd = (int) Tcl_GetFileInfo(pipePtr->readFile, NULL);
- while (read(fd, buffer, 4000) > 0) {
+ while (read(GetFd(pipePtr->readFile), buffer, 4000) > 0) {
/* Empty loop body. */
}
} else if (strcmp(argv[1], "fill") == 0) {
@@ -251,29 +242,22 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
return TCL_ERROR;
}
- /*
- * NOTE: Unix specific code below.
- */
-
- fd = (int) Tcl_GetFileInfo(pipePtr->writeFile, NULL);
memset((VOID *) buffer, 'a', 4000);
- while (write(fd, buffer, 4000) > 0) {
+ while (write(GetFd(pipePtr->writeFile), buffer, 4000) > 0) {
/* Empty loop body. */
}
} else if (strcmp(argv[1], "fillpartial") == 0) {
+ char buf[30];
+
if (argc != 3) {
Tcl_AppendResult(interp, "wrong # arguments: should be \"",
argv[0], " empty index\"", (char *) NULL);
return TCL_ERROR;
}
- /*
- * NOTE: Unix specific code below.
- */
-
- fd = (int) Tcl_GetFileInfo(pipePtr->writeFile, NULL);
memset((VOID *) buffer, 'b', 10);
- sprintf(interp->result, "%d", write(fd, buffer, 10));
+ sprintf(buf, "%d", write(GetFd(pipePtr->writeFile), buffer, 10));
+ Tcl_SetResult(interp, buf, TCL_VOLATILE);
} else if (strcmp(argv[1], "oneevent") == 0) {
Tcl_DoOneEvent(TCL_FILE_EVENTS|TCL_DONT_WAIT);
} else if (strcmp(argv[1], "wait") == 0) {
@@ -298,7 +282,7 @@ TestfilehandlerCmd(clientData, interp, argc, argv)
if (Tcl_GetInt(interp, argv[4], &timeout) != TCL_OK) {
return TCL_ERROR;
}
- i = TclWaitForFile(file, mask, timeout);
+ i = TclUnixWaitForFile(GetFd(file), mask, timeout);
if (i & TCL_READABLE) {
Tcl_AppendElement(interp, "readable");
}
@@ -335,6 +319,73 @@ static void TestFileHandlerProc(clientData, mask)
/*
*----------------------------------------------------------------------
*
+ * TestfilewaitCmd --
+ *
+ * This procedure implements the "testfilewait" command. It is
+ * used to test TclUnixWaitForFile.
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+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. */
+{
+ int mask, result, timeout;
+ Tcl_Channel channel;
+ int fd;
+
+ if (argc != 4) {
+ Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+ " file readable|writable|both timeout\"", (char *) NULL);
+ return TCL_ERROR;
+ }
+ channel = Tcl_GetChannel(interp, argv[1], NULL);
+ if (channel == NULL) {
+ return TCL_ERROR;
+ }
+ if (strcmp(argv[2], "readable") == 0) {
+ mask = TCL_READABLE;
+ } else if (strcmp(argv[2], "writable") == 0){
+ mask = TCL_WRITABLE;
+ } else if (strcmp(argv[2], "both") == 0){
+ mask = TCL_WRITABLE|TCL_READABLE;
+ } else {
+ Tcl_AppendResult(interp, "bad argument \"", argv[2],
+ "\": must be readable, writable, or both", (char *) NULL);
+ return TCL_ERROR;
+ }
+ if (Tcl_GetChannelHandle(channel,
+ (mask & TCL_READABLE) ? TCL_READABLE : TCL_WRITABLE,
+ (ClientData*) &fd) != TCL_OK) {
+ Tcl_SetResult(interp, "couldn't get channel file", TCL_STATIC);
+ return TCL_ERROR;
+ }
+ if (Tcl_GetInt(interp, argv[3], &timeout) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ result = TclUnixWaitForFile(fd, mask, timeout);
+ if (result & TCL_READABLE) {
+ Tcl_AppendElement(interp, "readable");
+ }
+ if (result & TCL_WRITABLE) {
+ Tcl_AppendElement(interp, "writable");
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TestgetopenfileCmd --
*
* This procedure implements the "testgetopenfile" command. It is