summaryrefslogtreecommitdiffstats
path: root/generic/tclPipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'generic/tclPipe.c')
-rw-r--r--generic/tclPipe.c187
1 files changed, 88 insertions, 99 deletions
diff --git a/generic/tclPipe.c b/generic/tclPipe.c
index 082fcda..0afc584 100644
--- a/generic/tclPipe.c
+++ b/generic/tclPipe.c
@@ -1,4 +1,4 @@
-/*
+/*
* tclPipe.c --
*
* This file contains the generic portion of the command channel driver
@@ -9,7 +9,7 @@
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclPipe.c,v 1.13 2005/10/05 22:09:04 andreas_kupries Exp $
+ * RCS: @(#) $Id: tclPipe.c,v 1.14 2005/11/02 14:51:05 dkf Exp $
*/
#include "tclInt.h"
@@ -34,10 +34,10 @@ TCL_DECLARE_MUTEX(pipeMutex) /* Guard access to detList. */
* Declarations for local functions defined in this file:
*/
-static TclFile FileForRedirect _ANSI_ARGS_((Tcl_Interp *interp,
- CONST char *spec, int atOk, CONST char *arg,
- CONST char *nextArg, int flags, int *skipPtr,
- int *closePtr, int *releasePtr));
+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,34 +61,33 @@ static TclFile FileForRedirect _ANSI_ARGS_((Tcl_Interp *interp,
*/
static TclFile
-FileForRedirect(interp, spec, atOK, arg, nextArg, flags, skipPtr, closePtr,
- releasePtr)
- Tcl_Interp *interp; /* Intepreter to use for error reporting. */
- CONST char *spec; /* Points to character just after redirection
+FileForRedirect(
+ Tcl_Interp *interp, /* Intepreter to use for error reporting. */
+ CONST char *spec, /* Points to character just after redirection
* character. */
- int atOK; /* Non-zero means that '@' notation can be
+ 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
+ int flags, /* Flags to use for opening file or to specify
* mode for channel. */
- int *skipPtr; /* Filled with 1 if redirection target was in
+ int *skipPtr, /* Filled with 1 if redirection target was in
* spec, 2 if it was in nextArg. */
- int *closePtr; /* Filled with one if the caller should close
+ int *closePtr, /* Filled with one if the caller should close
* the file when done with it, zero
* otherwise. */
- int *releasePtr;
+ int *releasePtr)
{
int writing = (flags & O_WRONLY);
Tcl_Channel chan;
TclFile file;
*skipPtr = 1;
- if ((atOK != 0) && (*spec == '@')) {
+ if ((atOK != 0) && (*spec == '@')) {
spec++;
if (*spec == '\0') {
spec = nextArg;
@@ -105,7 +104,7 @@ FileForRedirect(interp, spec, atOK, arg, nextArg, flags, skipPtr, closePtr,
if (file == NULL) {
Tcl_AppendResult(interp, "channel \"", Tcl_GetChannelName(chan),
"\" wasn't opened for ",
- ((writing) ? "writing" : "reading"), (char *) NULL);
+ ((writing) ? "writing" : "reading"), NULL);
return NULL;
}
*releasePtr = 1;
@@ -138,7 +137,7 @@ FileForRedirect(interp, spec, atOK, arg, nextArg, flags, skipPtr, closePtr,
if (file == NULL) {
Tcl_AppendResult(interp, "couldn't ",
((writing) ? "write" : "read"), " file \"", spec, "\": ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
return NULL;
}
*closePtr = 1;
@@ -147,7 +146,7 @@ FileForRedirect(interp, spec, atOK, arg, nextArg, flags, skipPtr, closePtr,
badLastArg:
Tcl_AppendResult(interp, "can't specify \"", arg,
- "\" as last word in command", (char *) NULL);
+ "\" as last word in command", NULL);
return NULL;
}
@@ -170,10 +169,10 @@ FileForRedirect(interp, spec, atOK, arg, nextArg, flags, skipPtr, closePtr,
*/
void
-Tcl_DetachPids(numPids, pidPtr)
- int numPids; /* Number of pids to detach: gives size of
+Tcl_DetachPids(
+ int numPids, /* Number of pids to detach: gives size of
* array pointed to by pidPtr. */
- Tcl_Pid *pidPtr; /* Array of pids to detach. */
+ Tcl_Pid *pidPtr) /* Array of pids to detach. */
{
register Detached *detPtr;
int i;
@@ -209,7 +208,7 @@ Tcl_DetachPids(numPids, pidPtr)
*/
void
-Tcl_ReapDetachedProcs()
+Tcl_ReapDetachedProcs(void)
{
register Detached *detPtr;
Detached *nextPtr, *prevPtr;
@@ -259,11 +258,11 @@ Tcl_ReapDetachedProcs()
*/
int
-TclCleanupChildren(interp, numPids, pidPtr, errorChan)
- Tcl_Interp *interp; /* Used for error messages. */
- int numPids; /* Number of entries in pidPtr array. */
- Tcl_Pid *pidPtr; /* Array of process ids of children. */
- Tcl_Channel errorChan; /* Channel for file containing stderr output
+TclCleanupChildren(
+ Tcl_Interp *interp, /* Used for error messages. */
+ int numPids, /* Number of entries in pidPtr array. */
+ Tcl_Pid *pidPtr, /* Array of process ids of children. */
+ Tcl_Channel errorChan) /* Channel for file containing stderr output
* from pipeline. NULL means there isn't any
* stderr output. */
{
@@ -286,7 +285,7 @@ TclCleanupChildren(interp, numPids, pidPtr, errorChan)
pid = Tcl_WaitPid(pidPtr[i], (int *) &waitStatus, 0);
if (pid == (Tcl_Pid) -1) {
result = TCL_ERROR;
- if (interp != (Tcl_Interp *) NULL) {
+ if (interp != NULL) {
msg = Tcl_PosixError(interp);
if (errno == ECHILD) {
/*
@@ -299,7 +298,7 @@ TclCleanupChildren(interp, numPids, pidPtr, errorChan)
"child process lost (is SIGCHLD ignored or trapped?)";
}
Tcl_AppendResult(interp, "error waiting for process to exit: ",
- msg, (char *) NULL);
+ msg, NULL);
}
continue;
}
@@ -319,37 +318,28 @@ TclCleanupChildren(interp, numPids, pidPtr, errorChan)
if (WIFEXITED(waitStatus)) {
if (interp != (Tcl_Interp *) NULL) {
sprintf(msg2, "%hu", WEXITSTATUS(waitStatus));
- Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2,
- (char *) NULL);
+ Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, NULL);
}
abnormalExit = 1;
- } else if (WIFSIGNALED(waitStatus)) {
- if (interp != (Tcl_Interp *) NULL) {
- CONST char *p;
-
+ } else if (interp != NULL) {
+ CONST char *p;
+
+ if (WIFSIGNALED(waitStatus)) {
p = Tcl_SignalMsg((int) (WTERMSIG(waitStatus)));
Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
Tcl_SignalId((int) (WTERMSIG(waitStatus))), p,
- (char *) NULL);
- Tcl_AppendResult(interp, "child killed: ", p, "\n",
- (char *) NULL);
- }
- } else if (WIFSTOPPED(waitStatus)) {
- if (interp != (Tcl_Interp *) NULL) {
- CONST char *p;
-
+ NULL);
+ Tcl_AppendResult(interp, "child killed: ", p, "\n", NULL);
+ } else if (WIFSTOPPED(waitStatus)) {
p = Tcl_SignalMsg((int) (WSTOPSIG(waitStatus)));
Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
- Tcl_SignalId((int) (WSTOPSIG(waitStatus))),
- p, (char *) NULL);
+ Tcl_SignalId((int) (WSTOPSIG(waitStatus))), p,
+ NULL);
Tcl_AppendResult(interp, "child suspended: ", p, "\n",
- (char *) NULL);
- }
- } else {
- if (interp != (Tcl_Interp *) NULL) {
+ NULL);
+ } else {
Tcl_AppendResult(interp,
- "child wait status didn't make sense\n",
- (char *) NULL);
+ "child wait status didn't make sense\n", NULL);
}
}
}
@@ -369,7 +359,7 @@ TclCleanupChildren(interp, numPids, pidPtr, errorChan)
if (interp != NULL) {
int count;
Tcl_Obj *objPtr;
-
+
Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET);
objPtr = Tcl_NewObj();
count = Tcl_ReadChars(errorChan, objPtr, -1, 0);
@@ -396,8 +386,7 @@ TclCleanupChildren(interp, numPids, pidPtr, errorChan)
*/
if ((abnormalExit != 0) && (anyErrorInfo == 0) && (interp != NULL)) {
- Tcl_AppendResult(interp, "child process exited abnormally",
- (char *) NULL);
+ Tcl_AppendResult(interp, "child process exited abnormally", NULL);
}
return result;
}
@@ -432,30 +421,29 @@ TclCleanupChildren(interp, numPids, pidPtr, errorChan)
*/
int
-TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
- outPipePtr, errFilePtr)
- 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
+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
* pipeline plus I/O redirection with <, <<,
* >, etc. Argv[argc] must be NULL. */
- Tcl_Pid **pidArrayPtr; /* Word at *pidArrayPtr gets filled in with
+ Tcl_Pid **pidArrayPtr, /* Word at *pidArrayPtr gets filled in with
* address of array of pids for processes in
* pipeline (first pid is first process in
* pipeline). */
- TclFile *inPipePtr; /* If non-NULL, input to the pipeline comes
+ TclFile *inPipePtr, /* If non-NULL, input to the pipeline comes
* from a pipe (unless overridden by
* redirection in the command). The file id
* with which to write to this pipe is stored
* at *inPipePtr. NULL means command specified
* its own input source. */
- TclFile *outPipePtr; /* If non-NULL, output to the pipeline goes to
+ TclFile *outPipePtr, /* If non-NULL, output to the pipeline goes to
* a pipe, unless overriden by redirection in
* the command. The file id with which to read
* frome this pipe is stored at *outPipePtr.
* NULL means command specified its own output
* sink. */
- TclFile *errFilePtr; /* If non-NULL, all stderr output from the
+ TclFile *errFilePtr) /* If non-NULL, all stderr output from the
* pipeline will go to a temporary file
* created here, and a descriptor to read the
* file will be left at *errFilePtr. The file
@@ -514,7 +502,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
}
Tcl_DStringInit(&execBuffer);
-
+
pipeIn = NULL;
curInFile = NULL;
curOutFile = NULL;
@@ -572,7 +560,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
inputLiteral = ((i + 1) == argc) ? NULL : argv[i + 1];
if (inputLiteral == NULL) {
Tcl_AppendResult(interp, "can't specify \"", argv[i],
- "\" as last word in command", (char *) NULL);
+ "\" as last word in command", NULL);
goto error;
}
skip = 2;
@@ -680,7 +668,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
if (i != argc-1) {
Tcl_AppendResult(interp, "must specify \"", argv[i],
- "\" as last word in command", (char *) NULL);
+ "\" as last word in command", NULL);
goto error;
}
errorFile = outputFile;
@@ -688,7 +676,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
skip = 1;
} else {
nextArg = ((i + 1) == argc) ? NULL : argv[i + 1];
- errorFile = FileForRedirect(interp, p, atOK, argv[i],
+ errorFile = FileForRedirect(interp, p, atOK, argv[i],
nextArg, flags, &skip, &errorClose, &errorRelease);
if (errorFile == NULL) {
goto error;
@@ -718,7 +706,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
if (inputFile == NULL) {
Tcl_AppendResult(interp,
"couldn't create input file for command: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
goto error;
}
inputClose = 1;
@@ -729,9 +717,9 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
*/
if (TclpCreatePipe(&inputFile, inPipePtr) == 0) {
- Tcl_AppendResult(interp,
+ Tcl_AppendResult(interp,
"couldn't create input pipe for command: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
goto error;
}
inputClose = 1;
@@ -758,9 +746,9 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
*/
if (TclpCreatePipe(outPipePtr, &outputFile) == 0) {
- Tcl_AppendResult(interp,
+ Tcl_AppendResult(interp,
"couldn't create output pipe for command: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
goto error;
}
outputClose = 1;
@@ -800,7 +788,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
if (errorFile == NULL) {
Tcl_AppendResult(interp,
"couldn't create error file for command: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
goto error;
}
*errFilePtr = errorFile;
@@ -818,7 +806,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
}
}
}
-
+
/*
* Scan through the argc array, creating a process for each group of
* arguments between the "|" characters.
@@ -829,13 +817,13 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
curInFile = inputFile;
- for (i = 0; i < argc; i = lastArg + 1) {
+ for (i = 0; i < argc; i = lastArg + 1) {
int result, joinThisError;
Tcl_Pid pid;
CONST char *oldName;
/*
- * Convert the program name into native form.
+ * Convert the program name into native form.
*/
if (Tcl_TranslateFileName(interp, argv[i], &execBuffer) == NULL) {
@@ -848,14 +836,15 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
joinThisError = 0;
for (lastArg = i; lastArg < argc; lastArg++) {
- if (argv[lastArg][0] == '|') {
- if (argv[lastArg][1] == '\0') {
- break;
- }
- if ((argv[lastArg][1] == '&') && (argv[lastArg][2] == '\0')) {
- joinThisError = 1;
- break;
- }
+ if (argv[lastArg][0] != '|') {
+ continue;
+ }
+ if (argv[lastArg][1] == '\0') {
+ break;
+ }
+ if ((argv[lastArg][1] == '&') && (argv[lastArg][2] == '\0')) {
+ joinThisError = 1;
+ break;
}
}
@@ -871,7 +860,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
argv[lastArg] = NULL;
if (TclpCreatePipe(&pipeIn, &curOutFile) == 0) {
Tcl_AppendResult(interp, "couldn't create pipe: ",
- Tcl_PosixError(interp), (char *) NULL);
+ Tcl_PosixError(interp), NULL);
goto error;
}
}
@@ -886,7 +875,7 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
* Restore argv[i], since a caller wouldn't expect the contents of
* argv to be modified.
*/
-
+
oldName = argv[i];
argv[i] = Tcl_DStringValue(&execBuffer);
result = TclpCreateProcess(interp, lastArg - i, argv + i,
@@ -1016,12 +1005,12 @@ TclCreatePipeline(interp, argc, argv, pidArrayPtr, inPipePtr,
*/
Tcl_Channel
-Tcl_OpenCommandChannel(interp, argc, argv, flags)
- Tcl_Interp *interp; /* Interpreter for error reporting. Can NOT be
+Tcl_OpenCommandChannel(
+ Tcl_Interp *interp, /* Interpreter for error reporting. Can NOT be
* NULL. */
- int argc; /* How many arguments. */
- CONST char **argv; /* Array of arguments for command pipe. */
- int flags; /* Or'ed combination of TCL_STDIN, TCL_STDOUT,
+ int argc, /* How many arguments. */
+ 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. */
{
TclFile *inPipePtr, *outPipePtr, *errFilePtr;
@@ -1035,7 +1024,7 @@ Tcl_OpenCommandChannel(interp, argc, argv, flags)
inPipePtr = (flags & TCL_STDIN) ? &inPipe : NULL;
outPipePtr = (flags & TCL_STDOUT) ? &outPipe : NULL;
errFilePtr = (flags & TCL_STDERR) ? &errFile : NULL;
-
+
numPids = TclCreatePipeline(interp, argc, argv, &pidPtr, inPipePtr,
outPipePtr, errFilePtr);
@@ -1051,22 +1040,22 @@ Tcl_OpenCommandChannel(interp, argc, argv, flags)
if (flags & TCL_ENFORCE_MODE) {
if ((flags & TCL_STDOUT) && (outPipe == NULL)) {
Tcl_AppendResult(interp, "can't read output from command:",
- " standard output was redirected", (char *) NULL);
+ " standard output was redirected", NULL);
goto error;
}
if ((flags & TCL_STDIN) && (inPipe == NULL)) {
Tcl_AppendResult(interp, "can't write input to command:",
- " standard input was redirected", (char *) NULL);
+ " standard input was redirected", NULL);
goto error;
}
}
-
+
channel = TclpCreateCommandChannel(outPipe, inPipe, errFile,
numPids, pidPtr);
if (channel == (Tcl_Channel) NULL) {
Tcl_AppendResult(interp, "pipe for command could not be created",
- (char *) NULL);
+ NULL);
goto error;
}
return channel;