brl-vgr Bug Report
ron at BRL.ARPA
ron at BRL.ARPA
Tue Oct 14 08:53:07 AEST 1986
Subject: Short summary of the problem
Index: lib/libc/gen/getusershell.c 4.3BSD
Description:
Setusershell and endusershell are ineffective and
sometimes dump core.
Repeat-By:
Do a few getusershell calls with an interspersed setusershell
and/or endusershell.
Fix:
The problem is that getusershell.c is horrible. Endusershell
may free things that have not been malloced. There are two
separate instances of the shells pointer one local to getusershell.
Setusershell sets a different one than the one getusershell uses.
A fixed up version follows:
/*
* Copyright (c) 1985 Regents of the University of California.
* All rights reserved. The Berkeley software License Agreement
* specifies the terms and conditions for redistribution.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)getusershell.c 5.2 (Berkeley) 3/9/86";
#endif LIBC_SCCS and not lint
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <ctype.h>
#include <stdio.h>
#define SHELLS "/etc/shells"
/*
* Do not add local shells here. They should be added in /etc/shells
*/
static char *okshells[] =
{ "/bin/sh", "/bin/csh", 0 };
static int inprogress;
static char **shells, *strings;
extern char **initshells();
/*
* Get a list of shells from SHELLS, if it exists.
*/
char *
getusershell()
{
char *ret;
static char **shp;
if (!inprogress)
shp = initshells();
ret = *shp;
if (*shp != NULL)
shp++;
return (ret);
}
endusershell()
{
if (shells != NULL)
free((char *)shells);
shells = NULL;
if (strings != NULL)
free(strings);
strings = NULL;
inprogress = 0;
}
setusershell()
{
endusershell();
}
static char **
initshells()
{
register char **sp, *cp;
register FILE *fp;
struct stat statb;
extern char *malloc(), *calloc();
inprogress = 1;
if (shells != NULL)
free((char *)shells);
shells = NULL;
if (strings != NULL)
free(strings);
strings = NULL;
if ((fp = fopen(SHELLS, "r")) == (FILE *)0)
return(okshells);
if (fstat(fileno(fp), &statb) == -1) {
(void)fclose(fp);
return(okshells);
}
if ((strings = malloc((unsigned)statb.st_size)) == NULL) {
(void)fclose(fp);
return(okshells);
}
shells = (char **)calloc((unsigned)statb.st_size / 3, sizeof (char *));
if (shells == NULL) {
(void)fclose(fp);
free(strings);
strings = NULL;
return(okshells);
}
sp = shells;
cp = strings;
while (fgets(cp, MAXPATHLEN + 1, fp) != NULL) {
while (!isspace(*cp) != '/' && *cp != '\0')
cp++;
if (*cp == '#' || *cp == '\0')
continue;
*sp++ = cp;
while (!isspace(*cp) && *cp != '#' && *cp != '\0')
cp++;
*cp++ = '\0';
}
*sp = (char *)0;
(void)fclose(fp);
return (shells);
}
More information about the Comp.unix.wizards
mailing list