aboutsummaryrefslogtreecommitdiff
path: root/lib/libc/gen/exec.c
diff options
context:
space:
mode:
authorBruce Evans <bde@FreeBSD.org>1994-12-12 01:15:01 +0000
committerBruce Evans <bde@FreeBSD.org>1994-12-12 01:15:01 +0000
commita2c0622293a8eb2488613d17ad149d5899376ad3 (patch)
treee96f69c1b39623a3b0b7378c4a340b5ecd7604c7 /lib/libc/gen/exec.c
parent4ecd9d4bfadcde77cf638618d2da6fbed3d459fe (diff)
downloadsrc-a2c0622293a8eb2488613d17ad149d5899376ad3.tar.gz
src-a2c0622293a8eb2488613d17ad149d5899376ad3.zip
Fix execl[e]. Multiple execle's failed because of bogus caching of the
pointer returned by realloc(). All callers free the pointer if the execve fails. Nuke the caching. This essentially restores buildargv() to the 1.1.5 version. Also fix a memory leak if realloc() fails. Also nuke similar but non-broken caching in execvp(). malloc() should be efficient enough.
Notes
Notes: svn path=/head/; revision=5070
Diffstat (limited to 'lib/libc/gen/exec.c')
-rw-r--r--lib/libc/gen/exec.c30
1 files changed, 14 insertions, 16 deletions
diff --git a/lib/libc/gen/exec.c b/lib/libc/gen/exec.c
index 2f7eadd67603..6af8868cd71b 100644
--- a/lib/libc/gen/exec.c
+++ b/lib/libc/gen/exec.c
@@ -58,19 +58,20 @@ buildargv(ap, arg, envpp)
const char *arg;
char ***envpp;
{
- static int memsize;
- static char **argv;
- register int off;
+ register char **argv, **nargv;
+ register int memsize, off;
argv = NULL;
- for (off = 0;; ++off) {
+ for (off = memsize = 0;; ++off) {
if (off >= memsize) {
memsize += 50; /* Starts out at 0. */
memsize *= 2; /* Ramp up fast. */
- if (!(argv = realloc(argv, memsize * sizeof(char *)))) {
- memsize = 0;
+ nargv = realloc(argv, memsize * sizeof(char *));
+ if (nargv == NULL) {
+ free(argv);
return (NULL);
}
+ argv = nargv;
if (off == 0) {
argv[0] = (char *)arg;
off = 1;
@@ -183,8 +184,7 @@ execvp(name, argv)
const char *name;
char * const *argv;
{
- static int memsize;
- static char **memp;
+ char **memp;
register int cnt, lp, ln;
register char *p;
int eacces, etxtbsy;
@@ -240,18 +240,16 @@ retry: (void)execve(bp, argv, environ);
case ENOENT:
break;
case ENOEXEC:
- for (cnt = 0; argv[cnt]; ++cnt);
- if ((cnt + 2) * sizeof(char *) > memsize) {
- memsize = (cnt + 2) * sizeof(char *);
- if ((memp = realloc(memp, memsize)) == NULL) {
- memsize = 0;
- goto done;
- }
- }
+ for (cnt = 0; argv[cnt]; ++cnt)
+ ;
+ memp = malloc((cnt + 2) * sizeof(char *));
+ if (memp == NULL)
+ goto done;
memp[0] = "sh";
memp[1] = bp;
bcopy(argv + 1, memp + 2, cnt * sizeof(char *));
(void)execve(_PATH_BSHELL, memp, environ);
+ free(memp);
goto done;
case ETXTBSY:
if (etxtbsy < 3)