summaryrefslogtreecommitdiffstats
path: root/unix/tclUnixPipe.c
diff options
context:
space:
mode:
authorhobbs <hobbs>1999-10-13 00:32:49 (GMT)
committerhobbs <hobbs>1999-10-13 00:32:49 (GMT)
commit04ea820b91d40ed30eed4b56ad2f4a12a552cb3f (patch)
tree6644d69c8f99aa752688a9e211685986541523fb /unix/tclUnixPipe.c
parent67604b787a8c97063919f609033bc87ac4d62995 (diff)
downloadtcl-04ea820b91d40ed30eed4b56ad2f4a12a552cb3f.zip
tcl-04ea820b91d40ed30eed4b56ad2f4a12a552cb3f.tar.gz
tcl-04ea820b91d40ed30eed4b56ad2f4a12a552cb3f.tar.bz2
* unix/Makefile.in: purify has to use -best-effort to instrument
* unix/tclAppInit.c: identified potential mem leak when compiling tcltest (not critical) * unix/tclUnixPipe.c: fixed mem leak in TclpCreateProcess when doing alloc between vfork and execvp. * unix/tclUnixTest.c: fixed mem leak in findexecutable test command
Diffstat (limited to 'unix/tclUnixPipe.c')
-rw-r--r--unix/tclUnixPipe.c49
1 files changed, 28 insertions, 21 deletions
diff --git a/unix/tclUnixPipe.c b/unix/tclUnixPipe.c
index b78715c..f140555 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.3 1999/04/16 00:48:05 stanton Exp $
+ * RCS: @(#) $Id: tclUnixPipe.c,v 1.4 1999/10/13 00:32:50 hobbs Exp $
*/
#include "tclInt.h"
@@ -333,7 +333,9 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
TclFile errPipeIn, errPipeOut;
int joinThisError, count, status, fd;
char errSpace[200 + TCL_INTEGER_SPACE];
- int pid;
+ Tcl_DString *dsArray;
+ char **newArgv;
+ int pid, i;
errPipeIn = NULL;
errPipeOut = NULL;
@@ -350,13 +352,20 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
goto error;
}
+ /*
+ * We need to allocate and convert this before the (v)fork
+ * so it is properly deallocated later
+ */
+ dsArray = (Tcl_DString *) ckalloc(argc * sizeof(Tcl_DString));
+ newArgv = (char **) ckalloc((argc+1) * sizeof(char *));
+ newArgv[argc] = NULL;
+ for (i = 0; i < argc; i++) {
+ newArgv[i] = Tcl_UtfToExternalDString(NULL, argv[i], -1, &dsArray[i]);
+ }
+
joinThisError = (errorFile == outputFile);
pid = vfork();
if (pid == 0) {
- Tcl_DString *dsArray;
- char *oldArgv0;
- int i;
-
fd = GetFd(errPipeOut);
/*
@@ -370,8 +379,7 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
((dup2(1,2) == -1) ||
(fcntl(2, F_SETFD, 0) != 0)))) {
sprintf(errSpace,
- "%dforked process couldn't set up input/output: ",
- errno);
+ "%dforked process couldn't set up input/output: ", errno);
write(fd, errSpace, (size_t) strlen(errSpace));
_exit(1);
}
@@ -381,22 +389,21 @@ TclpCreateProcess(interp, argc, argv, inputFile, outputFile, errorFile,
*/
RestoreSignals();
- 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,
- oldArgv0);
+ execvp(newArgv[0], newArgv); /* INTL: Native. */
+ sprintf(errSpace, "%dcouldn't execute \"%.150s\": ", errno, argv[0]);
write(fd, errSpace, (size_t) strlen(errSpace));
_exit(1);
}
+
+ /*
+ * Free the mem we used for the fork
+ */
+ for (i = 0; i < argc; i++) {
+ Tcl_DStringFree(&dsArray[i]);
+ }
+ ckfree((char *) dsArray);
+ ckfree((char *) newArgv);
+
if (pid == -1) {
Tcl_AppendResult(interp, "couldn't fork child process: ",
Tcl_PosixError(interp), (char *) NULL);