summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixPipe.c
diff options
context:
space:
mode:
Diffstat (limited to 'unix/tclUnixPipe.c')
-rw-r--r--unix/tclUnixPipe.c103
1 files changed, 56 insertions, 47 deletions
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c
index 871830c..b78715c 100644
--- a/unix/tclUnixPipe.c
+++ b/unix/tclUnixPipe.c
@@ -10,7 +10,7 @@
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclUnixPipe.c,v 1.2 1998/09/14 18:40:17 stanton Exp $
+ * RCS: @(#) $Id: tclUnixPipe.c,v 1.3 1999/04/16 00:48:05 stanton Exp $
*/
#include "tclInt.h"
@@ -128,12 +128,16 @@ TclpMakeFile(channel, direction)
TclFile
TclpOpenFile(fname, mode)
- char *fname; /* The name of the file to open. */
- int mode; /* In what mode to open the file? */
+ CONST char *fname; /* The name of the file to open. */
+ int mode; /* In what mode to open the file? */
{
int fd;
+ char *native;
+ Tcl_DString ds;
- fd = open(fname, mode, 0666);
+ native = Tcl_UtfToExternalDString(NULL, fname, -1, &ds);
+ fd = open(native, mode, 0666); /* INTL: Native. */
+ Tcl_DStringFree(&ds);
if (fd != -1) {
fcntl(fd, F_SETFD, FD_CLOEXEC);
@@ -175,36 +179,28 @@ TclpOpenFile(fname, mode)
*/
TclFile
-TclpCreateTempFile(contents, namePtr)
- char *contents; /* String to write into temp file, or NULL. */
- Tcl_DString *namePtr; /* If non-NULL, pointer to initialized
- * DString that is filled with the name of
- * the temp file that was created. */
+TclpCreateTempFile(contents)
+ CONST char *contents; /* String to write into temp file, or NULL. */
{
char fileName[L_tmpnam];
- TclFile file;
- size_t length = (contents == NULL) ? 0 : strlen(contents);
-
- tmpnam(fileName);
- file = TclpOpenFile(fileName, O_RDWR|O_CREAT|O_TRUNC);
- unlink(fileName);
-
- if ((file != NULL) && (length > 0)) {
- int fd = GetFd(file);
- while (1) {
- if (write(fd, contents, length) != -1) {
- break;
- } else if (errno != EINTR) {
- close(fd);
- return NULL;
- }
+ int fd;
+
+ tmpnam(fileName); /* INTL: Native. */
+ fd = open(fileName, O_RDWR|O_CREAT|O_TRUNC, 0666); /* INTL: Native. */
+ if (fd == -1) {
+ return NULL;
+ }
+ fcntl(fd, F_SETFD, FD_CLOEXEC);
+ unlink(fileName); /* INTL: Native. */
+
+ if (contents != NULL) {
+ if (write(fd, contents, strlen(contents)) == -1) {
+ close(fd);
+ return NULL;
}
lseek(fd, 0, SEEK_SET);
}
- if (namePtr != NULL) {
- Tcl_DStringAppend(namePtr, fileName, -1);
- }
- return file;
+ return MakeFile(fd);
}
/*
@@ -279,7 +275,7 @@ TclpCloseFile(file)
}
/*
- *----------------------------------------------------------------------
+ *---------------------------------------------------------------------------
*
* TclpCreateProcess --
*
@@ -292,14 +288,14 @@ TclpCloseFile(file)
*
* Results:
* The return value is TCL_ERROR and an error message is left in
- * interp->result if there was a problem creating the child
+ * the interp's result if there was a problem creating the child
* process. Otherwise, the return value is TCL_OK and *pidPtr is
* filled with the process id of the child process.
*
* Side effects:
* A process is created.
*
- *----------------------------------------------------------------------
+ *---------------------------------------------------------------------------
*/
/* ARGSUSED */
@@ -311,11 +307,11 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
* Error messages from the child process
* itself are sent to errorFile. */
int argc; /* Number of arguments in following array. */
- char **argv; /* Array of argument strings. argv[0]
- * contains the name of the executable
- * converted to native format (using the
- * Tcl_TranslateFileName call). Additional
- * arguments have not been converted. */
+ char **argv; /* Array of argument strings in UTF-8.
+ * argv[0] contains the name of the executable
+ * translated using Tcl_TranslateFileName
+ * call). Additional arguments have not been
+ * converted. */
TclFile inputFile; /* If non-NULL, gives the file to use as
* input for the child process. If inputFile
* file is not readable or is NULL, the child
@@ -336,7 +332,7 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
{
TclFile errPipeIn, errPipeOut;
int joinThisError, count, status, fd;
- char errSpace[200];
+ char errSpace[200 + TCL_INTEGER_SPACE];
int pid;
errPipeIn = NULL;
@@ -357,6 +353,10 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
joinThisError = (errorFile == outputFile);
pid = vfork();
if (pid == 0) {
+ Tcl_DString *dsArray;
+ char *oldArgv0;
+ int i;
+
fd = GetFd(errPipeOut);
/*
@@ -381,9 +381,19 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
*/
RestoreSignals();
- execvp(argv[0], &argv[0]);
+ for (i = 0; argv[i] != NULL; i++) {
+ /*
+ * How many arguments?
+ */
+ }
+ oldArgv0 = argv[0];
+ dsArray = (Tcl_DString *) ckalloc(i * sizeof(Tcl_DString));
+ for (i = 0; argv[i] != NULL; i++) {
+ argv[i] = Tcl_UtfToExternalDString(NULL, argv[i], -1, &dsArray[i]);
+ }
+ execvp(argv[0], argv); /* INTL: Native. */
sprintf(errSpace, "%dcouldn't execute \"%.150s\": ", errno,
- argv[0]);
+ oldArgv0);
write(fd, errSpace, (size_t) strlen(errSpace));
_exit(1);
}
@@ -621,7 +631,7 @@ TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
* the channel is closed or the processes
* are detached (in a background exec). */
{
- char channelName[20];
+ char channelName[16 + TCL_INTEGER_SPACE];
int channelId;
PipeState *statePtr = (PipeState *) ckalloc((unsigned) sizeof(PipeState));
int mode;
@@ -676,13 +686,13 @@ TclpCreateCommandChannel(readFile, writeFile, errorFile, numPids, pidPtr)
* This procedure is invoked in the generic implementation of a
* background "exec" (An exec when invoked with a terminating "&")
* to store a list of the PIDs for processes in a command pipeline
- * in interp->result and to detach the processes.
+ * in the interp's result and to detach the processes.
*
* Results:
* None.
*
* Side effects:
- * Modifies interp->result. Detaches processes.
+ * Modifies the interp's result. Detaches processes.
*
*----------------------------------------------------------------------
*/
@@ -695,7 +705,7 @@ TclGetAndDetachPids(interp, chan)
PipeState *pipePtr;
Tcl_ChannelType *chanTypePtr;
int i;
- char buf[20];
+ char buf[TCL_INTEGER_SPACE];
/*
* Punt if the channel is not a command channel.
@@ -708,7 +718,7 @@ TclGetAndDetachPids(interp, chan)
pipePtr = (PipeState *) Tcl_GetChannelInstanceData(chan);
for (i = 0; i < pipePtr->numPids; i++) {
- sprintf(buf, "%ld", TclpGetPid(pipePtr->pidPtr[i]));
+ TclFormatInt(buf, (long) TclpGetPid(pipePtr->pidPtr[i]));
Tcl_AppendElement(interp, buf);
Tcl_DetachPids(1, &(pipePtr->pidPtr[i]));
}
@@ -1129,8 +1139,7 @@ Tcl_PidObjCmd(dummy, interp, objc, objv)
if (objc == 1) {
Tcl_SetLongObj(Tcl_GetObjResult(interp), (long) getpid());
} else {
- chan = Tcl_GetChannel(interp, Tcl_GetStringFromObj(objv[1], NULL),
- NULL);
+ chan = Tcl_GetChannel(interp, Tcl_GetString(objv[1]), NULL);
if (chan == (Tcl_Channel) NULL) {
return TCL_ERROR;
}