summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorRenato Botelho <renato@netgate.com>2016-08-30 09:16:57 -0300
committerRenato Botelho <renato@netgate.com>2016-08-30 09:16:57 -0300
commit39fd693a18f8ef73b1268f2321393d5ca6101e89 (patch)
treeb1bae394d01f4c868d315c2d7a2f7f7f0539a57b /lib/libc
parent29ebd1247162a77db08e5e2e00d033220ec807fe (diff)
parentde43eec3e10416a7e9f3a7565f70e1ba2d265384 (diff)
downloadFreeBSD-src-39fd693a18f8ef73b1268f2321393d5ca6101e89.zip
FreeBSD-src-39fd693a18f8ef73b1268f2321393d5ca6101e89.tar.gz
Merge remote-tracking branch 'origin/stable/10' into devel
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/net/getaddrinfo.c27
-rw-r--r--lib/libc/nls/msgcat.c10
-rw-r--r--lib/libc/stdio/fgetln.35
-rw-r--r--lib/libc/stdio/fgetln.c15
-rw-r--r--lib/libc/stdio/fgetwc.c13
-rw-r--r--lib/libc/stdio/fgetwln.c7
-rw-r--r--lib/libc/stdio/fputwc.c16
-rw-r--r--lib/libc/stdio/getdelim.c4
-rw-r--r--lib/libc/stdio/vfprintf.c6
-rw-r--r--lib/libc/stdio/vfwprintf.c6
10 files changed, 69 insertions, 40 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
index 54ac329..c5bfc5e 100644
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -207,6 +207,7 @@ struct ai_order {
struct policyqueue *aio_dstpolicy;
struct addrinfo *aio_ai;
int aio_matchlen;
+ int aio_initial_sequence;
};
static const ns_src default_dns_files[] = {
@@ -690,6 +691,7 @@ reorder(struct addrinfo *sentinel)
aio[i].aio_dstpolicy = match_addrselectpolicy(ai->ai_addr,
&policyhead);
set_source(&aio[i], &policyhead);
+ aio[i].aio_initial_sequence = i;
}
/* perform sorting. */
@@ -1048,6 +1050,23 @@ comp_dst(const void *arg1, const void *arg2)
}
/* Rule 10: Otherwise, leave the order unchanged. */
+
+ /*
+ * Note that qsort is unstable; so, we can't return zero and
+ * expect the order to be unchanged.
+ * That also means we can't depend on the current position of
+ * dst2 being after dst1. We must enforce the initial order
+ * with an explicit compare on the original position.
+ * The qsort specification requires that "When the same objects
+ * (consisting of width bytes, irrespective of their current
+ * positions in the array) are passed more than once to the
+ * comparison function, the results shall be consistent with one
+ * another."
+ * In other words, If A < B, then we must also return B > A.
+ */
+ if (dst2->aio_initial_sequence < dst1->aio_initial_sequence)
+ return(1);
+
return(-1);
}
@@ -2251,6 +2270,8 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
struct res_target q, q2;
res_state res;
+ ai = NULL;
+
hostname = va_arg(ap, char *);
pai = va_arg(ap, const struct addrinfo *);
@@ -2329,16 +2350,16 @@ _dns_getaddrinfo(void *rv, void *cb_data, va_list ap)
/* prefer IPv6 */
if (q.next) {
ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai, res);
- if (ai) {
+ if (ai != NULL) {
cur->ai_next = ai;
while (cur && cur->ai_next)
cur = cur->ai_next;
}
}
- if (!ai || pai->ai_family != AF_UNSPEC ||
+ if (ai == NULL || pai->ai_family != AF_UNSPEC ||
(pai->ai_flags & (AI_ALL | AI_V4MAPPED)) != AI_V4MAPPED) {
ai = getanswer(buf, q.n, q.name, q.qtype, pai, res);
- if (ai)
+ if (ai != NULL)
cur->ai_next = ai;
}
free(buf);
diff --git a/lib/libc/nls/msgcat.c b/lib/libc/nls/msgcat.c
index 0cba460..b373a3d 100644
--- a/lib/libc/nls/msgcat.c
+++ b/lib/libc/nls/msgcat.c
@@ -47,7 +47,6 @@ __FBSDID("$FreeBSD$");
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
-#include <locale.h>
#include <nl_types.h>
#include <pthread.h>
#include <stdio.h>
@@ -56,7 +55,7 @@ __FBSDID("$FreeBSD$");
#include <unistd.h>
#include "un-namespace.h"
-#include "../locale/setlocale.h" /* for ENCODING_LEN */
+#include "../locale/xlocale_private.h"
#define _DEFAULT_NLS_PATH "/usr/share/nls/%L/%N.cat:/usr/share/nls/%N/%L:/usr/local/share/nls/%L/%N.cat:/usr/local/share/nls/%N/%L"
@@ -115,9 +114,10 @@ catopen(const char *name, int type)
{
struct stat sbuf;
struct catentry *np;
- char *base, *cptr, *cptr1, *lang, *nlspath, *pathP, *pcode;
- char *plang, *pter, *tmpptr;
+ char *base, *cptr, *cptr1, *nlspath, *pathP, *pcode;
+ char *plang, *pter;
int saverr, spcleft;
+ const char *lang, *tmpptr;
char path[PATH_MAX];
/* sanity checking */
@@ -129,7 +129,7 @@ catopen(const char *name, int type)
lang = NULL;
else {
if (type == NL_CAT_LOCALE)
- lang = setlocale(LC_MESSAGES, NULL);
+ lang = querylocale(LC_MESSAGES_MASK, __get_locale());
else
lang = getenv("LANG");
diff --git a/lib/libc/stdio/fgetln.3 b/lib/libc/stdio/fgetln.3
index 4b83664..7d4b89a5 100644
--- a/lib/libc/stdio/fgetln.3
+++ b/lib/libc/stdio/fgetln.3
@@ -28,7 +28,7 @@
.\" @(#)fgetln.3 8.3 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
-.Dd April 19, 1994
+.Dd February 15, 2016
.Dt FGETLN 3
.Os
.Sh NAME
@@ -97,6 +97,9 @@ These changes are lost as soon as the pointer becomes invalid.
The argument
.Fa stream
is not a stream open for reading.
+.It Bq Er ENOMEM
+The internal line buffer could not be expanded due to lack of available memory,
+or because it would need to expand beyond INT_MAX in size.
.El
.Pp
The
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
index 6546768..c8e30ee 100644
--- a/lib/libc/stdio/fgetln.c
+++ b/lib/libc/stdio/fgetln.c
@@ -37,6 +37,8 @@ static char sccsid[] = "@(#)fgetln.c 8.2 (Berkeley) 1/2/94";
__FBSDID("$FreeBSD$");
#include "namespace.h"
+#include <errno.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -61,6 +63,10 @@ __slbexpand(FILE *fp, size_t newsize)
#endif
if (fp->_lb._size >= newsize)
return (0);
+ if (newsize > INT_MAX) {
+ errno = ENOMEM;
+ return (-1);
+ }
if ((p = realloc(fp->_lb._base, newsize)) == NULL)
return (-1);
fp->_lb._base = p;
@@ -133,8 +139,11 @@ fgetln(FILE *fp, size_t *lenp)
(void)memcpy((void *)(fp->_lb._base + off), (void *)fp->_p,
len - off);
off = len;
- if (__srefill(fp))
- break; /* EOF or error: return partial line */
+ if (__srefill(fp)) {
+ if (__sfeof(fp))
+ break;
+ goto error;
+ }
if ((p = memchr((void *)fp->_p, '\n', (size_t)fp->_r)) == NULL)
continue;
@@ -152,7 +161,7 @@ fgetln(FILE *fp, size_t *lenp)
}
*lenp = len;
#ifdef notdef
- fp->_lb._base[len] = 0;
+ fp->_lb._base[len] = '\0';
#endif
FUNLOCKFILE(fp);
return ((char *)fp->_lb._base);
diff --git a/lib/libc/stdio/fgetwc.c b/lib/libc/stdio/fgetwc.c
index 52bc988..cf649fd 100644
--- a/lib/libc/stdio/fgetwc.c
+++ b/lib/libc/stdio/fgetwc.c
@@ -79,18 +79,9 @@ __fgetwc_mbs(FILE *fp, mbstate_t *mbs, int *nread, locale_t locale)
size_t nconv;
struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
- if (fp->_r <= 0 && __srefill(fp)) {
- *nread = 0;
- return (WEOF);
- }
- if (MB_CUR_MAX == 1) {
- /* Fast path for single-byte encodings. */
- wc = *fp->_p++;
- fp->_r--;
- *nread = 1;
- return (wc);
- }
*nread = 0;
+ if (fp->_r <= 0 && __srefill(fp))
+ return (WEOF);
do {
nconv = l->__mbrtowc(&wc, fp->_p, fp->_r, mbs);
if (nconv == (size_t)-1)
diff --git a/lib/libc/stdio/fgetwln.c b/lib/libc/stdio/fgetwln.c
index 8439496..34a80a0 100644
--- a/lib/libc/stdio/fgetwln.c
+++ b/lib/libc/stdio/fgetwln.c
@@ -56,13 +56,15 @@ fgetwln_l(FILE * __restrict fp, size_t *lenp, locale_t locale)
while ((wc = __fgetwc(fp, locale)) != WEOF) {
#define GROW 512
if (len * sizeof(wchar_t) >= fp->_lb._size &&
- __slbexpand(fp, (len + GROW) * sizeof(wchar_t)))
+ __slbexpand(fp, (len + GROW) * sizeof(wchar_t))) {
+ fp->_flags |= __SERR;
goto error;
+ }
*((wchar_t *)fp->_lb._base + len++) = wc;
if (wc == L'\n')
break;
}
- if (len == 0)
+ if (len == 0 || (wc == WEOF && !__sfeof(fp)))
goto error;
FUNLOCKFILE(fp);
@@ -74,6 +76,7 @@ error:
*lenp = 0;
return (NULL);
}
+
wchar_t *
fgetwln(FILE * __restrict fp, size_t *lenp)
{
diff --git a/lib/libc/stdio/fputwc.c b/lib/libc/stdio/fputwc.c
index 7b05d4a..7f0c910 100644
--- a/lib/libc/stdio/fputwc.c
+++ b/lib/libc/stdio/fputwc.c
@@ -53,19 +53,9 @@ __fputwc(wchar_t wc, FILE *fp, locale_t locale)
size_t i, len;
struct xlocale_ctype *l = XLOCALE_CTYPE(locale);
- if (MB_CUR_MAX == 1 && wc > 0 && wc <= UCHAR_MAX) {
- /*
- * Assume single-byte locale with no special encoding.
- * A more careful test would be to check
- * _CurrentRuneLocale->encoding.
- */
- *buf = (unsigned char)wc;
- len = 1;
- } else {
- if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
- fp->_flags |= __SERR;
- return (WEOF);
- }
+ if ((len = l->__wcrtomb(buf, wc, &fp->_mbstate)) == (size_t)-1) {
+ fp->_flags |= __SERR;
+ return (WEOF);
}
for (i = 0; i < len; i++)
diff --git a/lib/libc/stdio/getdelim.c b/lib/libc/stdio/getdelim.c
index d7d5627..7e0b2e2 100644
--- a/lib/libc/stdio/getdelim.c
+++ b/lib/libc/stdio/getdelim.c
@@ -125,7 +125,7 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim,
if (fp->_r <= 0 && __srefill(fp)) {
/* If fp is at EOF already, we just need space for the NUL. */
- if (__sferror(fp) || expandtofit(linep, 1, linecapp))
+ if (!__sfeof(fp) || expandtofit(linep, 1, linecapp))
goto error;
FUNLOCKFILE(fp);
(*linep)[0] = '\0';
@@ -137,7 +137,7 @@ getdelim(char ** __restrict linep, size_t * __restrict linecapp, int delim,
if (sappend(linep, &linelen, linecapp, fp->_p, fp->_r))
goto error;
if (__srefill(fp)) {
- if (__sferror(fp))
+ if (!__sfeof(fp))
goto error;
goto done; /* hit EOF */
}
diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c
index e54e8ac..bf45bfb 100644
--- a/lib/libc/stdio/vfprintf.c
+++ b/lib/libc/stdio/vfprintf.c
@@ -364,6 +364,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
int nextarg; /* 1-based argument index */
va_list orgap; /* original argument pointer */
char *convbuf; /* wide to multibyte conversion result */
+ int savserr;
static const char xdigs_lower[16] = "0123456789abcdef";
static const char xdigs_upper[16] = "0123456789ABCDEF";
@@ -460,6 +461,9 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap)
return (EOF);
}
+ savserr = fp->_flags & __SERR;
+ fp->_flags &= ~__SERR;
+
convbuf = NULL;
fmt = (char *)fmt0;
argtable = NULL;
@@ -1031,6 +1035,8 @@ error:
free(convbuf);
if (__sferror(fp))
ret = EOF;
+ else
+ fp->_flags |= savserr;
if ((argtable != NULL) && (argtable != statargtable))
free (argtable);
return (ret);
diff --git a/lib/libc/stdio/vfwprintf.c b/lib/libc/stdio/vfwprintf.c
index b75c504..9a5381d 100644
--- a/lib/libc/stdio/vfwprintf.c
+++ b/lib/libc/stdio/vfwprintf.c
@@ -444,6 +444,7 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap)
int nextarg; /* 1-based argument index */
va_list orgap; /* original argument pointer */
wchar_t *convbuf; /* multibyte to wide conversion result */
+ int savserr;
static const char xdigs_lower[16] = "0123456789abcdef";
static const char xdigs_upper[16] = "0123456789ABCDEF";
@@ -536,6 +537,9 @@ __vfwprintf(FILE *fp, locale_t locale, const wchar_t *fmt0, va_list ap)
return (EOF);
}
+ savserr = fp->_flags & __SERR;
+ fp->_flags &= ~__SERR;
+
convbuf = NULL;
fmt = (wchar_t *)fmt0;
argtable = NULL;
@@ -1096,6 +1100,8 @@ error:
free(convbuf);
if (__sferror(fp))
ret = EOF;
+ else
+ fp->_flags |= savserr;
if ((argtable != NULL) && (argtable != statargtable))
free (argtable);
return (ret);
OpenPOWER on IntegriCloud