summaryrefslogtreecommitdiffstats
path: root/generic/tclPipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclPipe.c')
-rw-r--r--generic/tclPipe.c261
1 files changed, 116 insertions, 145 deletions
diff --git a/generic/tclPipe.c b/generic/tclPipe.c
index 83fb818..698f85d 100644
--- a/generic/tclPipe.c
+++ b/generic/tclPipe.c
@@ -32,8 +32,8 @@ TCL_DECLARE_MUTEX(pipeMutex) /* Guard access to detList. */
* Declarations for local functions defined in this file:
*/
-static TclFile FileForRedirect(Tcl_Interp *interp, const char *spec,
- int atOk, const char *arg, const char *nextArg,
+static TclFile FileForRedirect(Tcl_Interp *interp, CONST char *spec,
+ int atOk, CONST char *arg, CONST char *nextArg,
int flags, int *skipPtr, int *closePtr,
int *releasePtr);
@@ -61,14 +61,14 @@ static TclFile FileForRedirect(Tcl_Interp *interp, const char *spec,
static TclFile
FileForRedirect(
Tcl_Interp *interp, /* Intepreter to use for error reporting. */
- const char *spec, /* Points to character just after redirection
+ CONST char *spec, /* Points to character just after redirection
* character. */
int atOK, /* Non-zero means that '@' notation can be
* used to specify a channel, zero means that
* it isn't. */
- const char *arg, /* Pointer to entire argument containing spec:
+ CONST char *arg, /* Pointer to entire argument containing spec:
* used for error reporting. */
- const char *nextArg, /* Next argument in argc/argv array, if needed
+ CONST char *nextArg, /* Next argument in argc/argv array, if needed
* for file name or channel name. May be
* NULL. */
int flags, /* Flags to use for opening file or to specify
@@ -94,27 +94,23 @@ FileForRedirect(
}
*skipPtr = 2;
}
- chan = Tcl_GetChannel(interp, spec, NULL);
- if (chan == (Tcl_Channel) NULL) {
- return NULL;
- }
+ chan = Tcl_GetChannel(interp, spec, NULL);
+ if (chan == (Tcl_Channel) NULL) {
+ return NULL;
+ }
file = TclpMakeFile(chan, writing ? TCL_WRITABLE : TCL_READABLE);
- if (file == NULL) {
- Tcl_Obj *msg;
-
+ if (file == NULL) {
+ Tcl_Obj* msg;
Tcl_GetChannelError(chan, &msg);
if (msg) {
- Tcl_SetObjResult(interp, msg);
+ Tcl_SetObjResult (interp, msg);
} else {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "channel \"%s\" wasn't opened for %s",
- Tcl_GetChannelName(chan),
- ((writing) ? "writing" : "reading")));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
- "BADCHAN", NULL);
+ Tcl_AppendResult(interp, "channel \"", Tcl_GetChannelName(chan),
+ "\" wasn't opened for ",
+ ((writing) ? "writing" : "reading"), NULL);
}
- return NULL;
- }
+ return NULL;
+ }
*releasePtr = 1;
if (writing) {
/*
@@ -122,10 +118,10 @@ FileForRedirect(
* by the child appears after stuff we've already written.
*/
- Tcl_Flush(chan);
+ Tcl_Flush(chan);
}
} else {
- const char *name;
+ CONST char *name;
Tcl_DString nameString;
if (*spec == '\0') {
@@ -142,20 +138,18 @@ FileForRedirect(
file = TclpOpenFile(name, flags);
Tcl_DStringFree(&nameString);
if (file == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "couldn't %s file \"%s\": %s",
- (writing ? "write" : "read"), spec,
- Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp, "couldn't ",
+ ((writing) ? "write" : "read"), " file \"", spec, "\": ",
+ Tcl_PosixError(interp), NULL);
return NULL;
}
- *closePtr = 1;
+ *closePtr = 1;
}
return file;
badLastArg:
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't specify \"%s\" as last word in command", arg));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "SYNTAX", NULL);
+ Tcl_AppendResult(interp, "can't specify \"", arg,
+ "\" as last word in command", NULL);
return NULL;
}
@@ -188,7 +182,7 @@ Tcl_DetachPids(
Tcl_MutexLock(&pipeMutex);
for (i = 0; i < numPids; i++) {
- detPtr = ckalloc(sizeof(Detached));
+ detPtr = (Detached *) ckalloc(sizeof(Detached));
detPtr->pid = pidPtr[i];
detPtr->nextPtr = detList;
detList = detPtr;
@@ -238,7 +232,7 @@ Tcl_ReapDetachedProcs(void)
} else {
prevPtr->nextPtr = detPtr->nextPtr;
}
- ckfree(detPtr);
+ ckfree((char *) detPtr);
detPtr = nextPtr;
}
Tcl_MutexUnlock(&pipeMutex);
@@ -278,8 +272,8 @@ TclCleanupChildren(
int result = TCL_OK;
int i, abnormalExit, anyErrorInfo;
Tcl_Pid pid;
- int waitStatus;
- const char *msg;
+ WAIT_STATUS_TYPE waitStatus;
+ CONST char *msg;
unsigned long resolvedPid;
abnormalExit = 0;
@@ -291,24 +285,24 @@ TclCleanupChildren(
*/
resolvedPid = TclpGetPid(pidPtr[i]);
- pid = Tcl_WaitPid(pidPtr[i], &waitStatus, 0);
+ pid = Tcl_WaitPid(pidPtr[i], (int *) &waitStatus, 0);
if (pid == (Tcl_Pid) -1) {
result = TCL_ERROR;
- if (interp != NULL) {
- msg = Tcl_PosixError(interp);
- if (errno == ECHILD) {
+ if (interp != NULL) {
+ msg = Tcl_PosixError(interp);
+ if (errno == ECHILD) {
/*
- * This changeup in message suggested by Mark Diekhans to
- * remind people that ECHILD errors can occur on some
- * systems if SIGCHLD isn't in its default state.
- */
-
- msg =
- "child process lost (is SIGCHLD ignored or trapped?)";
- }
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "error waiting for process to exit: %s", msg));
- }
+ * This changeup in message suggested by Mark Diekhans to
+ * remind people that ECHILD errors can occur on some
+ * systems if SIGCHLD isn't in its default state.
+ */
+
+ msg =
+ "child process lost (is SIGCHLD ignored or trapped?)";
+ }
+ Tcl_AppendResult(interp, "error waiting for process to exit: ",
+ msg, NULL);
+ }
continue;
}
@@ -325,32 +319,32 @@ TclCleanupChildren(
result = TCL_ERROR;
sprintf(msg1, "%lu", resolvedPid);
if (WIFEXITED(waitStatus)) {
- if (interp != NULL) {
- sprintf(msg2, "%u", WEXITSTATUS(waitStatus));
- Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, NULL);
- }
+ if (interp != (Tcl_Interp *) NULL) {
+ sprintf(msg2, "%lu",
+ (unsigned long) WEXITSTATUS(waitStatus));
+ Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, NULL);
+ }
abnormalExit = 1;
} else if (interp != NULL) {
- const char *p;
+ CONST char *p;
if (WIFSIGNALED(waitStatus)) {
- p = Tcl_SignalMsg(WTERMSIG(waitStatus));
- Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
- Tcl_SignalId(WTERMSIG(waitStatus)), p, NULL);
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "child killed: %s\n", p));
+ p = Tcl_SignalMsg((int) (WTERMSIG(waitStatus)));
+ Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
+ Tcl_SignalId((int) (WTERMSIG(waitStatus))), p,
+ NULL);
+ Tcl_AppendResult(interp, "child killed: ", p, "\n", NULL);
} else if (WIFSTOPPED(waitStatus)) {
- p = Tcl_SignalMsg(WSTOPSIG(waitStatus));
- Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
- Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL);
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "child suspended: %s\n", p));
+ p = Tcl_SignalMsg((int) (WSTOPSIG(waitStatus)));
+ Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
+ Tcl_SignalId((int) (WSTOPSIG(waitStatus))), p,
+ NULL);
+ Tcl_AppendResult(interp, "child suspended: ", p, "\n",
+ NULL);
} else {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "child wait status didn't make sense\n", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
- "ODDWAITRESULT", msg1, NULL);
- }
+ Tcl_AppendResult(interp,
+ "child wait status didn't make sense\n", NULL);
+ }
}
}
}
@@ -366,7 +360,7 @@ TclCleanupChildren(
* Make sure we start at the beginning of the file.
*/
- if (interp != NULL) {
+ if (interp != NULL) {
int count;
Tcl_Obj *objPtr;
@@ -377,9 +371,8 @@ TclCleanupChildren(
result = TCL_ERROR;
Tcl_DecrRefCount(objPtr);
Tcl_ResetResult(interp);
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "error reading stderr output file: %s",
- Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp, "error reading stderr output file: ",
+ Tcl_PosixError(interp), NULL);
} else if (count > 0) {
anyErrorInfo = 1;
Tcl_SetObjResult(interp, objPtr);
@@ -397,8 +390,7 @@ TclCleanupChildren(
*/
if ((abnormalExit != 0) && (anyErrorInfo == 0) && (interp != NULL)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "child process exited abnormally", -1));
+ Tcl_AppendResult(interp, "child process exited abnormally", NULL);
}
return result;
}
@@ -436,7 +428,7 @@ int
TclCreatePipeline(
Tcl_Interp *interp, /* Interpreter to use for error reporting. */
int argc, /* Number of entries in argv. */
- const char **argv, /* Array of strings describing commands in
+ CONST char **argv, /* Array of strings describing commands in
* pipeline plus I/O redirection with <, <<,
* >, etc. Argv[argc] must be NULL. */
Tcl_Pid **pidArrayPtr, /* Word at *pidArrayPtr gets filled in with
@@ -472,7 +464,7 @@ TclCreatePipeline(
* *pidPtr right now. */
int cmdCount; /* Count of number of distinct commands found
* in argc/argv. */
- const char *inputLiteral = NULL;
+ CONST char *inputLiteral = NULL;
/* If non-null, then this points to a string
* containing input data (specified via <<) to
* be piped to the first process in the
@@ -481,22 +473,22 @@ TclCreatePipeline(
* first process in pipeline (specified via <
* or <@). */
int inputClose = 0; /* If non-zero, then inputFile should be
- * closed when cleaning up. */
+ * closed when cleaning up. */
int inputRelease = 0;
TclFile outputFile = NULL; /* Writable file for output from last command
* in pipeline (could be file or pipe). NULL
* means use stdout. */
int outputClose = 0; /* If non-zero, then outputFile should be
- * closed when cleaning up. */
+ * closed when cleaning up. */
int outputRelease = 0;
TclFile errorFile = NULL; /* Writable file for error output from all
* commands in pipeline. NULL means use
* stderr. */
int errorClose = 0; /* If non-zero, then errorFile should be
- * closed when cleaning up. */
+ * closed when cleaning up. */
int errorRelease = 0;
- const char *p;
- const char *nextArg;
+ CONST char *p;
+ CONST char *nextArg;
int skip, lastBar, lastArg, i, j, atOK, flags, needCmd, errorToOutput = 0;
Tcl_DString execBuffer;
TclFile pipeIn;
@@ -547,10 +539,8 @@ TclCreatePipeline(
}
if (*p == '\0') {
if ((i == (lastBar + 1)) || (i == (argc - 1))) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "illegal use of | or |& in command", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
- "PIPESYNTAX", NULL);
+ Tcl_SetResult(interp, "illegal use of | or |& in command",
+ TCL_STATIC);
goto error;
}
}
@@ -575,11 +565,8 @@ TclCreatePipeline(
if (*inputLiteral == '\0') {
inputLiteral = ((i + 1) == argc) ? NULL : argv[i + 1];
if (inputLiteral == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "can't specify \"%s\" as last word in command",
- argv[i]));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
- "PIPESYNTAX", NULL);
+ Tcl_AppendResult(interp, "can't specify \"", argv[i],
+ "\" as last word in command", NULL);
goto error;
}
skip = 2;
@@ -686,11 +673,8 @@ TclCreatePipeline(
*/
if (i != argc-1) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "must specify \"%s\" as last word in command",
- argv[i]));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
- "PIPESYNTAX", NULL);
+ Tcl_AppendResult(interp, "must specify \"", argv[i],
+ "\" as last word in command", NULL);
goto error;
}
errorFile = outputFile;
@@ -707,12 +691,9 @@ TclCreatePipeline(
break;
default:
- /*
- * Got a command word, not a redirection.
- */
-
- needCmd = 0;
- break;
+ /* Got a command word, not a redirection */
+ needCmd = 0;
+ break;
}
if (skip != 0) {
@@ -725,14 +706,11 @@ TclCreatePipeline(
}
if (needCmd) {
- /*
- * We had a bar followed only by redirections.
- */
+ /* We had a bar followed only by redirections. */
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "illegal use of | or |& in command", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX",
- NULL);
+ Tcl_SetResult(interp,
+ "illegal use of | or |& in command",
+ TCL_STATIC);
goto error;
}
@@ -746,9 +724,9 @@ TclCreatePipeline(
inputFile = TclpCreateTempFile(inputLiteral);
if (inputFile == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "couldn't create input file for command: %s",
- Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp,
+ "couldn't create input file for command: ",
+ Tcl_PosixError(interp), NULL);
goto error;
}
inputClose = 1;
@@ -759,9 +737,9 @@ TclCreatePipeline(
*/
if (TclpCreatePipe(&inputFile, inPipePtr) == 0) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "couldn't create input pipe for command: %s",
- Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp,
+ "couldn't create input pipe for command: ",
+ Tcl_PosixError(interp), NULL);
goto error;
}
inputClose = 1;
@@ -788,9 +766,9 @@ TclCreatePipeline(
*/
if (TclpCreatePipe(outPipePtr, &outputFile) == 0) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "couldn't create output pipe for command: %s",
- Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp,
+ "couldn't create output pipe for command: ",
+ Tcl_PosixError(interp), NULL);
goto error;
}
outputClose = 1;
@@ -828,9 +806,9 @@ TclCreatePipeline(
errorFile = TclpCreateTempFile(NULL);
if (errorFile == NULL) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "couldn't create error file for command: %s",
- Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp,
+ "couldn't create error file for command: ",
+ Tcl_PosixError(interp), NULL);
goto error;
}
*errFilePtr = errorFile;
@@ -855,14 +833,14 @@ TclCreatePipeline(
*/
Tcl_ReapDetachedProcs();
- pidPtr = ckalloc(cmdCount * sizeof(Tcl_Pid));
+ pidPtr = (Tcl_Pid *) ckalloc((unsigned) (cmdCount * sizeof(Tcl_Pid)));
curInFile = inputFile;
for (i = 0; i < argc; i = lastArg + 1) {
int result, joinThisError;
Tcl_Pid pid;
- const char *oldName;
+ CONST char *oldName;
/*
* Convert the program name into native form.
@@ -901,8 +879,8 @@ TclCreatePipeline(
} else {
argv[lastArg] = NULL;
if (TclpCreatePipe(&pipeIn, &curOutFile) == 0) {
- Tcl_SetObjResult(interp, Tcl_ObjPrintf(
- "couldn't create pipe: %s", Tcl_PosixError(interp)));
+ Tcl_AppendResult(interp, "couldn't create pipe: ",
+ Tcl_PosixError(interp), NULL);
goto error;
}
}
@@ -1008,7 +986,7 @@ TclCreatePipeline(
Tcl_DetachPids(1, &pidPtr[i]);
}
}
- ckfree(pidPtr);
+ ckfree((char *) pidPtr);
}
numPids = -1;
goto cleanup;
@@ -1049,9 +1027,9 @@ TclCreatePipeline(
Tcl_Channel
Tcl_OpenCommandChannel(
Tcl_Interp *interp, /* Interpreter for error reporting. Can NOT be
- * NULL. */
+ * NULL. */
int argc, /* How many arguments. */
- const char **argv, /* Array of arguments for command pipe. */
+ CONST char **argv, /* Array of arguments for command pipe. */
int flags) /* Or'ed combination of TCL_STDIN, TCL_STDOUT,
* TCL_STDERR, and TCL_ENFORCE_MODE. */
{
@@ -1068,7 +1046,7 @@ Tcl_OpenCommandChannel(
errFilePtr = (flags & TCL_STDERR) ? &errFile : NULL;
numPids = TclCreatePipeline(interp, argc, argv, &pidPtr, inPipePtr,
- outPipePtr, errFilePtr);
+ outPipePtr, errFilePtr);
if (numPids < 0) {
goto error;
@@ -1081,19 +1059,13 @@ Tcl_OpenCommandChannel(
if (flags & TCL_ENFORCE_MODE) {
if ((flags & TCL_STDOUT) && (outPipe == NULL)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "can't read output from command:"
- " standard output was redirected", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
- "BADREDIRECT", NULL);
+ Tcl_AppendResult(interp, "can't read output from command:"
+ " standard output was redirected", NULL);
goto error;
}
if ((flags & TCL_STDIN) && (inPipe == NULL)) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "can't write input to command:"
- " standard input was redirected", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
- "BADREDIRECT", NULL);
+ Tcl_AppendResult(interp, "can't write input to command:"
+ " standard input was redirected", NULL);
goto error;
}
}
@@ -1101,10 +1073,9 @@ Tcl_OpenCommandChannel(
channel = TclpCreateCommandChannel(outPipe, inPipe, errFile,
numPids, pidPtr);
- if (channel == NULL) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "pipe for command could not be created", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "NOPIPE", NULL);
+ if (channel == (Tcl_Channel) NULL) {
+ Tcl_AppendResult(interp, "pipe for command could not be created",
+ NULL);
goto error;
}
return channel;
@@ -1112,7 +1083,7 @@ Tcl_OpenCommandChannel(
error:
if (numPids > 0) {
Tcl_DetachPids(numPids, pidPtr);
- ckfree(pidPtr);
+ ckfree((char *) pidPtr);
}
if (inPipe != NULL) {
TclpCloseFile(inPipe);