From: Ulrich Drepper Date: Fri, 2 Jul 1999 11:13:51 +0000 (+0000) Subject: Update from main branch. X-Git-Tag: cvs/glibc_2-1-2~340 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3353c7e2b4a6c85dc88617c7a552940bff59823d;p=thirdparty%2Fglibc.git Update from main branch. --- diff --git a/ChangeLog b/ChangeLog index 46589c739fb..aff3fc695ca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +1999-06-28 Ulrich Drepper + + * 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 [PR libc/1185]. + 1999-06-28 Andreas Jaeger * manual/string.texi (Copying and Concatenation): Mention that diff --git a/inet/rcmd.c b/inet/rcmd.c index d8524f93c89..e6a9b1d2085 100644 --- a/inet/rcmd.c +++ b/inet/rcmd.c @@ -53,6 +53,7 @@ static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94"; #include #include #include +#include int __ivaliduser __P ((FILE *, u_int32_t, const char *, const char *)); @@ -83,7 +84,8 @@ rcmd(ahost, rport, locuser, remuser, cmd, fd2p) 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); @@ -273,7 +275,8 @@ ruserok(rhost, superuser, ruser, luser) 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 @@ -373,7 +376,8 @@ iruserok2 (raddr, superuser, ruser, luser, rhost) 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); @@ -472,7 +476,7 @@ __icheckhost (raddr, lhost, rhost) 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 { @@ -566,10 +570,10 @@ __ivaliduser2(hostf, raddr, luser, ruser, rhost) /* 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; } diff --git a/inet/rexec.c b/inet/rexec.c index 8f329b575cd..38248528a33 100644 --- a/inet/rexec.c +++ b/inet/rexec.c @@ -68,7 +68,8 @@ rexec(ahost, rport, name, pass, cmd, fd2p) 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); diff --git a/manual/arith.texi b/manual/arith.texi index a42267712d2..1a24beb7ca4 100644 --- a/manual/arith.texi +++ b/manual/arith.texi @@ -2191,27 +2191,30 @@ All these functions are defined in @file{stdlib.h}. @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 @@ -2220,6 +2223,9 @@ left of the decimal point. For example, if @var{ndigit} is @code{-1}, 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 @@ -2230,6 +2236,9 @@ to @code{fcvt}. @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 @@ -2238,22 +2247,25 @@ functions that take @code{long double} arguments. @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 @@ -2280,7 +2292,7 @@ This function is a GNU extension. @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}. @@ -2300,7 +2312,7 @@ This function is a GNU extension. @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}. diff --git a/manual/socket.texi b/manual/socket.texi index f8564ab5bb3..d77e556214e 100644 --- a/manual/socket.texi +++ b/manual/socket.texi @@ -1268,6 +1268,86 @@ The host database contains an entry for the name, but it doesn't have an 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. diff --git a/manual/users.texi b/manual/users.texi index e1c04302799..7317f5efa20 100644 --- a/manual/users.texi +++ b/manual/users.texi @@ -1479,12 +1479,14 @@ the information instead of using a static buffer. The first 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 @@ -1690,12 +1692,14 @@ the information instead of using a static buffer. The first 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 diff --git a/posix/wordexp.c b/posix/wordexp.c index c43d608aba9..b6cf85af322 100644 --- a/posix/wordexp.c +++ b/posix/wordexp.c @@ -311,7 +311,7 @@ parse_tilde (char **word, size_t *word_length, size_t *max_length, 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) @@ -340,7 +340,7 @@ parse_tilde (char **word, size_t *word_length, size_t *max_length, 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 { diff --git a/pwd/getpw.c b/pwd/getpw.c index 8bfb02eb8b4..5973ef0eea4 100644 --- a/pwd/getpw.c +++ b/pwd/getpw.c @@ -50,6 +50,9 @@ __getpw (uid, buf) 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) @@ -58,3 +61,5 @@ __getpw (uid, buf) return 0; } weak_alias (__getpw, getpw) + +link_warning (getpw, "the `getpw' function is dangerous and should not be used.") diff --git a/pwd/pwd.h b/pwd/pwd.h index e03144fee6e..594dd03314d 100644 --- a/pwd/pwd.h +++ b/pwd/pwd.h @@ -135,6 +135,12 @@ extern int fgetpwent_r __P ((FILE *__restrict __stream, #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 diff --git a/sunrpc/clnt_gen.c b/sunrpc/clnt_gen.c index 1a2cc9141ea..0f388572d43 100644 --- a/sunrpc/clnt_gen.c +++ b/sunrpc/clnt_gen.c @@ -78,7 +78,8 @@ clnt_create (const char *hostname, u_long prog, u_long vers, 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; @@ -107,8 +108,8 @@ clnt_create (const char *hostname, u_long prog, u_long vers, 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; diff --git a/sunrpc/clnt_simp.c b/sunrpc/clnt_simp.c index bf9f6905735..e1e7e2ab734 100644 --- a/sunrpc/clnt_simp.c +++ b/sunrpc/clnt_simp.c @@ -105,7 +105,8 @@ callrpc (const char *host, u_long prognum, u_long versnum, u_long procnum, 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 diff --git a/sunrpc/getrpcport.c b/sunrpc/getrpcport.c index df48dc66d86..2e12482abc5 100644 --- a/sunrpc/getrpcport.c +++ b/sunrpc/getrpcport.c @@ -56,8 +56,8 @@ getrpcport (const char *host, u_long prognum, u_long versnum, u_int proto) 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 diff --git a/sysdeps/generic/glob.c b/sysdeps/generic/glob.c index fe09f50a109..9b134c5a0dd 100644 --- a/sysdeps/generic/glob.c +++ b/sysdeps/generic/glob.c @@ -650,12 +650,12 @@ glob (pattern, flags, errfunc, pglob) 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; @@ -664,9 +664,8 @@ glob (pattern, flags, errfunc, pglob) } # else p = getpwnam (name); - success = p != NULL; # endif - if (success) + if (p != NULL) home_dir = p->pw_dir; } } @@ -735,7 +734,7 @@ glob (pattern, flags, errfunc, pglob) 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) { diff --git a/sysdeps/libm-ieee754/e_gamma_r.c b/sysdeps/libm-ieee754/e_gamma_r.c index 901f1451d2b..bd802c24f16 100644 --- a/sysdeps/libm-ieee754/e_gamma_r.c +++ b/sysdeps/libm-ieee754/e_gamma_r.c @@ -1,5 +1,5 @@ /* 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 , 1997. @@ -34,11 +34,15 @@ __ieee754_gamma_r (double x, int *signgamp) 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); } diff --git a/sysdeps/libm-ieee754/e_gammaf_r.c b/sysdeps/libm-ieee754/e_gammaf_r.c index bf79ffeb57f..926905e7cdd 100644 --- a/sysdeps/libm-ieee754/e_gammaf_r.c +++ b/sysdeps/libm-ieee754/e_gammaf_r.c @@ -1,5 +1,5 @@ /* 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 , 1997. @@ -33,11 +33,15 @@ __ieee754_gammaf_r (float x, int *signgamp) 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); } diff --git a/sysdeps/libm-ieee754/e_gammal_r.c b/sysdeps/libm-ieee754/e_gammal_r.c index 4fd49886d1e..104992450b7 100644 --- a/sysdeps/libm-ieee754/e_gammal_r.c +++ b/sysdeps/libm-ieee754/e_gammal_r.c @@ -1,5 +1,5 @@ /* 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 , 1997. @@ -33,11 +33,15 @@ __ieee754_gammal_r (long double x, int *signgamp) 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); } diff --git a/sysdeps/posix/cuserid.c b/sysdeps/posix/cuserid.c index 68de92ae646..5d9ef83c331 100644 --- a/sysdeps/posix/cuserid.c +++ b/sysdeps/posix/cuserid.c @@ -1,4 +1,4 @@ -/* 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 @@ -34,7 +34,8 @@ cuserid (s) 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'; diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c index f43aa03d1fd..6810963357c 100644 --- a/sysdeps/posix/getaddrinfo.c +++ b/sysdeps/posix/getaddrinfo.c @@ -206,7 +206,7 @@ gaih_inet_serv (const char *servicename, struct gaih_typeproto *tp, r = __getservbyname_r (servicename, tp->name, &ts, tmpbuf, tmpbuflen, &s); - if (r) + if (r || s == NULL) { if (errno == ERANGE) tmpbuflen *= 2; diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c index 3ef6ac63fbf..6f501e391dd 100644 --- a/sysdeps/unix/sysv/linux/gethostid.c +++ b/sysdeps/unix/sysv/linux/gethostid.c @@ -1,4 +1,4 @@ -/* 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 @@ -91,7 +91,8 @@ gethostid () /* 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 diff --git a/time/strptime.c b/time/strptime.c index 26f77ebbdde..14814ce153c 100644 --- a/time/strptime.c +++ b/time/strptime.c @@ -252,13 +252,14 @@ strptime_internal (buf, format, tm, decided) 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') { @@ -407,6 +408,7 @@ strptime_internal (buf, format, tm, decided) /* Match day of month. */ get_number (1, 31); tm->tm_mday = val; + have_mday = 1; want_xday = 1; break; case 'F': @@ -464,6 +466,7 @@ strptime_internal (buf, format, tm, decided) /* Match number of month. */ get_number (1, 12); tm->tm_mon = val - 1; + have_mon = 1; want_xday = 1; break; case 'M': @@ -743,6 +746,7 @@ strptime_internal (buf, format, tm, decided) /* 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': @@ -763,6 +767,7 @@ strptime_internal (buf, format, tm, decided) /* 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': @@ -809,8 +814,19 @@ strptime_internal (buf, format, tm, decided) 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); diff --git a/wcsmbs/wcschr.c b/wcsmbs/wcschr.c index 7f5c7dcba2d..01e5b2ac981 100644 --- a/wcsmbs/wcschr.c +++ b/wcsmbs/wcschr.c @@ -1,4 +1,4 @@ -/* 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 @@ -25,11 +25,10 @@ wcschr (wcs, wc) 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; } diff --git a/wcsmbs/wcsrchr.c b/wcsmbs/wcsrchr.c index 9f032c76245..e041f7a05d7 100644 --- a/wcsmbs/wcsrchr.c +++ b/wcsmbs/wcsrchr.c @@ -1,4 +1,4 @@ -/* 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, @@ -28,12 +28,10 @@ wcsrchr (wcs, wc) { 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; }