diff options
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/fts-compat.c | 5 | ||||
-rw-r--r-- | lib/libc/gen/fts.c | 1 | ||||
-rw-r--r-- | lib/libc/gen/posix_spawn.c | 9 | ||||
-rw-r--r-- | lib/libc/locale/ascii.c | 2 | ||||
-rw-r--r-- | lib/libc/locale/none.c | 1 | ||||
-rw-r--r-- | lib/libc/regex/engine.c | 15 | ||||
-rw-r--r-- | lib/libc/stdlib/div.c | 2 | ||||
-rw-r--r-- | lib/libc/stdlib/imaxdiv.c | 2 | ||||
-rw-r--r-- | lib/libc/stdlib/ldiv.c | 2 | ||||
-rw-r--r-- | lib/libc/stdlib/lldiv.c | 2 | ||||
-rw-r--r-- | lib/libc/stdlib/rand.c | 57 | ||||
-rw-r--r-- | lib/libc/stdlib/random.3 | 4 | ||||
-rw-r--r-- | lib/libc/stdlib/random.c | 79 | ||||
-rw-r--r-- | lib/libc/sys/vfork.2 | 40 |
14 files changed, 90 insertions, 131 deletions
diff --git a/lib/libc/gen/fts-compat.c b/lib/libc/gen/fts-compat.c index 1be41da..8254a9b 100644 --- a/lib/libc/gen/fts-compat.c +++ b/lib/libc/gen/fts-compat.c @@ -114,7 +114,6 @@ static const char *ufslike_filesystems[] = { "ufs", "zfs", "nfs", - "nfs4", "ext2fs", 0 }; @@ -586,8 +585,10 @@ __fts_children_44bsd(sp, instr) if ((fd = _open(".", O_RDONLY | O_CLOEXEC, 0)) < 0) return (NULL); sp->fts_child = fts_build(sp, instr); - if (fchdir(fd)) + if (fchdir(fd)) { + (void)_close(fd); return (NULL); + } (void)_close(fd); return (sp->fts_child); } diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c index 8083a88..b0623c0 100644 --- a/lib/libc/gen/fts.c +++ b/lib/libc/gen/fts.c @@ -104,7 +104,6 @@ static const char *ufslike_filesystems[] = { "ufs", "zfs", "nfs", - "nfs4", "ext2fs", 0 }; diff --git a/lib/libc/gen/posix_spawn.c b/lib/libc/gen/posix_spawn.c index c65a730..2838c5c 100644 --- a/lib/libc/gen/posix_spawn.c +++ b/lib/libc/gen/posix_spawn.c @@ -140,7 +140,7 @@ process_spawnattr(const posix_spawnattr_t sa) static int process_file_actions_entry(posix_spawn_file_actions_entry_t *fae) { - int fd; + int fd, saved_errno; switch (fae->fae_action) { case FAE_OPEN: @@ -149,8 +149,11 @@ process_file_actions_entry(posix_spawn_file_actions_entry_t *fae) if (fd < 0) return (errno); if (fd != fae->fae_fildes) { - if (_dup2(fd, fae->fae_fildes) == -1) - return (errno); + if (_dup2(fd, fae->fae_fildes) == -1) { + saved_errno = errno; + (void)_close(fd); + return (saved_errno); + } if (_close(fd) != 0) { if (errno == EBADF) return (EBADF); diff --git a/lib/libc/locale/ascii.c b/lib/libc/locale/ascii.c index 784814d..a70d71a 100644 --- a/lib/libc/locale/ascii.c +++ b/lib/libc/locale/ascii.c @@ -143,6 +143,7 @@ _ascii_mbsnrtowcs(wchar_t * __restrict dst, const char ** __restrict src, nchr = 0; while (len-- > 0 && nms-- > 0) { if (*s & 0x80) { + *src = s; errno = EILSEQ; return ((size_t)-1); } @@ -177,6 +178,7 @@ _ascii_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, nchr = 0; while (len-- > 0 && nwc-- > 0) { if (*s < 0 || *s > 127) { + *src = s; errno = EILSEQ; return ((size_t)-1); } diff --git a/lib/libc/locale/none.c b/lib/libc/locale/none.c index 75adffa..41835ee 100644 --- a/lib/libc/locale/none.c +++ b/lib/libc/locale/none.c @@ -172,6 +172,7 @@ _none_wcsnrtombs(char * __restrict dst, const wchar_t ** __restrict src, nchr = 0; while (len-- > 0 && nwc-- > 0) { if (*s < 0 || *s > UCHAR_MAX) { + *src = s; errno = EILSEQ; return ((size_t)-1); } diff --git a/lib/libc/regex/engine.c b/lib/libc/regex/engine.c index 72922f6..2ca971b 100644 --- a/lib/libc/regex/engine.c +++ b/lib/libc/regex/engine.c @@ -606,9 +606,9 @@ backref(struct match *m, return(NULL); break; case OBOL: - if ( (sp == m->beginp && !(m->eflags®_NOTBOL)) || - (sp < m->endp && *(sp-1) == '\n' && - (m->g->cflags®_NEWLINE)) ) + if ((sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp > m->offp && sp < m->endp && + *(sp-1) == '\n' && (m->g->cflags®_NEWLINE))) { /* yes */ } else return(NULL); @@ -622,12 +622,9 @@ backref(struct match *m, return(NULL); break; case OBOW: - if (( (sp == m->beginp && !(m->eflags®_NOTBOL)) || - (sp < m->endp && *(sp-1) == '\n' && - (m->g->cflags®_NEWLINE)) || - (sp > m->beginp && - !ISWORD(*(sp-1))) ) && - (sp < m->endp && ISWORD(*sp)) ) + if (sp < m->endp && ISWORD(*sp) && + ((sp == m->beginp && !(m->eflags®_NOTBOL)) || + (sp > m->offp && !ISWORD(*(sp-1))))) { /* yes */ } else return(NULL); diff --git a/lib/libc/stdlib/div.c b/lib/libc/stdlib/div.c index 7dfe553..0bafbe6 100644 --- a/lib/libc/stdlib/div.c +++ b/lib/libc/stdlib/div.c @@ -46,6 +46,7 @@ div(num, denom) r.quot = num / denom; r.rem = num % denom; +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) /* * The ANSI standard says that |r.quot| <= |n/d|, where * n/d is to be computed in infinite precision. In other @@ -73,5 +74,6 @@ div(num, denom) r.quot++; r.rem -= denom; } +#endif return (r); } diff --git a/lib/libc/stdlib/imaxdiv.c b/lib/libc/stdlib/imaxdiv.c index 7dae467..adcab0b 100644 --- a/lib/libc/stdlib/imaxdiv.c +++ b/lib/libc/stdlib/imaxdiv.c @@ -37,9 +37,11 @@ imaxdiv(intmax_t numer, intmax_t denom) retval.quot = numer / denom; retval.rem = numer % denom; +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) if (numer >= 0 && retval.rem < 0) { retval.quot++; retval.rem -= denom; } +#endif return (retval); } diff --git a/lib/libc/stdlib/ldiv.c b/lib/libc/stdlib/ldiv.c index 0ec98e6..745c566 100644 --- a/lib/libc/stdlib/ldiv.c +++ b/lib/libc/stdlib/ldiv.c @@ -48,9 +48,11 @@ ldiv(num, denom) r.quot = num / denom; r.rem = num % denom; +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) if (num >= 0 && r.rem < 0) { r.quot++; r.rem -= denom; } +#endif return (r); } diff --git a/lib/libc/stdlib/lldiv.c b/lib/libc/stdlib/lldiv.c index b34b65e..197b48f 100644 --- a/lib/libc/stdlib/lldiv.c +++ b/lib/libc/stdlib/lldiv.c @@ -37,9 +37,11 @@ lldiv(long long numer, long long denom) retval.quot = numer / denom; retval.rem = numer % denom; +#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) if (numer >= 0 && retval.rem < 0) { retval.quot++; retval.rem -= denom; } +#endif return (retval); } diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c index 4f4aa8d..6125b1a 100644 --- a/lib/libc/stdlib/rand.c +++ b/lib/libc/stdlib/rand.c @@ -49,14 +49,6 @@ __FBSDID("$FreeBSD$"); static int do_rand(unsigned long *ctx) { -#ifdef USE_WEAK_SEEDING -/* - * Historic implementation compatibility. - * The random sequences do not vary much with the seed, - * even with overflowing. - */ - return ((*ctx = *ctx * 1103515245 + 12345) % ((u_long)RAND_MAX + 1)); -#else /* !USE_WEAK_SEEDING */ /* * Compute x = (7^5 * x) mod (2^31 - 1) * without overflowing 31 bits: @@ -67,64 +59,45 @@ do_rand(unsigned long *ctx) */ long hi, lo, x; - /* Must be in [1, 0x7ffffffe] range at this point. */ - hi = *ctx / 127773; - lo = *ctx % 127773; + /* Transform to [1, 0x7ffffffe] range. */ + x = (*ctx % 0x7ffffffe) + 1; + hi = x / 127773; + lo = x % 127773; x = 16807 * lo - 2836 * hi; if (x < 0) x += 0x7fffffff; - *ctx = x; /* Transform to [0, 0x7ffffffd] range. */ - return (x - 1); -#endif /* !USE_WEAK_SEEDING */ + x--; + *ctx = x; + return (x); } int -rand_r(unsigned int *ctx) +rand_r(unsigned *ctx) { u_long val; int r; -#ifdef USE_WEAK_SEEDING val = *ctx; -#else - /* Transform to [1, 0x7ffffffe] range. */ - val = (*ctx % 0x7ffffffe) + 1; -#endif r = do_rand(&val); - -#ifdef USE_WEAK_SEEDING - *ctx = (unsigned int)val; -#else - *ctx = (unsigned int)(val - 1); -#endif + *ctx = (unsigned)val; return (r); } -static u_long next = -#ifdef USE_WEAK_SEEDING - 1; -#else - 2; -#endif +static u_long next = 1; int -rand() +rand(void) { return (do_rand(&next)); } void -srand(seed) -u_int seed; +srand(unsigned seed) { next = seed; -#ifndef USE_WEAK_SEEDING - /* Transform to [1, 0x7ffffffe] range. */ - next = (next % 0x7ffffffe) + 1; -#endif } @@ -136,7 +109,7 @@ u_int seed; * data from the kernel. */ void -sranddev() +sranddev(void) { int mib[2]; size_t len; @@ -146,10 +119,6 @@ sranddev() mib[0] = CTL_KERN; mib[1] = KERN_ARND; sysctl(mib, 2, (void *)&next, &len, NULL, 0); -#ifndef USE_WEAK_SEEDING - /* Transform to [1, 0x7ffffffe] range. */ - next = (next % 0x7ffffffe) + 1; -#endif } diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3 index dc8e961..35b0aa1 100644 --- a/lib/libc/stdlib/random.3 +++ b/lib/libc/stdlib/random.3 @@ -175,8 +175,8 @@ If .Fn initstate is called with less than 8 bytes of state information, or if .Fn setstate -detects that the state information has been garbled, error -messages are printed on the standard error output. +detects that the state information has been garbled, +NULL is returned. .Sh SEE ALSO .Xr arc4random 3 , .Xr lrand48 3 , diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c index 580f26e3..fe8fc86 100644 --- a/lib/libc/stdlib/random.c +++ b/lib/libc/stdlib/random.c @@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <sys/sysctl.h> #include <stdint.h> -#include <stdio.h> #include <stdlib.h> #include "un-namespace.h" @@ -138,11 +137,7 @@ __FBSDID("$FreeBSD$"); */ #define MAX_TYPES 5 /* max number of types above */ -#ifdef USE_WEAK_SEEDING -#define NSHUFF 0 -#else /* !USE_WEAK_SEEDING */ #define NSHUFF 50 /* to drop some "seed -> 1st value" linearity */ -#endif /* !USE_WEAK_SEEDING */ static const int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; static const int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; @@ -163,23 +158,12 @@ static const int seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; static uint32_t randtbl[DEG_3 + 1] = { TYPE_3, -#ifdef USE_WEAK_SEEDING -/* Historic implementation compatibility */ -/* The random sequences do not vary much with the seed */ - 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5, - 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd, - 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88, - 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc, - 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b, - 0x27fb47b9, -#else /* !USE_WEAK_SEEDING */ - 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05, - 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454, - 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471, - 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1, - 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41, - 0xf3bec5da -#endif /* !USE_WEAK_SEEDING */ + 0x2cf41758, 0x27bb3711, 0x4916d4d1, 0x7b02f59f, 0x9b8e28eb, 0xc0e80269, + 0x696f5c16, 0x878f1ff5, 0x52d9c07f, 0x916a06cd, 0xb50b3a20, 0x2776970a, + 0xee4eb2a6, 0xe94640ec, 0xb1d65612, 0x9d1ed968, 0x1043f6b7, 0xa3432a76, + 0x17eacbb9, 0x3c09e2eb, 0x4f8c2b3, 0x708a1f57, 0xee341814, 0x95d0e4d2, + 0xb06f216c, 0x8bd2e72e, 0x8f7c38d7, 0xcfc6a8fc, 0x2a59495, 0xa20d2a69, + 0xe29d12d1 }; /* @@ -216,16 +200,8 @@ static int rand_sep = SEP_3; static uint32_t *end_ptr = &randtbl[DEG_3 + 1]; static inline uint32_t -good_rand(int32_t x) +good_rand(uint32_t ctx) { -#ifdef USE_WEAK_SEEDING -/* - * Historic implementation compatibility. - * The random sequences do not vary much with the seed, - * even with overflowing. - */ - return (1103515245 * x + 12345); -#else /* !USE_WEAK_SEEDING */ /* * Compute x = (7^5 * x) mod (2^31 - 1) * wihout overflowing 31 bits: @@ -234,18 +210,17 @@ good_rand(int32_t x) * Park and Miller, Communications of the ACM, vol. 31, no. 10, * October 1988, p. 1195. */ - int32_t hi, lo; + int32_t hi, lo, x; - /* Can't be initialized with 0, so use another value. */ - if (x == 0) - x = 123459876; + /* Transform to [1, 0x7ffffffe] range. */ + x = (ctx % 0x7ffffffe) + 1; hi = x / 127773; lo = x % 127773; x = 16807 * lo - 2836 * hi; if (x < 0) x += 0x7fffffff; - return (x); -#endif /* !USE_WEAK_SEEDING */ + /* Transform to [0, 0x7ffffffd] range. */ + return (x - 1); } /* @@ -341,15 +316,12 @@ initstate(unsigned long seed, char *arg_state, long n) char *ostate = (char *)(&state[-1]); uint32_t *int_arg_state = (uint32_t *)arg_state; + if (n < BREAK_0) + return (NULL); if (rand_type == TYPE_0) state[-1] = rand_type; else state[-1] = MAX_TYPES * (rptr - state) + rand_type; - if (n < BREAK_0) { - (void)fprintf(stderr, - "random: not enough state (%ld bytes); ignored.\n", n); - return (0); - } if (n < BREAK_1) { rand_type = TYPE_0; rand_deg = DEG_0; @@ -408,24 +380,15 @@ setstate(char *arg_state) uint32_t rear = new_state[0] / MAX_TYPES; char *ostate = (char *)(&state[-1]); + if (type != TYPE_0 && rear >= degrees[type]) + return (NULL); if (rand_type == TYPE_0) state[-1] = rand_type; else state[-1] = MAX_TYPES * (rptr - state) + rand_type; - switch(type) { - case TYPE_0: - case TYPE_1: - case TYPE_2: - case TYPE_3: - case TYPE_4: - rand_type = type; - rand_deg = degrees[type]; - rand_sep = seps[type]; - break; - default: - (void)fprintf(stderr, - "random: state info corrupted; not changed.\n"); - } + rand_type = type; + rand_deg = degrees[type]; + rand_sep = seps[type]; state = new_state + 1; if (rand_type != TYPE_0) { rptr = &state[rear]; @@ -460,14 +423,14 @@ random(void) if (rand_type == TYPE_0) { i = state[0]; - state[0] = i = (good_rand(i)) & 0x7fffffff; + state[0] = i = good_rand(i); } else { /* * Use local variables rather than static variables for speed. */ f = fptr; r = rptr; *f += *r; - i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */ + i = *f >> 1; /* chucking least random bit */ if (++f >= end_ptr) { f = state; ++r; diff --git a/lib/libc/sys/vfork.2 b/lib/libc/sys/vfork.2 index 798c500..751a3cf 100644 --- a/lib/libc/sys/vfork.2 +++ b/lib/libc/sys/vfork.2 @@ -28,7 +28,7 @@ .\" @(#)vfork.2 8.1 (Berkeley) 6/4/93 .\" $FreeBSD$ .\" -.Dd April 6, 2015 +.Dd May 22, 2016 .Dt VFORK 2 .Os .Sh NAME @@ -41,11 +41,20 @@ .Ft pid_t .Fn vfork void .Sh DESCRIPTION +.Bf -symbolic +Since this function is hard to use correctly from application software, +it is recommended to use +.Xr posix_spawn 3 +or +.Xr fork 2 +instead. +.Ef +.Pp The .Fn vfork system call can be used to create new processes without fully copying the address -space of the old process, which is horrendously inefficient in a paged +space of the old process, which is inefficient in a paged environment. It is useful when the purpose of .Xr fork 2 @@ -56,13 +65,15 @@ The system call differs from .Xr fork 2 -in that the child borrows the parent's memory and thread of -control until a call to +in that the child borrows the parent process's address space and the +calling thread's stack +until a call to .Xr execve 2 or an exit (either by a call to .Xr _exit 2 or abnormally). -The parent process is suspended while the child is using its resources. +The calling thread is suspended while the child is using its resources. +Other threads continue to run. .Pp The .Fn vfork @@ -70,17 +81,21 @@ system call returns 0 in the child's context and (later) the pid of the child in the parent's context. .Pp -The -.Fn vfork -system call -can normally be used just like -.Xr fork 2 . -It does not work, however, to return while running in the child's context +Many problems can occur when replacing +.Xr fork 2 +with +.Fn vfork . +For example, it does not work to return while running in the child's context from the procedure that called .Fn vfork since the eventual return from .Fn vfork would then return to a no longer existent stack frame. +Also, changing process state which is partially implemented in user space +such as signal handlers with +.Xr libthr 3 +will corrupt the parent's state. +.Pp Be careful, also, to call .Xr _exit 2 rather than @@ -106,7 +121,8 @@ Same as for .Xr rfork 2 , .Xr sigaction 2 , .Xr wait 2 , -.Xr exit 3 +.Xr exit 3 , +.Xr posix_spawn 3 .Sh HISTORY The .Fn vfork |