diff options
Diffstat (limited to 'generic/tclPipe.c')
-rw-r--r-- | generic/tclPipe.c | 186 |
1 files changed, 103 insertions, 83 deletions
diff --git a/generic/tclPipe.c b/generic/tclPipe.c index dd70e5e..5f59c38 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,23 +94,26 @@ 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_AppendResult(interp, "channel \"", Tcl_GetChannelName(chan), - "\" wasn't opened for ", - ((writing) ? "writing" : "reading"), NULL); + Tcl_AppendResult(interp, "channel \"", + Tcl_GetChannelName(chan), "\" wasn't opened for ", + ((writing) ? "writing" : "reading"), NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", + "BADCHAN", NULL); } - return NULL; - } + return NULL; + } *releasePtr = 1; if (writing) { /* @@ -118,10 +121,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') { @@ -143,13 +146,14 @@ FileForRedirect( Tcl_PosixError(interp), NULL); return NULL; } - *closePtr = 1; + *closePtr = 1; } return file; badLastArg: Tcl_AppendResult(interp, "can't specify \"", arg, "\" as last word in command", NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "SYNTAX", NULL); return NULL; } @@ -182,7 +186,7 @@ Tcl_DetachPids( Tcl_MutexLock(&pipeMutex); for (i = 0; i < numPids; i++) { - detPtr = (Detached *) ckalloc(sizeof(Detached)); + detPtr = ckalloc(sizeof(Detached)); detPtr->pid = pidPtr[i]; detPtr->nextPtr = detList; detList = detPtr; @@ -232,7 +236,7 @@ Tcl_ReapDetachedProcs(void) } else { prevPtr->nextPtr = detPtr->nextPtr; } - ckfree((char *) detPtr); + ckfree(detPtr); detPtr = nextPtr; } Tcl_MutexUnlock(&pipeMutex); @@ -272,8 +276,8 @@ TclCleanupChildren( int result = TCL_OK; int i, abnormalExit, anyErrorInfo; Tcl_Pid pid; - WAIT_STATUS_TYPE waitStatus; - CONST char *msg; + int waitStatus; + const char *msg; unsigned long resolvedPid; abnormalExit = 0; @@ -285,24 +289,24 @@ TclCleanupChildren( */ resolvedPid = TclpGetPid(pidPtr[i]); - pid = Tcl_WaitPid(pidPtr[i], (int *) &waitStatus, 0); + pid = Tcl_WaitPid(pidPtr[i], &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_AppendResult(interp, "error waiting for process to exit: ", - msg, NULL); - } + * 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; } @@ -319,32 +323,31 @@ TclCleanupChildren( result = TCL_ERROR; sprintf(msg1, "%lu", resolvedPid); if (WIFEXITED(waitStatus)) { - if (interp != (Tcl_Interp *) NULL) { - sprintf(msg2, "%lu", - (unsigned long) WEXITSTATUS(waitStatus)); - Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, NULL); - } + if (interp != NULL) { + sprintf(msg2, "%u", 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((int) (WTERMSIG(waitStatus))); - Tcl_SetErrorCode(interp, "CHILDKILLED", msg1, - Tcl_SignalId((int) (WTERMSIG(waitStatus))), p, - NULL); - Tcl_AppendResult(interp, "child killed: ", p, "\n", NULL); + p = Tcl_SignalMsg(WTERMSIG(waitStatus)); + Tcl_SetErrorCode(interp, "CHILDKILLED", msg1, + Tcl_SignalId(WTERMSIG(waitStatus)), 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, + p = Tcl_SignalMsg(WSTOPSIG(waitStatus)); + Tcl_SetErrorCode(interp, "CHILDSUSP", msg1, + Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL); + Tcl_AppendResult(interp, "child suspended: ", p, "\n", NULL); - Tcl_AppendResult(interp, "child suspended: ", p, "\n", - NULL); } else { - Tcl_AppendResult(interp, - "child wait status didn't make sense\n", NULL); - } + Tcl_AppendResult(interp, + "child wait status didn't make sense\n", NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", + "ODDWAITRESULT", msg1, NULL); + } } } } @@ -360,7 +363,7 @@ TclCleanupChildren( * Make sure we start at the beginning of the file. */ - if (interp != NULL) { + if (interp != NULL) { int count; Tcl_Obj *objPtr; @@ -428,7 +431,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 @@ -464,7 +467,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 @@ -473,22 +476,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; @@ -541,6 +544,8 @@ TclCreatePipeline( if ((i == (lastBar + 1)) || (i == (argc - 1))) { Tcl_SetResult(interp, "illegal use of | or |& in command", TCL_STATIC); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", + "PIPESYNTAX", NULL); goto error; } } @@ -567,6 +572,8 @@ TclCreatePipeline( if (inputLiteral == NULL) { Tcl_AppendResult(interp, "can't specify \"", argv[i], "\" as last word in command", NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", + "PIPESYNTAX", NULL); goto error; } skip = 2; @@ -675,6 +682,8 @@ TclCreatePipeline( if (i != argc-1) { Tcl_AppendResult(interp, "must specify \"", argv[i], "\" as last word in command", NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", + "PIPESYNTAX", NULL); goto error; } errorFile = outputFile; @@ -691,9 +700,12 @@ 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) { @@ -706,11 +718,14 @@ TclCreatePipeline( } if (needCmd) { - /* We had a bar followed only by redirections. */ + /* + * We had a bar followed only by redirections. + */ - Tcl_SetResult(interp, - "illegal use of | or |& in command", - TCL_STATIC); + Tcl_SetResult(interp, "illegal use of | or |& in command", + TCL_STATIC); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX", + NULL); goto error; } @@ -833,14 +848,14 @@ TclCreatePipeline( */ Tcl_ReapDetachedProcs(); - pidPtr = (Tcl_Pid *) ckalloc((unsigned) (cmdCount * sizeof(Tcl_Pid))); + pidPtr = ckalloc(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. @@ -986,7 +1001,7 @@ TclCreatePipeline( Tcl_DetachPids(1, &pidPtr[i]); } } - ckfree((char *) pidPtr); + ckfree(pidPtr); } numPids = -1; goto cleanup; @@ -1027,9 +1042,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. */ { @@ -1046,7 +1061,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; @@ -1061,11 +1076,15 @@ Tcl_OpenCommandChannel( if ((flags & TCL_STDOUT) && (outPipe == NULL)) { Tcl_AppendResult(interp, "can't read output from command:" " standard output was redirected", NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", + "BADREDIRECT", NULL); goto error; } if ((flags & TCL_STDIN) && (inPipe == NULL)) { Tcl_AppendResult(interp, "can't write input to command:" " standard input was redirected", NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", + "BADREDIRECT", NULL); goto error; } } @@ -1073,9 +1092,10 @@ Tcl_OpenCommandChannel( channel = TclpCreateCommandChannel(outPipe, inPipe, errFile, numPids, pidPtr); - if (channel == (Tcl_Channel) NULL) { - Tcl_AppendResult(interp, "pipe for command could not be created", - NULL); + if (channel == NULL) { + Tcl_AppendResult(interp, "pipe for command could not be created", + NULL); + Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "NOPIPE", NULL); goto error; } return channel; @@ -1083,7 +1103,7 @@ Tcl_OpenCommandChannel( error: if (numPids > 0) { Tcl_DetachPids(numPids, pidPtr); - ckfree((char *) pidPtr); + ckfree(pidPtr); } if (inPipe != NULL) { TclpCloseFile(inPipe); |