summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/unixFCmd.test26
-rw-r--r--unix/tclUnixTest.c106
2 files changed, 42 insertions, 90 deletions
diff --git a/tests/unixFCmd.test b/tests/unixFCmd.test
index 41b9bc7..e8f997d 100644
--- a/tests/unixFCmd.test
+++ b/tests/unixFCmd.test
@@ -92,13 +92,25 @@ test unixFCmd-1.7 {TclpRenameFile: EXDEV} {
set result
} {1}
test unixFCmd-1.8 {Checking EINTR Bug} {
- global gotsig
- set gotsig 0
- testalarm {set gotsig 1}
- for {set i 0} {$i < 500000} {incr i} {}
- return $gotsig
-} {1}
-catch {unset gotsig}
+ testalarm
+ after 2000
+ list [testgotsig] [testgotsig]
+} {1 0}
+test unixFCmd-1.9 {Checking EINTR Bug} {
+ cleanup
+ set f [open tfalarm w]
+ puts $f {
+ after 2000
+ puts "hello world"
+ exit 0
+ }
+ close $f
+ testalarm
+ set pipe [open "|[info nameofexecutable] tfalarm" r+]
+ set line [read $pipe 1]
+ catch {close $pipe}
+ list $line [testgotsig]
+} {h 1}
test unixFCmd-2.1 {TclpCopyFile: target exists: lstat(dst) == 0} {
cleanup
exec touch tf1
diff --git a/unix/tclUnixTest.c b/unix/tclUnixTest.c
index 835b5e5..8ab163e 100644
--- a/unix/tclUnixTest.c
+++ b/unix/tclUnixTest.c
@@ -55,10 +55,10 @@ typedef struct Pipe {
static Pipe testPipes[MAX_PIPES];
/*
- * The var below is used by the testalarm command.
+ * The stuff below is used by the testalarm and testgotsig ommands.
*/
-static Tcl_AsyncHandler sigToken;
+static char gotsig = '0';
/*
* Forward declarations of procedures defined later in this file:
@@ -77,11 +77,9 @@ static int TestgetopenfileCmd _ANSI_ARGS_((ClientData dummy,
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));
void AlarmHandler _ANSI_ARGS_(());
-int HandleAlarmSignal _ANSI_ARGS_((ClientData clientData,
- Tcl_Interp *interp, int code));
-static void CleanupAlarmAssocData _ANSI_ARGS_((
- ClientData clientData, Tcl_Interp *interp));
/*
*----------------------------------------------------------------------
@@ -114,6 +112,8 @@ TclplatformtestInit(interp)
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
Tcl_CreateCommand(interp, "testalarm", TestalarmCmd,
(ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
+ Tcl_CreateCommand(interp, "testgotsig", TestgotsigCmd,
+ (ClientData) 0, (Tcl_CmdDeleteProc *) NULL);
return TCL_OK;
}
@@ -525,44 +525,16 @@ TestalarmCmd(clientData, interp, argc, argv)
int argc; /* Number of arguments. */
char **argv; /* Argument strings. */
{
- char *cmd;
- char *oldData;
- Tcl_InterpDeleteProc *procPtr;
unsigned int sec;
RETSIGTYPE (*oldhandler)();
- if (argc < 2) {
- Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
- " script ?seconds?\"", (char *) NULL);
- return TCL_ERROR;
- }
-
- cmd = ckalloc((unsigned) strlen(argv[1]) + 1);
- strcpy(cmd, argv[1]);
- if (argc > 2) {
- Tcl_GetInt(interp, argv[2], (int *)&sec);
+ if (argc > 1) {
+ Tcl_GetInt(interp, argv[1], (int *)&sec);
} else {
sec = 1;
}
/*
- * If we previously associated a malloced value with the variable,
- * free it before associating a new value.
- */
-
- oldData = (char *) Tcl_GetAssocData(interp, argv[1], &procPtr);
- if ((oldData != NULL) && (procPtr == CleanupAlarmAssocData)) {
- ckfree(oldData);
- }
-
- /*
- * Store the command to execute when the signal is generated.
- */
-
- Tcl_SetAssocData(interp, "alarmCmd", CleanupAlarmAssocData,
- (ClientData) cmd);
-
- /*
* Setup the signal handling.
*/
@@ -571,7 +543,6 @@ TestalarmCmd(clientData, interp, argc, argv)
Tcl_AppendResult(interp, "signal: ", Tcl_PosixError(interp), NULL);
return TCL_ERROR;
}
- sigToken = Tcl_AsyncCreate(HandleAlarmSignal, NULL);
if (alarm(sec) < 0) {
Tcl_AppendResult(interp, "alarm: ", Tcl_PosixError(interp), NULL);
return TCL_ERROR;
@@ -594,67 +565,36 @@ TestalarmCmd(clientData, interp, argc, argv)
*
*----------------------------------------------------------------------
*/
+
void
AlarmHandler()
{
- Tcl_AsyncMark(sigToken);
+ gotsig = '1';
}
/*
*----------------------------------------------------------------------
+ * TestgotsigCmd --
*
- * HandleAlarmSignal --
- *
- * The async callback from Tcl that calls the alarm command.
+ * Verify the signal was handled after the testalarm command.
*
* Results:
- * A standard Tcl result.
- *
- * Side effects:
* None.
*
- *----------------------------------------------------------------------
- */
-
-int
-HandleAlarmSignal(clientData, interp, code)
- ClientData clientData; /* Data to be released. */
- Tcl_Interp *interp; /* Interpreter being deleted. */
- int code;
-{
- char *cmd;
-
- cmd = (char *) Tcl_GetAssocData(interp, "alarmCmd", NULL);
- if (cmd != NULL) {
- Tcl_GlobalEval(interp, cmd);
- return TCL_OK;
- } else {
- Tcl_AppendResult(interp, "alarm assoc data is NULL", (char *) NULL);
- return TCL_ERROR;
- }
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * CleanupAlarmAssocData --
- *
- * This function is called when an interpreter is deleted to clean
- * up any data left over from running the testalarm command.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Releases storage.
+ * Side Effects:
+ * Resets the value of gotsig back to '0'.
*
*----------------------------------------------------------------------
*/
-static void
-CleanupAlarmAssocData(clientData, interp)
- ClientData clientData; /* Data to be released. */
- Tcl_Interp *interp; /* Interpreter being deleted. */
+int
+TestgotsigCmd(clientData, interp, argc, argv)
+ ClientData clientData; /* Not used. */
+ Tcl_Interp *interp; /* Current interpreter. */
+ int argc; /* Number of arguments. */
+ char **argv; /* Argument strings. */
{
- ckfree((char *) clientData);
+ Tcl_AppendResult(interp, &gotsig, (char *) NULL);
+ gotsig = '0';
+ return TCL_OK;
}