+1999-06-28 Ulrich Drepper <drepper@cygnus.com>
+
+ * sysdeps/libm-ieee754/e_gamma_r.c: Initialize *signgamp for NaN
+ returns.
+ * sysdeps/libm-ieee754/e_gammaf_r.c: Likewise.
+ * sysdeps/libm-ieee754/e_gammal_r.c: Likewise.
+ Reported by John Reiser <jreiser@BitWagon.com> [PR libc/1185].
+
1999-06-28 Andreas Jaeger <aj@arthur.rhein-neckar.de>
* manual/string.texi (Copying and Concatenation): Mention that
#include <stdio.h>
#include <ctype.h>
#include <string.h>
+#include <libintl.h>
int __ivaliduser __P ((FILE *, u_int32_t, const char *, const char *));
hstbuflen = 1024;
tmphstbuf = __alloca (hstbuflen);
while (__gethostbyname_r (*ahost, &hostbuf, tmphstbuf, hstbuflen,
- &hp, &herr) < 0)
+ &hp, &herr) != 0
+ || hp == NULL)
if (herr != NETDB_INTERNAL || errno != ERANGE)
{
__set_h_errno (herr);
buffer = __alloca (buflen);
while (__gethostbyname_r (rhost, &hostbuf, buffer, buflen, &hp, &herr)
- < 0)
+ != 0
+ || hp == NULL)
if (herr != NETDB_INTERNAL || errno != ERANGE)
return -1;
else
char *buffer = __alloca (buflen);
uid_t uid;
- if (__getpwnam_r (luser, &pwdbuf, buffer, buflen, &pwd))
+ if (__getpwnam_r (luser, &pwdbuf, buffer, buflen, &pwd) != 0
+ || pwd == NULL)
return -1;
dirlen = strlen (pwd->pw_dir);
buffer = __alloca (buflen);
save_errno = errno;
while (__gethostbyname_r (lhost, &hostbuf, buffer, buflen, &hp, &herr)
- < 0)
+ != 0)
if (herr != NETDB_INTERNAL || errno != ERANGE)
return (0);
else {
/* Skip lines that are too long. */
if (strchr (p, '\n') == NULL) {
- int ch = getc (hostf);
+ int ch = getc_unlocked (hostf);
while (ch != '\n' && ch != EOF)
- ch = getc (hostf);
+ ch = getc_unlocked (hostf);
continue;
}
hstbuflen = 1024;
hsttmpbuf = __alloca (hstbuflen);
while (__gethostbyname_r (*ahost, &hostbuf, hsttmpbuf, hstbuflen,
- &hp, &herr) < 0)
+ &hp, &herr) != 0
+ || hp == NULL)
if (herr != NETDB_INTERNAL || errno != ERANGE)
{
__set_h_errno (herr);
@comment SVID, Unix98
@deftypefun {char *} ecvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
The function @code{ecvt} converts the floating-point number @var{value}
-to a string with at most @var{ndigit} decimal digits.
-The returned string contains no decimal point or sign. The first
-digit of the string is non-zero (unless @var{value} is actually zero)
-and the last digit is rounded to nearest. @var{decpt} is set to the
+to a string with at most @var{ndigit} decimal digits. The
+returned string contains no decimal point or sign. The first digit of
+the string is non-zero (unless @var{value} is actually zero) and the
+last digit is rounded to nearest. @code{*@var{decpt}} is set to the
index in the string of the first digit after the decimal point.
-@var{neg} is set to a nonzero value if @var{value} is negative, zero
-otherwise.
+@code{*@var{neg}} is set to a nonzero value if @var{value} is negative,
+zero otherwise.
+
+If @var{ndigit} decimal digits would exceed the precision of a
+@code{double} it is reduced to a system-specific value.
The returned string is statically allocated and overwritten by each call
to @code{ecvt}.
-If @var{value} is zero, it's implementation defined whether @var{decpt} is
-@code{0} or @code{1}.
+If @var{value} is zero, it is implementation defined whether
+@code{*@var{decpt}} is @code{0} or @code{1}.
-For example: @code{ecvt (12.3, 5, &decpt, &neg)} returns @code{"12300"}
-and sets @var{decpt} to @code{2} and @var{neg} to @code{0}.
+For example: @code{ecvt (12.3, 5, &d, &n)} returns @code{"12300"}
+and sets @var{d} to @code{2} and @var{n} to @code{0}.
@end deftypefun
@comment stdlib.h
@comment SVID, Unix98
-@deftypefun {char *} fcvt (double @var{value}, int @var{ndigit}, int @var{decpt}, int *@var{neg})
+@deftypefun {char *} fcvt (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
The function @code{fcvt} is like @code{ecvt}, but @var{ndigit} specifies
the number of digits after the decimal point. If @var{ndigit} is less
than zero, @var{value} is rounded to the @math{@var{ndigit}+1}'th place to the
negative and larger than the number of digits to the left of the decimal
point in @var{value}, @var{value} will be rounded to one significant digit.
+If @var{ndigit} decimal digits would exceed the precision of a
+@code{double} it is reduced to a system-specific value.
+
The returned string is statically allocated and overwritten by each call
to @code{fcvt}.
@end deftypefun
@code{gcvt} is functionally equivalent to @samp{sprintf(buf, "%*g",
ndigit, value}. It is provided only for compatibility's sake. It
returns @var{buf}.
+
+If @var{ndigit} decimal digits would exceed the precision of a
+@code{double} it is reduced to a system-specific value.
@end deftypefun
As extensions, the GNU C library provides versions of these three
@comment stdlib.h
@comment GNU
@deftypefun {char *} qecvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
-This function is equivalent to @code{ecvt} except that it
-takes a @code{long double} for the first parameter.
+This function is equivalent to @code{ecvt} except that it takes a
+@code{long double} for the first parameter and that @var{ndigit} is
+restricted by the precision of a @code{long double}.
@end deftypefun
@comment stdlib.h
@comment GNU
-@deftypefun {char *} qfcvt (long double @var{value}, int @var{ndigit}, int @var{decpt}, int *@var{neg})
+@deftypefun {char *} qfcvt (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg})
This function is equivalent to @code{fcvt} except that it
-takes a @code{long double} for the first parameter.
+takes a @code{long double} for the first parameter and that @var{ndigit} is
+restricted by the precision of a @code{long double}.
@end deftypefun
@comment stdlib.h
@comment GNU
@deftypefun {char *} qgcvt (long double @var{value}, int @var{ndigit}, char *@var{buf})
-This function is equivalent to @code{gcvt} except that it
-takes a @code{long double} for the first parameter.
+This function is equivalent to @code{gcvt} except that it takes a
+@code{long double} for the first parameter and that @var{ndigit} is
+restricted by the precision of a @code{long double}.
@end deftypefun
@comment stdlib.h
@comment SVID, Unix98
-@deftypefun {char *} fcvt_r (double @var{value}, int @var{ndigit}, int @var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
+@deftypefun {char *} fcvt_r (double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
The @code{fcvt_r} function is the same as @code{fcvt}, except
that it places its result into the user-specified buffer pointed to by
@var{buf}, with length @var{len}.
@comment stdlib.h
@comment GNU
-@deftypefun {char *} qfcvt_r (long double @var{value}, int @var{ndigit}, int @var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
+@deftypefun {char *} qfcvt_r (long double @var{value}, int @var{ndigit}, int *@var{decpt}, int *@var{neg}, char *@var{buf}, size_t @var{len})
The @code{qfcvt_r} function is the same as @code{qfcvt}, except
that it places its result into the user-specified buffer pointed to by
@var{buf}, with length @var{len}.
associated Internet address.
@end table
+The lookup functions above all have one in common: they are not
+reentrant and therefore unusable in multi-threaded applications.
+Therefore provides the GNU C library a new set of functions which can be
+used in this context.
+
+@comment netdb.h
+@comment GNU
+@deftypefun int gethostbyname_r (const char *restrict @var{name}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
+The @code{gethostbyname_r} function returns information about the host
+named @var{name}. The caller must pass a pointer to an object of type
+@code{struct hostent} in the @var{result_buf} parameter. In addition
+the function may need extra buffer space and the caller must pass an
+pointer and the size of the buffer in the @var{buf} and @var{buflen}
+parameters.
+
+A pointer to the buffer, in which the result is stored, is available in
+@code{*@var{result}} after the function call successfully returned. If
+an error occurs or if no entry is found, the pointer @code{*var{result}
+is a null pointer. Success is signalled by a zero return value. If the
+function failed the return value is an error number. In addition to the
+errors defined for @code{gethostbyname} it can also be @code{ERANGE}.
+In this case the call should be repeated with a larger buffer.
+Additional error information is not stored in the global variable
+@code{h_errno} but instead in the object pointed to by @var{h_errnop}.
+
+Here's a small example:
+@smallexample
+struct hostent *
+gethostname (char *host)
+@{
+ struct hostent hostbuf, *hp;
+ size_t hstbuflen;
+ char *tmphstbuf;
+ int res;
+ int herr;
+
+ hstbuflen = 1024;
+ tmphstbuf = malloc (hstbuflen);
+
+ while ((res = gethostbyname_r (host, &hostbuf, tmphstbuf, hstbuflen,
+ &hp, &herr)) == ERANGE)
+ @{
+ /* Enlarge the buffer. */
+ hstbuflen *= 2;
+ tmphstbuf = realloc (tmphstbuf, hstbuflen);
+ @}
+ /* Check for errors. */
+ if (res || hp == NULL)
+ return NULL;
+ return hp->h_name;
+@}
+@end smallexample
+@end deftypefun
+
+@comment netdb.h
+@comment GNU
+@deftypefun int gethostbyname2_r (const char *@var{name}, int @var{af}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
+The @code{gethostbyname2_r} function is like @code{gethostbyname_r}, but
+allows the caller to specify the desired address family (e.g.@:
+@code{AF_INET} or @code{AF_INET6}) for the result.
+@end deftypefun
+
+@comment netdb.h
+@comment GNU
+@deftypefun int gethostbyaddr_r (const char *@var{addr}, int @var{length}, int @var{format}, struct hostent *restrict @var{result_buf}, char *restrict @var{buf}, size_t @var{buflen}, struct hostent **restrict @var{result}, int *restrict @var{h_errnop})
+The @code{gethostbyaddr_r} function returns information about the host
+with Internet address @var{addr}. The parameter @var{addr} is not
+really a pointer to char - it can be a pointer to an IPv4 or an IPv6
+address. The @var{length} argument is the size (in bytes) of the address
+at @var{addr}. @var{format} specifies the address format; for an IPv4
+Internet address, specify a value of @code{AF_INET}; for an IPv6
+Internet address, use @code{AF_INET6}.
+
+Similar to the @code{gethostbyname_r} function, the caller must provide
+buffers for the result and memory used internally. In case of success
+the function returns zero. Otherwise the value is an error number where
+@code{ERANGE} has the special meaning that the caller-provided buffer is
+too small.
+@end deftypefun
+
You can also scan the entire hosts database one entry at a time using
@code{sethostent}, @code{gethostent}, and @code{endhostent}. Be careful
in using these functions, because they are not reentrant.
are used to contain additional information, normally strings which are
pointed to by the elements of the result structure.
-If the return value is @code{0} the pointer returned in @var{result}
-points to the record which contains the wanted data (i.e., @var{result}
-contains the value @var{result_buf}). If it is nonzero, there is no
-user in the data base with user ID @var{uid}, or the buffer @var{buffer}
-is too small to contain all the needed information. In the latter case,
-@var{errno} is set to @code{ERANGE}.
+If a user with ID @var{uid} is found, the pointer returned in
+@var{result} points to the record which contains the wanted data (i.e.,
+@var{result} contains the value @var{result_buf}). If no user is found
+or if an error occured, the pointer returned in @var{result} is a null
+pointer. The function returns zero or an error code. If the buffer
+@var{buffer} is too small to contain all the needed information, the
+error code @code{ERANGE} is returned and @var{errno} is set to
+@code{ERANGE}.
@end deftypefun
are used to contain additional information, normally strings which are
pointed to by the elements of the result structure.
-If the return value is @code{0} the pointer returned in @var{result}
-points to the requested data (i.e., @var{result} contains the value
-@var{result_buf}). If it is nonzero, there is no group in the data base
-with group ID @var{gid}, or the buffer @var{buffer} is too small to
-contain all the needed information. In the latter case, @var{errno} is
-set to @code{ERANGE}.
+If a group with ID @var{gid} is found, the pointer returned in
+@var{result} points to the record which contains the wanted data (i.e.,
+@var{result} contains the value @var{result_buf}). If no group is found
+or if an error occured, the pointer returned in @var{result} is a null
+pointer. The function returns zero or an error code. If the buffer
+@var{buffer} is too small to contain all the needed information, the
+error code @code{ERANGE} is returned and @var{errno} is set to
+@code{ERANGE}.
@end deftypefun
@comment grp.h
buffer = __alloca (buflen);
}
- if (result == 0 && pwd.pw_dir != NULL)
+ if (result == 0 && tpwd != NULL && pwd.pw_dir != NULL)
{
*word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
if (*word == NULL)
buffer = __alloca (buflen);
}
- if (result == 0 && pwd.pw_dir)
+ if (result == 0 && tpwd != NULL && pwd.pw_dir)
*word = w_addstr (*word, word_length, max_length, pwd.pw_dir);
else
{
if (__getpwuid_r (uid, &resbuf, tmpbuf, buflen, &p) != 0)
return -1;
+ if (p == NULL)
+ return -1;
+
if (sprintf (buf, "%s:%s:%lu:%lu:%s:%s:%s", p->pw_name, p->pw_passwd,
(unsigned long int) p->pw_uid, (unsigned long int) p->pw_gid,
p->pw_gecos, p->pw_dir, p->pw_shell) < 0)
return 0;
}
weak_alias (__getpw, getpw)
+
+link_warning (getpw, "the `getpw' function is dangerous and should not be used.")
#endif /* POSIX or reentrant */
+#ifdef __USE_GNU
+/* Re-construct the password-file line for the given uid
+ in the given buffer. This knows the format that the caller
+ will expect, but this need not be the format of the password file. */
+extern int getpw __P ((__uid_t __uid, char *__buffer));
+#endif
__END_DECLS
hstbuflen = 1024;
hsttmpbuf = __alloca (hstbuflen);
while (__gethostbyname_r (hostname, &hostbuf, hsttmpbuf, hstbuflen,
- &h, &herr) < 0)
+ &h, &herr) != 0
+ || h == NULL)
if (herr != NETDB_INTERNAL || errno != ERANGE)
{
rpc_createerr.cf_stat = RPC_UNKNOWNHOST;
prtbuflen = 1024;
prttmpbuf = __alloca (prtbuflen);
- while (__getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p)
- < 0)
+ while (__getprotobyname_r (proto, &protobuf, prttmpbuf, prtbuflen, &p) != 0
+ || p == NULL)
if (errno != ERANGE)
{
rpc_createerr.cf_stat = RPC_UNKNOWNPROTO;
buflen = 1024;
buffer = __alloca (buflen);
while (__gethostbyname_r (host, &hostbuf, buffer, buflen,
- &hp, &herr) < 0)
+ &hp, &herr) != 0
+ || hp == NULL)
if (herr != NETDB_INTERNAL || errno != ERANGE)
return (int) RPC_UNKNOWNHOST;
else
buflen = 1024;
buffer = __alloca (buflen);
- while (__gethostbyname_r (host, &hostbuf, buffer, buflen, &hp, &herr)
- < 0)
+ while (__gethostbyname_r (host, &hostbuf, buffer, buflen, &hp, &herr) != 0
+ || hp == NULL)
if (herr != NETDB_INTERNAL || errno != ERANGE)
return 0;
else
pwbuflen = 1024;
pwtmpbuf = (char *) __alloca (pwbuflen);
- success = 1;
- while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p) < 0)
+ while (getpwnam_r (name, &pwbuf, pwtmpbuf, pwbuflen, &p)
+ != 0)
{
if (errno != ERANGE)
{
- success = 0;
+ p = NULL;
break;
}
pwbuflen *= 2;
}
# else
p = getpwnam (name);
- success = p != NULL;
# endif
- if (success)
+ if (p != NULL)
home_dir = p->pw_dir;
}
}
buflen = 1024;
pwtmpbuf = (char *) __alloca (buflen);
- while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) < 0)
+ while (getpwnam_r (user_name, &pwbuf, pwtmpbuf, buflen, &p) != 0)
{
if (errno != ERANGE)
{
/* Implementation of gamma function according to ISO C.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
EXTRACT_WORDS (hx, lx, x);
if (((hx & 0x7fffffff) | lx) == 0)
- /* Return value for x == 0 is NaN with invalid exception. */
- return x / x;
+ {
+ /* Return value for x == 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return x / x;
+ }
if (hx < 0 && (u_int32_t) hx < 0xfff00000 && __rint (x) == x)
{
/* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
return (x - x) / (x - x);
}
/* Implementation of gamma function according to ISO C.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
GET_FLOAT_WORD (hx, x);
if ((hx & 0x7fffffff) == 0)
- /* Return value for x == 0 is NaN with invalid exception. */
- return x / x;
+ {
+ /* Return value for x == 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return x / x;
+ }
if (hx < 0 && (u_int32_t) hx < 0xff800000 && __rintf (x) == x)
{
/* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
return (x - x) / (x - x);
}
/* Implementation of gamma function according to ISO C.
- Copyright (C) 1997 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
GET_LDOUBLE_WORDS (es, hx, lx, x);
if (((es & 0x7fff) | hx | lx) == 0)
- /* Return value for x == 0 is NaN with invalid exception. */
- return x / x;
+ {
+ /* Return value for x == 0 is NaN with invalid exception. */
+ *signgamp = 0;
+ return x / x;
+ }
if ((hx & 0x8000) != 0 && (hx & 0x7fff) != 0x7fff && __rintl (x) == x)
{
/* Return value for integer x < 0 is NaN with invalid exception. */
+ *signgamp = 0;
return (x - x) / (x - x);
}
-/* Copyright (C) 1991, 1996, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1998, 1999 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
struct passwd pwent;
struct passwd *pwptr;
- if (__getpwuid_r (__geteuid (), &pwent, buf, sizeof (buf), &pwptr))
+ if (__getpwuid_r (__geteuid (), &pwent, buf, sizeof (buf), &pwptr)
+ || pwptr == NULL)
{
if (s != NULL)
s[0] = '\0';
r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen,
&s);
- if (r)
+ if (r || s == NULL)
{
if (errno == ERANGE)
tmpbuflen *= 2;
-/* Copyright (C) 1995, 1996, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
/* To get the IP address we need to know the host name. */
while (__gethostbyname_r (hostname, &hostbuf, buffer, buflen, &hp, &herr)
- < 0)
+ != 0
+ || hp == NULL)
if (herr != NETDB_INTERNAL || errno != ERANGE)
return 0;
else
int century, want_century;
int have_wday, want_xday;
int have_yday;
-
+ int have_mon, have_mday;
+
rp = buf;
fmt = format;
have_I = is_pm = 0;
century = -1;
want_century = 0;
- have_wday = want_xday = have_yday = 0;
+ have_wday = want_xday = have_yday = have_mon = have_mday = 0;
while (*fmt != '\0')
{
/* Match day of month. */
get_number (1, 31);
tm->tm_mday = val;
+ have_mday = 1;
want_xday = 1;
break;
case 'F':
/* Match number of month. */
get_number (1, 12);
tm->tm_mon = val - 1;
+ have_mon = 1;
want_xday = 1;
break;
case 'M':
/* Match day of month using alternate numeric symbols. */
get_alt_number (1, 31);
tm->tm_mday = val;
+ have_mday = 1;
want_xday = 1;
break;
case 'H':
/* Match month using alternate numeric symbols. */
get_alt_number (1, 12);
tm->tm_mon = val - 1;
+ have_mon = 1;
want_xday = 1;
break;
case 'M':
if (want_century && century != -1)
tm->tm_year = tm->tm_year % 100 + (century - 19) * 100;
- if (want_xday && !have_wday)
- day_of_the_week (tm);
+ if (want_xday && !have_wday) {
+ if ( !(have_mon && have_mday) && have_yday) {
+ /* we don't have tm_mon and/or tm_mday, compute them */
+ int t_mon = 0;
+ while (__mon_yday[__isleap(1900 + tm->tm_year)][t_mon] <= tm->tm_yday)
+ t_mon++;
+ if (!have_mon)
+ tm->tm_mon = t_mon - 1;
+ if (!have_mday)
+ tm->tm_mday = tm->tm_yday - __mon_yday[__isleap(1900 + tm->tm_year)][t_mon - 1] + 1;
+ }
+ day_of_the_week (tm);
+ }
if (want_xday && !have_yday)
day_of_the_year (tm);
-/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1999 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
register const wchar_t *wcs;
register const wchar_t wc;
{
- while (*wcs != L'\0')
+ do
if (*wcs == wc)
return (wchar_t *) wcs;
- else
- ++wcs;
+ while (*wcs++ != L'\0');
return NULL;
}
-/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1995, 1996, 1999 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>
{
const wchar_t *retval = NULL;
- while (*wcs != L'\0')
- {
- if (*wcs == wc)
- retval = wcs;
- ++wcs;
- }
+ do
+ if (*wcs == wc)
+ retval = wcs;
+ while (*wcs++ != L'\0');
return (wchar_t *) retval;
}