1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-12-24 17:51:17 +03:00
1998-06-08 13:34  Ulrich Drepper  <drepper@cygnus.com>

	* elf/sprof.c: Implement call graph profiling.

	* sysdeps/generic/getenv.c: Optimize to use strncmp less often.

1998-06-07  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* pwd/fgetpwent_r.c (__fgetpwent_r): Correct buffer overflow fix.
	* grp/fgetgrent_r.c (__fgetgrent_r): Likewise.
	* shadow/fgetspent_r.c (__fgetspent_r): Likewise.
	Noticed by Jake Garver <garver@valkyrie.net>.

1998-06-07  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* libio/genops.c (__underflow): Read character from read pointer
	as unsigned.
	(__uflow): Likewise.
This commit is contained in:
Ulrich Drepper
1998-06-08 13:37:25 +00:00
parent c0fb8a563c
commit 31f7410f5c
7 changed files with 291 additions and 35 deletions

View File

@@ -1,4 +1,4 @@
/* Copyright (C) 1991, 1992, 1994, 1996 Free Software Foundation, Inc.
/* Copyright (C) 1991, 1992, 1994, 1996, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -16,7 +16,9 @@
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#include <endian.h>
#include <errno.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -25,20 +27,74 @@
#define __environ environ
#endif
/* Return the value of the environment variable NAME. */
/* Return the value of the environment variable NAME. This implementation
is tuned a bit in that it assumes no environment variable has an empty
name which of course should always be true. We have a special case for
one character names so that for the general case we can assume at least
two characters which we can access. By doing this we can avoid using the
`strncmp' most of the time. */
char *
getenv (name)
const char *name;
{
const size_t len = strlen (name);
char **ep;
uint16_t name_start;
if (__environ == NULL)
if (__environ == NULL || name[0] == '\0')
return NULL;
for (ep = __environ; *ep != NULL; ++ep)
if (!strncmp (*ep, name, len) && (*ep)[len] == '=')
return &(*ep)[len + 1];
if (name[1] == '\0')
{
/* The name of the variable consists of only one character. Therefore
the first two characters of the environment entry are this character
and a '=' character. */
#if __BYTE_ORDER == __LITTLE_ENDIAN
name_start = ('=' << 8) | *(const unsigned char *) name;
#else
# if __BYTE_ORDER == __BIG_ENDIAN
name_start = '=' | ((*(const unsigned char *) name) << 8);
# else
#error "Funny byte order."
# endif
#endif
for (ep = __environ; *ep != NULL; ++ep)
{
#if _STRING_ARCH_unaligned
uint16_t ep_start = *(uint16_t *) *ep;
#else
uint16_t ep_start = (((unsigned char *) *ep)[0]
| (((unsigned char *) *ep)[1] << 8));
#endif
if (name_start == ep_start)
return &(*ep)[2];
}
}
else
{
#if _STRING_ARCH_unaligned
name_start = *(const uint16_t *) name;
#else
name_start = (((const unsigned char *) name)[0]
| (((const unsigned char *) name)[1] << 8));
#endif
len -= 2;
name += 2;
for (ep = __environ; *ep != NULL; ++ep)
{
#if _STRING_ARCH_unaligned
uint16_t ep_start = *(uint16_t *) *ep;
#else
uint16_t ep_start = (((unsigned char *) *ep)[0]
| (((unsigned char *) *ep)[1] << 8));
#endif
if (name_start == ep_start && !strncmp (*ep + 2, name, len)
&& (*ep)[len + 2] == '=')
return &(*ep)[len + 3];
}
}
return NULL;
}