summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorbde <bde@FreeBSD.org>1994-12-12 01:15:01 +0000
committerbde <bde@FreeBSD.org>1994-12-12 01:15:01 +0000
commit85651f85dafb2ae149a7f6acb6589318c8639e00 (patch)
treee96f69c1b39623a3b0b7378c4a340b5ecd7604c7 /lib/libc
parenta7b72cfd8402f77ec8d1bfc7e289048ef3e5b191 (diff)
downloadFreeBSD-src-85651f85dafb2ae149a7f6acb6589318c8639e00.zip
FreeBSD-src-85651f85dafb2ae149a7f6acb6589318c8639e00.tar.gz
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.
Diffstat (limited to 'lib/libc')
-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 2f7eadd..6af8868 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)
OpenPOWER on IntegriCloud