summaryrefslogtreecommitdiffstats
path: root/lib/libc
diff options
context:
space:
mode:
authorsjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
committersjg <sjg@FreeBSD.org>2013-04-12 20:48:55 +0000
commit97d8b9495668afa398ab17c8c5f7e223b5fd2e89 (patch)
tree54038c9ac32a45f8741dcc23fb9a8ffc0e15ff89 /lib/libc
parent5ee3bfdb338e7c80af29a67f4425c4be24c7b866 (diff)
parent086d73aef6d0ab7d21daa2076fdc8d25961f9b05 (diff)
downloadFreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.zip
FreeBSD-src-97d8b9495668afa398ab17c8c5f7e223b5fd2e89.tar.gz
sync from head
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/arm/aeabi/Makefile.inc19
-rw-r--r--lib/libc/gen/Makefile.inc560
-rw-r--r--lib/libc/gen/Symbol.map2
-rw-r--r--lib/libc/gen/cap_sandboxed.370
-rw-r--r--lib/libc/gen/cap_sandboxed.c50
-rw-r--r--lib/libc/gen/fts.c3
-rw-r--r--lib/libc/gen/getcontext.34
-rw-r--r--lib/libc/gen/glob.c2
-rw-r--r--lib/libc/gen/opendir.c51
-rw-r--r--lib/libc/gen/sem_new.c16
-rw-r--r--lib/libc/gen/wordexp.c5
-rw-r--r--lib/libc/include/compat.h2
-rw-r--r--lib/libc/locale/btowc.34
-rw-r--r--lib/libc/locale/isblank.32
-rw-r--r--lib/libc/net/getaddrinfo.310
-rw-r--r--lib/libc/net/getnameinfo.36
-rw-r--r--lib/libc/net/nscachedcli.c9
-rw-r--r--lib/libc/net/sctp_sys_calls.c310
-rw-r--r--lib/libc/regex/regcomp.c2
-rw-r--r--lib/libc/rpc/clnt_vc.c2
-rw-r--r--lib/libc/stdio/Makefile.inc4
-rw-r--r--lib/libc/stdio/Symbol.map2
-rw-r--r--lib/libc/stdio/fgetln.c2
-rw-r--r--lib/libc/stdio/fopen.32
-rw-r--r--lib/libc/stdio/fwalk.c1
-rw-r--r--lib/libc/stdio/open_memstream.3155
-rw-r--r--lib/libc/stdio/open_memstream.c209
-rw-r--r--lib/libc/stdio/open_wmemstream.c271
-rw-r--r--lib/libc/stdio/setbuf.317
-rw-r--r--lib/libc/stdlib/bsearch.38
-rw-r--r--lib/libc/stdlib/qsort.342
-rw-r--r--lib/libc/stdlib/rand.36
-rw-r--r--lib/libc/stdlib/rand.c33
-rw-r--r--lib/libc/stdlib/random.36
-rw-r--r--lib/libc/stdlib/random.c42
-rw-r--r--lib/libc/stdlib/realpath.32
-rw-r--r--lib/libc/stdtime/Makefile.inc3
-rw-r--r--lib/libc/string/Makefile.inc9
-rw-r--r--lib/libc/string/Symbol.map1
-rw-r--r--lib/libc/string/strchr.331
-rw-r--r--lib/libc/string/strchrnul.c48
-rw-r--r--lib/libc/sys/Makefile.inc303
-rw-r--r--lib/libc/sys/Symbol.map11
-rw-r--r--lib/libc/sys/accept.216
-rw-r--r--lib/libc/sys/bindat.2109
-rw-r--r--lib/libc/sys/cap_enter.239
-rw-r--r--lib/libc/sys/cap_fcntls_limit.2126
-rw-r--r--lib/libc/sys/cap_ioctls_limit.2157
-rw-r--r--lib/libc/sys/cap_rights_limit.2 (renamed from lib/libc/sys/cap_new.2)398
-rw-r--r--lib/libc/sys/chflags.259
-rw-r--r--lib/libc/sys/connectat.2109
-rw-r--r--lib/libc/sys/dup.26
-rw-r--r--lib/libc/sys/extattr_get_file.26
-rw-r--r--lib/libc/sys/fcntl.24
-rw-r--r--lib/libc/sys/getsockopt.26
-rw-r--r--lib/libc/sys/mlock.29
-rw-r--r--lib/libc/sys/posix_openpt.29
-rw-r--r--lib/libc/sys/recv.29
-rw-r--r--lib/libc/sys/sigqueue.22
-rw-r--r--lib/libc/sys/socket.211
-rw-r--r--lib/libc/sys/socketpair.211
61 files changed, 2718 insertions, 705 deletions
diff --git a/lib/libc/arm/aeabi/Makefile.inc b/lib/libc/arm/aeabi/Makefile.inc
index ac147c0..379eb23 100644
--- a/lib/libc/arm/aeabi/Makefile.inc
+++ b/lib/libc/arm/aeabi/Makefile.inc
@@ -7,5 +7,24 @@ SRCS+= aeabi_atexit.c \
aeabi_float.c \
aeabi_unwind_cpp.c
+# Add the aeabi_mem* functions. While they live in compiler-rt they call into
+# libc. This causes issues when other parts of libc call these functions.
+# We work around this by including these functions in libc but mark them as
+# hidden so users of libc will not pick up these versions.
+.PATH: ${.CURDIR}/../../contrib/compiler-rt/lib/arm
+
+SRCS+= aeabi_memcmp.S \
+ aeabi_memcpy.S \
+ aeabi_memmove.S \
+ aeabi_memset.S
+
+# Mark the functions as hidden so they are not available outside of libc.
+CFLAGS.aeabi_memcmp.S= -DVISIBILITY_HIDDEN
+CFLAGS.aeabi_memcpy.S= -DVISIBILITY_HIDDEN
+CFLAGS.aeabi_memmove.S= -DVISIBILITY_HIDDEN
+CFLAGS.aeabi_memset.S= -DVISIBILITY_HIDDEN
+CFLAGS+= ${CFLAGS.${.IMPSRC:T}}
+
+
SYM_MAPS+=${.CURDIR}/arm/aeabi/Symbol.map
diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc
index 0bbbb33..fac1e43 100644
--- a/lib/libc/gen/Makefile.inc
+++ b/lib/libc/gen/Makefile.inc
@@ -4,37 +4,145 @@
# machine-independent gen sources
.PATH: ${.CURDIR}/${LIBC_ARCH}/gen ${.CURDIR}/gen
-SRCS+= __getosreldate.c __xuname.c \
- _once_stub.c _pthread_stubs.c _rand48.c _spinlock_stub.c \
+SRCS+= __getosreldate.c \
+ __xuname.c \
+ _once_stub.c \
+ _pthread_stubs.c \
+ _rand48.c \
+ _spinlock_stub.c \
_thread_init.c \
- alarm.c arc4random.c assert.c auxv.c basename.c check_utility_compat.c \
- clock.c clock_getcpuclockid.c closedir.c confstr.c \
- crypt.c ctermid.c daemon.c devname.c dirfd.c dirname.c disklabel.c \
- dlfcn.c drand48.c elf_utils.c erand48.c err.c errlst.c errno.c \
- exec.c fdevname.c feature_present.c fmtcheck.c fmtmsg.c fnmatch.c \
- fpclassify.c frexp.c fstab.c ftok.c fts.c fts-compat.c ftw.c \
- getbootfile.c getbsize.c \
- getcap.c getcwd.c getdomainname.c getgrent.c getgrouplist.c \
- gethostname.c getloadavg.c getlogin.c getmntinfo.c getnetgrent.c \
- getosreldate.c getpagesize.c getpagesizes.c \
- getpeereid.c getprogname.c getpwent.c getttyent.c \
- getusershell.c getutxent.c getvfsbyname.c glob.c \
- initgroups.c isatty.c isinf.c isnan.c jrand48.c lcong48.c \
+ alarm.c \
+ arc4random.c \
+ assert.c \
+ auxv.c \
+ basename.c \
+ cap_sandboxed.c \
+ check_utility_compat.c \
+ clock.c \
+ clock_getcpuclockid.c \
+ closedir.c \
+ confstr.c \
+ crypt.c \
+ ctermid.c \
+ daemon.c \
+ devname.c \
+ dirfd.c \
+ dirname.c \
+ disklabel.c \
+ dlfcn.c \
+ drand48.c \
+ elf_utils.c \
+ erand48.c \
+ err.c \
+ errlst.c \
+ errno.c \
+ exec.c \
+ fdevname.c \
+ feature_present.c \
+ fmtcheck.c \
+ fmtmsg.c \
+ fnmatch.c \
+ fpclassify.c \
+ frexp.c \
+ fstab.c \
+ ftok.c \
+ fts.c \
+ fts-compat.c \
+ ftw.c \
+ getbootfile.c \
+ getbsize.c \
+ getcap.c \
+ getcwd.c \
+ getdomainname.c \
+ getgrent.c \
+ getgrouplist.c \
+ gethostname.c \
+ getloadavg.c \
+ getlogin.c \
+ getmntinfo.c \
+ getnetgrent.c \
+ getosreldate.c \
+ getpagesize.c \
+ getpagesizes.c \
+ getpeereid.c \
+ getprogname.c \
+ getpwent.c \
+ getttyent.c \
+ getusershell.c \
+ getutxent.c \
+ getvfsbyname.c \
+ glob.c \
+ initgroups.c \
+ isatty.c \
+ isinf.c \
+ isnan.c \
+ jrand48.c \
+ lcong48.c \
libc_dlopen.c \
- lockf.c lrand48.c mrand48.c nftw.c nice.c \
- nlist.c nrand48.c opendir.c \
- pause.c pmadvise.c popen.c posix_spawn.c \
- psignal.c pututxline.c pw_scan.c \
- raise.c readdir.c readpassphrase.c rewinddir.c \
- scandir.c seed48.c seekdir.c semctl.c \
- setdomainname.c sethostname.c setjmperr.c setmode.c \
- setproctitle.c setprogname.c siginterrupt.c siglist.c signal.c \
- sigsetops.c sleep.c srand48.c statvfs.c stringlist.c strtofflags.c \
- sysconf.c sysctl.c sysctlbyname.c sysctlnametomib.c \
- syslog.c telldir.c termios.c time.c times.c timezone.c tls.c \
- ttyname.c ttyslot.c ualarm.c ulimit.c uname.c unvis-compat.c \
- usleep.c utime.c utxdb.c valloc.c wait.c wait3.c waitpid.c \
- waitid.c wordexp.c
+ lockf.c \
+ lrand48.c \
+ mrand48.c \
+ nftw.c \
+ nice.c \
+ nlist.c \
+ nrand48.c \
+ opendir.c \
+ pause.c \
+ pmadvise.c \
+ popen.c \
+ posix_spawn.c \
+ psignal.c \
+ pututxline.c \
+ pw_scan.c \
+ raise.c \
+ readdir.c \
+ readpassphrase.c \
+ rewinddir.c \
+ scandir.c \
+ seed48.c \
+ seekdir.c \
+ semctl.c \
+ setdomainname.c \
+ sethostname.c \
+ setjmperr.c \
+ setmode.c \
+ setproctitle.c \
+ setprogname.c \
+ siginterrupt.c \
+ siglist.c \
+ signal.c \
+ sigsetops.c \
+ sleep.c \
+ srand48.c \
+ statvfs.c \
+ stringlist.c \
+ strtofflags.c \
+ sysconf.c \
+ sysctl.c \
+ sysctlbyname.c \
+ sysctlnametomib.c \
+ syslog.c \
+ telldir.c \
+ termios.c \
+ time.c \
+ times.c \
+ timezone.c \
+ tls.c \
+ ttyname.c \
+ ttyslot.c \
+ ualarm.c \
+ ulimit.c \
+ uname.c \
+ unvis-compat.c \
+ usleep.c \
+ utime.c \
+ utxdb.c \
+ valloc.c \
+ wait.c \
+ wait3.c \
+ waitpid.c \
+ waitid.c \
+ wordexp.c
.PATH: ${.CURDIR}/../../contrib/libc-pwcache
SRCS+= pwcache.c pwcache.h
@@ -58,101 +166,259 @@ SYM_MAPS+=${.CURDIR}/gen/Symbol.map
# machine-dependent gen sources
.sinclude "${.CURDIR}/${LIBC_ARCH}/gen/Makefile.inc"
-MAN+= alarm.3 arc4random.3 \
- basename.3 check_utility_compat.3 clock.3 clock_getcpuclockid.3 \
- confstr.3 ctermid.3 daemon.3 devname.3 directory.3 dirname.3 \
- dl_iterate_phdr.3 dladdr.3 dlinfo.3 dllockinit.3 dlopen.3 \
- err.3 exec.3 \
- feature_present.3 fmtcheck.3 fmtmsg.3 fnmatch.3 fpclassify.3 frexp.3 \
- ftok.3 fts.3 ftw.3 \
- getbootfile.3 getbsize.3 getcap.3 getcontext.3 getcwd.3 \
- getdiskbyname.3 getdomainname.3 getfsent.3 \
- getgrent.3 getgrouplist.3 gethostname.3 getloadavg.3 \
- getmntinfo.3 getnetgrent.3 getosreldate.3 getpagesize.3 \
- getpagesizes.3 getpass.3 getpeereid.3 getprogname.3 getpwent.3 \
- getttyent.3 getusershell.3 getutxent.3 getvfsbyname.3 \
- glob.3 initgroups.3 isgreater.3 ldexp.3 lockf.3 makecontext.3 \
+MAN+= alarm.3 \
+ arc4random.3 \
+ basename.3 \
+ cap_sandboxed.3 \
+ check_utility_compat.3 \
+ clock.3 \
+ clock_getcpuclockid.3 \
+ confstr.3 \
+ ctermid.3 \
+ daemon.3 \
+ devname.3 \
+ directory.3 \
+ dirname.3 \
+ dl_iterate_phdr.3 \
+ dladdr.3 \
+ dlinfo.3 \
+ dllockinit.3 \
+ dlopen.3 \
+ err.3 \
+ exec.3 \
+ feature_present.3 \
+ fmtcheck.3 \
+ fmtmsg.3 \
+ fnmatch.3 \
+ fpclassify.3 \
+ frexp.3 \
+ ftok.3 \
+ fts.3 \
+ ftw.3 \
+ getbootfile.3 \
+ getbsize.3 \
+ getcap.3 \
+ getcontext.3 \
+ getcwd.3 \
+ getdiskbyname.3 \
+ getdomainname.3 \
+ getfsent.3 \
+ getgrent.3 \
+ getgrouplist.3 \
+ gethostname.3 \
+ getloadavg.3 \
+ getmntinfo.3 \
+ getnetgrent.3 \
+ getosreldate.3 \
+ getpagesize.3 \
+ getpagesizes.3 \
+ getpass.3 \
+ getpeereid.3 \
+ getprogname.3 \
+ getpwent.3 \
+ getttyent.3 \
+ getusershell.3 \
+ getutxent.3 \
+ getvfsbyname.3 \
+ glob.3 \
+ initgroups.3 \
+ isgreater.3 \
+ ldexp.3 \
+ lockf.3 \
+ makecontext.3 \
modf.3 \
- nice.3 nlist.3 pause.3 popen.3 \
- posix_spawn.3 posix_spawn_file_actions_addopen.3 \
- posix_spawn_file_actions_init.3 posix_spawnattr_getflags.3 \
- posix_spawnattr_getpgroup.3 posix_spawnattr_getschedparam.3 \
- posix_spawnattr_getschedpolicy.3 posix_spawnattr_init.3 \
- posix_spawnattr_getsigdefault.3 posix_spawnattr_getsigmask.3 \
- psignal.3 pwcache.3 \
- raise.3 rand48.3 readpassphrase.3 rfork_thread.3 \
- scandir.3 sem_destroy.3 sem_getvalue.3 sem_init.3 \
- sem_open.3 sem_post.3 sem_timedwait.3 sem_wait.3 \
- setjmp.3 setmode.3 setproctitle.3 \
- siginterrupt.3 signal.3 sigsetops.3 sleep.3 \
- statvfs.3 stringlist.3 \
- strtofflags.3 sysconf.3 sysctl.3 syslog.3 tcgetpgrp.3 tcgetsid.3 \
- tcsendbreak.3 tcsetattr.3 tcsetpgrp.3 tcsetsid.3 time.3 times.3 \
- timezone.3 ttyname.3 tzset.3 ualarm.3 ucontext.3 ulimit.3 uname.3 \
- unvis.3 usleep.3 utime.3 valloc.3 vis.3 wordexp.3
+ nice.3 \
+ nlist.3 \
+ pause.3 \
+ popen.3 \
+ posix_spawn.3 \
+ posix_spawn_file_actions_addopen.3 \
+ posix_spawn_file_actions_init.3 \
+ posix_spawnattr_getflags.3 \
+ posix_spawnattr_getpgroup.3 \
+ posix_spawnattr_getschedparam.3 \
+ posix_spawnattr_getschedpolicy.3 \
+ posix_spawnattr_init.3 \
+ posix_spawnattr_getsigdefault.3 \
+ posix_spawnattr_getsigmask.3 \
+ psignal.3 \
+ pwcache.3 \
+ raise.3 \
+ rand48.3 \
+ readpassphrase.3 \
+ rfork_thread.3 \
+ scandir.3 \
+ sem_destroy.3 \
+ sem_getvalue.3 \
+ sem_init.3 \
+ sem_open.3 \
+ sem_post.3 \
+ sem_timedwait.3 \
+ sem_wait.3 \
+ setjmp.3 \
+ setmode.3 \
+ setproctitle.3 \
+ siginterrupt.3 \
+ signal.3 \
+ sigsetops.3 \
+ sleep.3 \
+ statvfs.3 \
+ stringlist.3 \
+ strtofflags.3 \
+ sysconf.3 \
+ sysctl.3 \
+ syslog.3 \
+ tcgetpgrp.3 \
+ tcgetsid.3 \
+ tcsendbreak.3 \
+ tcsetattr.3 \
+ tcsetpgrp.3 \
+ tcsetsid.3 \
+ time.3 \
+ times.3 \
+ timezone.3 \
+ ttyname.3 \
+ tzset.3 \
+ ualarm.3 \
+ ucontext.3 \
+ ulimit.3 \
+ uname.3 \
+ unvis.3 \
+ usleep.3 \
+ utime.3 \
+ valloc.3 \
+ vis.3 \
+ wordexp.3
-MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3 \
- arc4random.3 arc4random_buf.3 arc4random.3 arc4random_uniform.3
+MLINKS+=arc4random.3 arc4random_addrandom.3 \
+ arc4random.3 arc4random_stir.3 \
+ arc4random.3 arc4random_buf.3 \
+ arc4random.3 arc4random_uniform.3
MLINKS+=basename.3 basename_r.3
MLINKS+=ctermid.3 ctermid_r.3
MLINKS+=devname.3 devname_r.3
MLINKS+=devname.3 fdevname.3
MLINKS+=devname.3 fdevname_r.3
-MLINKS+=directory.3 closedir.3 directory.3 dirfd.3 directory.3 opendir.3 \
+MLINKS+=directory.3 closedir.3 \
+ directory.3 dirfd.3 \
+ directory.3 opendir.3 \
directory.3 fdopendir.3 \
- directory.3 readdir.3 directory.3 readdir_r.3 directory.3 rewinddir.3 \
- directory.3 seekdir.3 directory.3 telldir.3
-MLINKS+=dlopen.3 fdlopen.3 dlopen.3 dlclose.3 dlopen.3 dlerror.3 \
- dlopen.3 dlfunc.3 dlopen.3 dlsym.3
-MLINKS+=err.3 err_set_exit.3 err.3 err_set_file.3 err.3 errc.3 err.3 errx.3 \
- err.3 verr.3 err.3 verrc.3 err.3 verrx.3 err.3 vwarn.3 err.3 vwarnc.3 \
- err.3 vwarnx.3 err.3 warnc.3 err.3 warn.3 err.3 warnx.3
-MLINKS+=exec.3 execl.3 exec.3 execle.3 exec.3 execlp.3 exec.3 exect.3 \
- exec.3 execv.3 exec.3 execvP.3 exec.3 execvp.3
-MLINKS+=fpclassify.3 finite.3 fpclassify.3 finitef.3 \
- fpclassify.3 isfinite.3 fpclassify.3 isinf.3 fpclassify.3 isnan.3 \
+ directory.3 readdir.3 \
+ directory.3 readdir_r.3 \
+ directory.3 rewinddir.3 \
+ directory.3 seekdir.3 \
+ directory.3 telldir.3
+MLINKS+=dlopen.3 fdlopen.3 \
+ dlopen.3 dlclose.3 \
+ dlopen.3 dlerror.3 \
+ dlopen.3 dlfunc.3 \
+ dlopen.3 dlsym.3
+MLINKS+=err.3 err_set_exit.3 \
+ err.3 err_set_file.3 \
+ err.3 errc.3 \
+ err.3 errx.3 \
+ err.3 verr.3 \
+ err.3 verrc.3 \
+ err.3 verrx.3 \
+ err.3 vwarn.3 \
+ err.3 vwarnc.3 \
+ err.3 vwarnx.3 \
+ err.3 warnc.3 \
+ err.3 warn.3 \
+ err.3 warnx.3
+MLINKS+=exec.3 execl.3 \
+ exec.3 execle.3 \
+ exec.3 execlp.3 \
+ exec.3 exect.3 \
+ exec.3 execv.3 \
+ exec.3 execvP.3 \
+ exec.3 execvp.3
+MLINKS+=fpclassify.3 finite.3 \
+ fpclassify.3 finitef.3 \
+ fpclassify.3 isfinite.3 \
+ fpclassify.3 isinf.3 \
+ fpclassify.3 isnan.3 \
fpclassify.3 isnormal.3
-MLINKS+=frexp.3 frexpf.3 frexp.3 frexpl.3
-MLINKS+=fts.3 fts_children.3 fts.3 fts_close.3 fts.3 fts_open.3 \
- fts.3 fts_read.3 fts.3 fts_set.3 fts.3 fts_set_clientptr.3 \
- fts.3 fts_get_clientptr.3 fts.3 fts_get_stream.3
+MLINKS+=frexp.3 frexpf.3 \
+ frexp.3 frexpl.3
+MLINKS+=fts.3 fts_children.3 \
+ fts.3 fts_close.3 \
+ fts.3 fts_open.3 \
+ fts.3 fts_read.3 \
+ fts.3 fts_set.3 \
+ fts.3 fts_set_clientptr.3 \
+ fts.3 fts_get_clientptr.3 \
+ fts.3 fts_get_stream.3
MLINKS+=ftw.3 nftw.3
-MLINKS+=getcap.3 cgetcap.3 getcap.3 cgetclose.3 getcap.3 cgetent.3 \
- getcap.3 cgetfirst.3 getcap.3 cgetmatch.3 getcap.3 cgetnext.3 \
- getcap.3 cgetnum.3 getcap.3 cgetset.3 getcap.3 cgetstr.3 \
+MLINKS+=getcap.3 cgetcap.3 \
+ getcap.3 cgetclose.3 \
+ getcap.3 cgetent.3 \
+ getcap.3 cgetfirst.3 \
+ getcap.3 cgetmatch.3 \
+ getcap.3 cgetnext.3 \
+ getcap.3 cgetnum.3 \
+ getcap.3 cgetset.3 \
+ getcap.3 cgetstr.3 \
getcap.3 cgetustr.3
MLINKS+=getcwd.3 getwd.3
+MLINKS+=getcontext.3 getcontextx.3
MLINKS+=getcontext.3 setcontext.3
MLINKS+=getdomainname.3 setdomainname.3
-MLINKS+=getfsent.3 endfsent.3 getfsent.3 getfsfile.3 getfsent.3 getfsspec.3 \
- getfsent.3 getfstype.3 getfsent.3 setfsent.3 \
- getfsent.3 setfstab.3 getfsent.3 getfstab.3
-MLINKS+=getgrent.3 endgrent.3 getgrent.3 getgrgid.3 getgrent.3 getgrnam.3 \
- getgrent.3 setgrent.3 getgrent.3 setgroupent.3 \
- getgrent.3 getgrent_r.3 getgrent.3 getgrnam_r.3 getgrent.3 getgrgid_r.3
+MLINKS+=getfsent.3 endfsent.3 \
+ getfsent.3 getfsfile.3 \
+ getfsent.3 getfsspec.3 \
+ getfsent.3 getfstype.3 \
+ getfsent.3 setfsent.3 \
+ getfsent.3 setfstab.3 \
+ getfsent.3 getfstab.3
+MLINKS+=getgrent.3 endgrent.3 \
+ getgrent.3 getgrgid.3 \
+ getgrent.3 getgrnam.3 \
+ getgrent.3 setgrent.3 \
+ getgrent.3 setgroupent.3 \
+ getgrent.3 getgrent_r.3 \
+ getgrent.3 getgrnam_r.3 \
+ getgrent.3 getgrgid_r.3
MLINKS+=gethostname.3 sethostname.3
-MLINKS+=getnetgrent.3 endnetgrent.3 getnetgrent.3 innetgr.3 \
+MLINKS+=getnetgrent.3 endnetgrent.3 \
+ getnetgrent.3 innetgr.3 \
getnetgrent.3 setnetgrent.3
MLINKS+=getprogname.3 setprogname.3
-MLINKS+=getpwent.3 endpwent.3 getpwent.3 getpwnam.3 getpwent.3 getpwuid.3 \
- getpwent.3 setpassent.3 getpwent.3 setpwent.3 getpwent.3 setpwfile.3 \
- getpwent.3 getpwent_r.3 getpwent.3 getpwnam_r.3 \
+MLINKS+=getpwent.3 endpwent.3 \
+ getpwent.3 getpwnam.3 \
+ getpwent.3 getpwuid.3 \
+ getpwent.3 setpassent.3 \
+ getpwent.3 setpwent.3 \
+ getpwent.3 setpwfile.3 \
+ getpwent.3 getpwent_r.3 \
+ getpwent.3 getpwnam_r.3 \
getpwent.3 getpwuid_r.3
-MLINKS+=getttyent.3 endttyent.3 getttyent.3 getttynam.3 \
- getttyent.3 isdialuptty.3 getttyent.3 isnettty.3 \
+MLINKS+=getttyent.3 endttyent.3 \
+ getttyent.3 getttynam.3 \
+ getttyent.3 isdialuptty.3 \
+ getttyent.3 isnettty.3 \
getttyent.3 setttyent.3
-MLINKS+=getusershell.3 endusershell.3 getusershell.3 setusershell.3
-MLINKS+=getutxent.3 endutxent.3 getutxent.3 getutxid.3 \
- getutxent.3 getutxline.3 getutxent.3 getutxuser.3 \
- getutxent.3 pututxline.3 getutxent.3 setutxdb.3 \
- getutxent.3 setutxent.3 getutxent.3 utmpx.3
+MLINKS+=getusershell.3 endusershell.3 \
+ getusershell.3 setusershell.3
+MLINKS+=getutxent.3 endutxent.3 \
+ getutxent.3 getutxid.3 \
+ getutxent.3 getutxline.3 \
+ getutxent.3 getutxuser.3 \
+ getutxent.3 pututxline.3 \
+ getutxent.3 setutxdb.3 \
+ getutxent.3 setutxent.3 \
+ getutxent.3 utmpx.3
MLINKS+=glob.3 globfree.3
-MLINKS+=isgreater.3 isgreaterequal.3 isgreater.3 isless.3 \
- isgreater.3 islessequal.3 isgreater.3 islessgreater.3 \
+MLINKS+=isgreater.3 isgreaterequal.3 \
+ isgreater.3 isless.3 \
+ isgreater.3 islessequal.3 \
+ isgreater.3 islessgreater.3 \
isgreater.3 isunordered.3
-MLINKS+=ldexp.3 ldexpf.3 ldexp.3 ldexpl.3
+MLINKS+=ldexp.3 ldexpf.3 \
+ ldexp.3 ldexpl.3
MLINKS+=makecontext.3 swapcontext.3
-MLINKS+=modf.3 modff.3 modf.3 modfl.3
+MLINKS+=modf.3 modff.3 \
+ modf.3 modfl.3
MLINKS+=popen.3 pclose.3
MLINKS+=posix_spawn.3 posix_spawnp.3 \
posix_spawn_file_actions_addopen.3 posix_spawn_file_actions_addclose.3 \
@@ -165,36 +431,80 @@ MLINKS+=posix_spawn.3 posix_spawnp.3 \
posix_spawnattr_getsigdefault.3 posix_spawnattr_setsigdefault.3 \
posix_spawnattr_getsigmask.3 posix_spawnattr_setsigmask.3 \
posix_spawnattr_init.3 posix_spawnattr_destroy.3
-MLINKS+=psignal.3 strsignal.3 psignal.3 sys_siglist.3 psignal.3 sys_signame.3
-MLINKS+=pwcache.3 group_from_gid.3 pwcache.3 user_from_uid.3
-MLINKS+=rand48.3 _rand48.3 rand48.3 drand48.3 rand48.3 erand48.3 \
- rand48.3 jrand48.3 rand48.3 lcong48.3 rand48.3 lrand48.3 \
- rand48.3 mrand48.3 rand48.3 nrand48.3 rand48.3 seed48.3 \
+MLINKS+=psignal.3 strsignal.3 \
+ psignal.3 sys_siglist.3 \
+ psignal.3 sys_signame.3
+MLINKS+=pwcache.3 group_from_gid.3 \
+ pwcache.3 user_from_uid.3
+MLINKS+=rand48.3 _rand48.3 \
+ rand48.3 drand48.3 \
+ rand48.3 erand48.3 \
+ rand48.3 jrand48.3 \
+ rand48.3 lcong48.3 \
+ rand48.3 lrand48.3 \
+ rand48.3 mrand48.3 \
+ rand48.3 nrand48.3 \
+ rand48.3 seed48.3 \
rand48.3 srand48.3
MLINKS+=scandir.3 alphasort.3
-MLINKS+=sem_open.3 sem_close.3 sem_open.3 sem_unlink.3
+MLINKS+=sem_open.3 sem_close.3 \
+ sem_open.3 sem_unlink.3
MLINKS+=sem_wait.3 sem_trywait.3
-MLINKS+=setjmp.3 _longjmp.3 setjmp.3 _setjmp.3 setjmp.3 longjmp.3 \
- setjmp.3 longjmperr.3 setjmp.3 longjmperror.3 \
- setjmp.3 siglongjmp.3 setjmp.3 sigsetjmp.3
+MLINKS+=setjmp.3 _longjmp.3 \
+ setjmp.3 _setjmp.3 \
+ setjmp.3 longjmp.3 \
+ setjmp.3 longjmperr.3 \
+ setjmp.3 longjmperror.3 \
+ setjmp.3 siglongjmp.3 \
+ setjmp.3 sigsetjmp.3
MLINKS+=setmode.3 getmode.3
-MLINKS+=sigsetops.3 sigaddset.3 sigsetops.3 sigdelset.3 \
- sigsetops.3 sigemptyset.3 sigsetops.3 sigfillset.3 \
+MLINKS+=sigsetops.3 sigaddset.3 \
+ sigsetops.3 sigdelset.3 \
+ sigsetops.3 sigemptyset.3 \
+ sigsetops.3 sigfillset.3 \
sigsetops.3 sigismember.3
MLINKS+=statvfs.3 fstatvfs.3
-MLINKS+=stringlist.3 sl_add.3 stringlist.3 sl_find.3 \
- stringlist.3 sl_free.3 stringlist.3 sl_init.3
+MLINKS+=stringlist.3 sl_add.3 \
+ stringlist.3 sl_find.3 \
+ stringlist.3 sl_free.3 \
+ stringlist.3 sl_init.3
MLINKS+=strtofflags.3 fflagstostr.3
-MLINKS+=sysctl.3 sysctlbyname.3 sysctl.3 sysctlnametomib.3
-MLINKS+=syslog.3 closelog.3 syslog.3 openlog.3 syslog.3 setlogmask.3 \
+MLINKS+=sysctl.3 sysctlbyname.3 \
+ sysctl.3 sysctlnametomib.3
+MLINKS+=syslog.3 closelog.3 \
+ syslog.3 openlog.3 \
+ syslog.3 setlogmask.3 \
syslog.3 vsyslog.3
-MLINKS+=tcsendbreak.3 tcdrain.3 tcsendbreak.3 tcflow.3 tcsendbreak.3 tcflush.3
-MLINKS+=tcsetattr.3 cfgetispeed.3 tcsetattr.3 cfgetospeed.3 \
- tcsetattr.3 cfmakeraw.3 tcsetattr.3 cfmakesane.3 \
- tcsetattr.3 cfsetispeed.3 tcsetattr.3 cfsetospeed.3 \
- tcsetattr.3 cfsetspeed.3 tcsetattr.3 tcgetattr.3
-MLINKS+=ttyname.3 isatty.3 ttyname.3 ttyname_r.3
+MLINKS+=tcsendbreak.3 tcdrain.3 \
+ tcsendbreak.3 tcflow.3 \
+ tcsendbreak.3 tcflush.3
+MLINKS+=tcsetattr.3 cfgetispeed.3 \
+ tcsetattr.3 cfgetospeed.3 \
+ tcsetattr.3 cfmakeraw.3 \
+ tcsetattr.3 cfmakesane.3 \
+ tcsetattr.3 cfsetispeed.3 \
+ tcsetattr.3 cfsetospeed.3 \
+ tcsetattr.3 cfsetspeed.3 \
+ tcsetattr.3 tcgetattr.3
+MLINKS+=ttyname.3 isatty.3 \
+ ttyname.3 ttyname_r.3
MLINKS+=tzset.3 tzsetwall.3
-MLINKS+=unvis.3 strunvis.3 unvis.3 strunvisx.3
-MLINKS+=vis.3 strvis.3 vis.3 strvisx.3
+MLINKS+=unvis.3 strunvis.3 \
+ unvis.3 strunvisx.3
+MLINKS+=vis.3 nvis.3 \
+ vis.3 snvis.3 \
+ vis.3 strenvisx.3 \
+ vis.3 strnunvis.3 \
+ vis.3 strnunvisx.3 \
+ vis.3 strnvis.3 \
+ vis.3 strnvisx.3 \
+ vis.3 strsenvisx.3 \
+ vis.3 strsnvis.3 \
+ vis.3 strsnvisx.3 \
+ vis.3 strsvis.3 \
+ vis.3 strsvisx.3 \
+ vis.3 strvis.3 \
+ vis.3 strvisx.3 \
+ vis.3 svis.3
+
MLINKS+=wordexp.3 wordfree.3
diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map
index 4cbf07c..2438951 100644
--- a/lib/libc/gen/Symbol.map
+++ b/lib/libc/gen/Symbol.map
@@ -391,10 +391,12 @@ FBSD_1.3 {
pwcache_userdb;
pwcache_groupdb;
snvis;
+ strenvisx;
strnunvis;
strnunvisx;
strnvis;
strnvisx;
+ strsenvisx;
strsnvis;
strsnvisx;
strsvis;
diff --git a/lib/libc/gen/cap_sandboxed.3 b/lib/libc/gen/cap_sandboxed.3
new file mode 100644
index 0000000..067d6d2
--- /dev/null
+++ b/lib/libc/gen/cap_sandboxed.3
@@ -0,0 +1,70 @@
+.\" Copyright (c) 2012 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
+.\" from the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 18, 2012
+.Dt CAP_SANDBOXED 3
+.Os
+.Sh NAME
+.Nm cap_sandboxed
+.Nd Check if in a capability mode sandbox
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/capability.h
+.In stdbool.h
+.Ft bool
+.Fn cap_sandboxed "void"
+.Sh DESCRIPTION
+.Fn cap_sandboxed
+returns
+.Va true
+if the process is in a capability mode sandbox or
+.Va false
+if it is not.
+This function is a more handy alternative to the
+.Xr cap_getmode 2
+system call as it always succeeds, so there is no need for error checking.
+If the support for capability mode is not compiled into the kernel,
+.Fn cap_sandboxed
+will always return
+.Va false .
+.Sh RETURN VALUES
+Function
+.Fn cap_sandboxed
+is always successful and will return either
+.Va true
+or
+.Va false .
+.Sh SEE ALSO
+.Xr cap_enter 2 ,
+.Xr capsicum 4
+.Sh AUTHORS
+This function was implemented and manual page was written by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship of the FreeBSD Foundation.
diff --git a/lib/libc/gen/cap_sandboxed.c b/lib/libc/gen/cap_sandboxed.c
new file mode 100644
index 0000000..baa9b3f
--- /dev/null
+++ b/lib/libc/gen/cap_sandboxed.c
@@ -0,0 +1,50 @@
+/*-
+ * Copyright (c) 2012 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Pawel Jakub Dawidek under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/capability.h>
+
+#include <assert.h>
+#include <errno.h>
+#include <stdbool.h>
+
+bool
+cap_sandboxed(void)
+{
+ u_int mode;
+
+ if (cap_getmode(&mode) != 0) {
+ assert(errno == ENOSYS);
+ return (false);
+ }
+ assert(mode == 0 || mode == 1);
+ return (mode == 1);
+}
diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c
index 243320c..d15be06 100644
--- a/lib/libc/gen/fts.c
+++ b/lib/libc/gen/fts.c
@@ -1119,7 +1119,8 @@ fts_safe_changedir(FTS *sp, FTSENT *p, int fd, char *path)
newfd = fd;
if (ISSET(FTS_NOCHDIR))
return (0);
- if (fd < 0 && (newfd = _open(path, O_RDONLY | O_CLOEXEC, 0)) < 0)
+ if (fd < 0 && (newfd = _open(path, O_RDONLY | O_DIRECTORY |
+ O_CLOEXEC, 0)) < 0)
return (-1);
if (_fstat(newfd, &sb)) {
ret = -1;
diff --git a/lib/libc/gen/getcontext.3 b/lib/libc/gen/getcontext.3
index 5b801fd..9e3e4fc 100644
--- a/lib/libc/gen/getcontext.3
+++ b/lib/libc/gen/getcontext.3
@@ -35,7 +35,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 26, 2011
+.Dd March 13, 2013
.Dt GETCONTEXT 3
.Os
.Sh NAME
@@ -47,6 +47,8 @@
.In ucontext.h
.Ft int
.Fn getcontext "ucontext_t *ucp"
+.Ft ucontext_t *
+.Fn getcontextx "void"
.Ft int
.Fn setcontext "const ucontext_t *ucp"
.Sh DESCRIPTION
diff --git a/lib/libc/gen/glob.c b/lib/libc/gen/glob.c
index 832dc8d..95a3a06 100644
--- a/lib/libc/gen/glob.c
+++ b/lib/libc/gen/glob.c
@@ -738,7 +738,7 @@ glob3(Char *pathbuf, Char *pathend, Char *pathend_last,
/*
- * Extend the gl_pathv member of a glob_t structure to accomodate a new item,
+ * Extend the gl_pathv member of a glob_t structure to accommodate a new item,
* add the new item, and update gl_pathc.
*
* This assumes the BSD realloc, which only copies the block when its size
diff --git a/lib/libc/gen/opendir.c b/lib/libc/gen/opendir.c
index 2d505fc..a9eb0af 100644
--- a/lib/libc/gen/opendir.c
+++ b/lib/libc/gen/opendir.c
@@ -49,7 +49,7 @@ __FBSDID("$FreeBSD$");
#include "gen-private.h"
#include "telldir.h"
-static DIR * __opendir_common(int, const char *, int);
+static DIR * __opendir_common(int, int);
/*
* Open a directory.
@@ -78,7 +78,7 @@ fdopendir(int fd)
}
if (_fcntl(fd, F_SETFD, FD_CLOEXEC) == -1)
return (NULL);
- return (__opendir_common(fd, NULL, DTF_HIDEW|DTF_NODUP));
+ return (__opendir_common(fd, DTF_HIDEW|DTF_NODUP));
}
DIR *
@@ -92,7 +92,7 @@ __opendir2(const char *name, int flags)
O_RDONLY | O_NONBLOCK | O_DIRECTORY | O_CLOEXEC)) == -1)
return (NULL);
- dir = __opendir_common(fd, name, flags);
+ dir = __opendir_common(fd, flags);
if (dir == NULL) {
saved_errno = errno;
_close(fd);
@@ -113,7 +113,7 @@ opendir_compar(const void *p1, const void *p2)
* Common routine for opendir(3), __opendir2(3) and fdopendir(3).
*/
static DIR *
-__opendir_common(int fd, const char *name, int flags)
+__opendir_common(int fd, int flags)
{
DIR *dirp;
int incr;
@@ -121,6 +121,8 @@ __opendir_common(int fd, const char *name, int flags)
int unionstack;
int fd2;
+ fd2 = -1;
+
if ((dirp = malloc(sizeof(DIR) + sizeof(struct _telldir))) == NULL)
return (NULL);
@@ -165,7 +167,22 @@ __opendir_common(int fd, const char *name, int flags)
* entries into a buffer, sort the buffer, and
* remove duplicate entries by setting the inode
* number to zero.
+ *
+ * We reopen the directory because _getdirentries()
+ * on a MNT_UNION mount modifies the open directory,
+ * making it refer to the lower directory after the
+ * upper directory's entries are exhausted.
+ * This would otherwise break software that uses
+ * the directory descriptor for fchdir or *at
+ * functions, such as fts.c.
*/
+ if ((fd2 = _openat(fd, ".", O_RDONLY | O_CLOEXEC)) == -1) {
+ saved_errno = errno;
+ free(buf);
+ free(dirp);
+ errno = saved_errno;
+ return (NULL);
+ }
do {
/*
@@ -181,7 +198,7 @@ __opendir_common(int fd, const char *name, int flags)
ddptr = buf + (len - space);
}
- n = _getdirentries(fd, ddptr, space, &dirp->dd_seek);
+ n = _getdirentries(fd2, ddptr, space, &dirp->dd_seek);
if (n > 0) {
ddptr += n;
space -= n;
@@ -191,25 +208,8 @@ __opendir_common(int fd, const char *name, int flags)
ddeptr = ddptr;
flags |= __DTF_READALL;
- /*
- * Re-open the directory.
- * This has the effect of rewinding back to the
- * top of the union stack and is needed by
- * programs which plan to fchdir to a descriptor
- * which has also been read -- see fts.c.
- */
- if (flags & DTF_REWIND) {
- if ((fd2 = _open(name, O_RDONLY | O_DIRECTORY |
- O_CLOEXEC)) == -1) {
- saved_errno = errno;
- free(buf);
- free(dirp);
- errno = saved_errno;
- return (NULL);
- }
- (void)_dup2(fd2, fd);
- _close(fd2);
- }
+ _close(fd2);
+ fd2 = -1;
/*
* There is now a buffer full of (possibly) duplicate
@@ -293,7 +293,6 @@ __opendir_common(int fd, const char *name, int flags)
if (dirp->dd_buf == NULL)
goto fail;
dirp->dd_seek = 0;
- flags &= ~DTF_REWIND;
}
dirp->dd_loc = 0;
@@ -310,6 +309,8 @@ __opendir_common(int fd, const char *name, int flags)
fail:
saved_errno = errno;
+ if (fd2 != -1)
+ _close(fd2);
free(dirp);
errno = saved_errno;
return (NULL);
diff --git a/lib/libc/gen/sem_new.c b/lib/libc/gen/sem_new.c
index b11d547..1bf84ea 100644
--- a/lib/libc/gen/sem_new.c
+++ b/lib/libc/gen/sem_new.c
@@ -198,15 +198,11 @@ _sem_open(const char *name, int flags, ...)
goto error;
}
- fd = _open(path, flags|O_RDWR|O_CLOEXEC, mode);
+ fd = _open(path, flags|O_RDWR|O_CLOEXEC|O_EXLOCK, mode);
if (fd == -1)
goto error;
- if (flock(fd, LOCK_EX) == -1)
+ if (_fstat(fd, &sb))
goto error;
- if (_fstat(fd, &sb)) {
- flock(fd, LOCK_UN);
- goto error;
- }
if (sb.st_size < sizeof(sem_t)) {
sem_t tmp;
@@ -214,10 +210,8 @@ _sem_open(const char *name, int flags, ...)
tmp._kern._has_waiters = 0;
tmp._kern._count = value;
tmp._kern._flags = USYNC_PROCESS_SHARED | SEM_NAMED;
- if (_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp)) {
- flock(fd, LOCK_UN);
+ if (_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp))
goto error;
- }
}
flock(fd, LOCK_UN);
sem = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE,
@@ -235,18 +229,18 @@ _sem_open(const char *name, int flags, ...)
ni->open_count = 1;
ni->sem = sem;
LIST_INSERT_HEAD(&sem_list, ni, next);
- _pthread_mutex_unlock(&sem_llock);
_close(fd);
+ _pthread_mutex_unlock(&sem_llock);
return (sem);
error:
errsave = errno;
- _pthread_mutex_unlock(&sem_llock);
if (fd != -1)
_close(fd);
if (sem != NULL)
munmap(sem, sizeof(sem_t));
free(ni);
+ _pthread_mutex_unlock(&sem_llock);
errno = errsave;
return (SEM_FAILED);
}
diff --git a/lib/libc/gen/wordexp.c b/lib/libc/gen/wordexp.c
index bcab1f5..b518b57 100644
--- a/lib/libc/gen/wordexp.c
+++ b/lib/libc/gen/wordexp.c
@@ -114,15 +114,12 @@ we_askshell(const char *words, wordexp_t *we, int flags)
int status; /* Child exit status */
int error; /* Our return value */
int serrno; /* errno to return */
- char *ifs; /* IFS env. var. */
char *np, *p; /* Handy pointers */
char *nstrings; /* Temporary for realloc() */
char **nwv; /* Temporary for realloc() */
sigset_t newsigblock, oldsigblock;
serrno = errno;
- if ((ifs = getenv("IFS")) == NULL)
- ifs = " \t\n";
if (pipe(pdes) < 0)
return (WRDE_NOSPACE); /* XXX */
@@ -150,7 +147,7 @@ we_askshell(const char *words, wordexp_t *we, int flags)
if (_dup2(pdes[1], STDOUT_FILENO) < 0)
_exit(1);
_close(pdes[1]);
- if (asprintf(&cmd, "wordexp%c%s\n", *ifs, words) < 0)
+ if (asprintf(&cmd, "wordexp %s\n", words) < 0)
_exit(1);
if ((flags & WRDE_SHOWERR) == 0) {
if ((devnull = _open(_PATH_DEVNULL, O_RDWR, 0666)) < 0)
diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h
index 7694540..3739fe1 100644
--- a/lib/libc/include/compat.h
+++ b/lib/libc/include/compat.h
@@ -42,6 +42,8 @@ __sym_compat(__semctl, freebsd7___semctl, FBSD_1.0);
__sym_compat(msgctl, freebsd7_msgctl, FBSD_1.0);
__sym_compat(shmctl, freebsd7_shmctl, FBSD_1.0);
+__sym_compat(cap_getrights, cap_rights_get, FBSD_1.2);
+
#undef __sym_compat
#endif /* __LIBC_COMPAT_H__ */
diff --git a/lib/libc/locale/btowc.3 b/lib/libc/locale/btowc.3
index d9c3e9c..2d8cb49 100644
--- a/lib/libc/locale/btowc.3
+++ b/lib/libc/locale/btowc.3
@@ -42,9 +42,9 @@
.In wchar.h
.In xlocale.h
.Ft wint_t
-.Fn btowc "int c"
+.Fn btowc_l "int c" "locale_t loc"
.Ft int
-.Fn wctob "wint_t c"
+.Fn wctob_l "wint_t c" "locale_t loc"
.Sh DESCRIPTION
The
.Fn btowc
diff --git a/lib/libc/locale/isblank.3 b/lib/libc/locale/isblank.3
index 5542280..731a88b 100644
--- a/lib/libc/locale/isblank.3
+++ b/lib/libc/locale/isblank.3
@@ -41,7 +41,7 @@
.Ft int
.Fn isblank "int c"
.Ft int
-.Fn isblank "int c" "locale_t loc"
+.Fn isblank_l "int c" "locale_t loc"
.Sh DESCRIPTION
The
.Fn isblank
diff --git a/lib/libc/net/getaddrinfo.3 b/lib/libc/net/getaddrinfo.3
index b09c068..3419809 100644
--- a/lib/libc/net/getaddrinfo.3
+++ b/lib/libc/net/getaddrinfo.3
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd January 6, 2009
+.Dd February 14, 2013
.Dt GETADDRINFO 3
.Os
.Sh NAME
@@ -339,7 +339,7 @@ hints.ai_socktype = SOCK_STREAM;
error = getaddrinfo("www.kame.net", "http", &hints, &res0);
if (error) {
errx(1, "%s", gai_strerror(error));
- /*NOTREACHED*/
+ /* NOTREACHED */
}
s = -1;
for (res = res0; res; res = res->ai_next) {
@@ -361,7 +361,7 @@ for (res = res0; res; res = res->ai_next) {
}
if (s < 0) {
err(1, "%s", cause);
- /*NOTREACHED*/
+ /* NOTREACHED */
}
freeaddrinfo(res0);
.Ed
@@ -383,7 +383,7 @@ hints.ai_flags = AI_PASSIVE;
error = getaddrinfo(NULL, "http", &hints, &res0);
if (error) {
errx(1, "%s", gai_strerror(error));
- /*NOTREACHED*/
+ /* NOTREACHED */
}
nsock = 0;
for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
@@ -405,7 +405,7 @@ for (res = res0; res && nsock < MAXSOCK; res = res->ai_next) {
}
if (nsock == 0) {
err(1, "%s", cause);
- /*NOTREACHED*/
+ /* NOTREACHED */
}
freeaddrinfo(res0);
.Ed
diff --git a/lib/libc/net/getnameinfo.3 b/lib/libc/net/getnameinfo.3
index 327c135..e508e5d 100644
--- a/lib/libc/net/getnameinfo.3
+++ b/lib/libc/net/getnameinfo.3
@@ -18,7 +18,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd February 28, 2007
+.Dd February 14, 2013
.Dt GETNAMEINFO 3
.Os
.Sh NAME
@@ -157,7 +157,7 @@ char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) {
errx(1, "could not get numeric hostname");
- /*NOTREACHED*/
+ /* NOTREACHED */
}
printf("host=%s, serv=%s\en", hbuf, sbuf);
.Ed
@@ -170,7 +170,7 @@ char hbuf[NI_MAXHOST];
if (getnameinfo(sa, sa->sa_len, hbuf, sizeof(hbuf), NULL, 0,
NI_NAMEREQD)) {
errx(1, "could not resolve hostname");
- /*NOTREACHED*/
+ /* NOTREACHED */
}
printf("host=%s\en", hbuf);
.Ed
diff --git a/lib/libc/net/nscachedcli.c b/lib/libc/net/nscachedcli.c
index 1323805..b4de0c1 100644
--- a/lib/libc/net/nscachedcli.c
+++ b/lib/libc/net/nscachedcli.c
@@ -75,9 +75,10 @@ safe_write(struct cached_connection_ *connection, const void *data,
nevents = _kevent(connection->write_queue, NULL, 0, &eventlist,
1, &timeout);
if ((nevents == 1) && (eventlist.filter == EVFILT_WRITE)) {
- s_result = _write(connection->sockfd, data + result,
+ s_result = _sendto(connection->sockfd, data + result,
eventlist.data < data_size - result ?
- eventlist.data : data_size - result);
+ eventlist.data : data_size - result, MSG_NOSIGNAL,
+ NULL, 0);
if (s_result == -1)
return (-1);
else
@@ -175,8 +176,8 @@ send_credentials(struct cached_connection_ *connection, int type)
nevents = _kevent(connection->write_queue, NULL, 0, &eventlist, 1,
NULL);
if (nevents == 1 && eventlist.filter == EVFILT_WRITE) {
- result = (_sendmsg(connection->sockfd, &cred_hdr, 0) == -1) ?
- -1 : 0;
+ result = (_sendmsg(connection->sockfd, &cred_hdr,
+ MSG_NOSIGNAL) == -1) ? -1 : 0;
EV_SET(&eventlist, connection->sockfd, EVFILT_WRITE, EV_ADD,
0, 0, NULL);
_kevent(connection->write_queue, &eventlist, 1, NULL, 0, NULL);
diff --git a/lib/libc/net/sctp_sys_calls.c b/lib/libc/net/sctp_sys_calls.c
index beedf94..6b938a4 100644
--- a/lib/libc/net/sctp_sys_calls.c
+++ b/lib/libc/net/sctp_sys_calls.c
@@ -48,8 +48,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/sctp_uio.h>
#include <netinet/sctp.h>
-#include <net/if_dl.h>
-
#ifndef IN6_IS_ADDR_V4MAPPED
#define IN6_IS_ADDR_V4MAPPED(a) \
((*(const uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
@@ -57,77 +55,8 @@ __FBSDID("$FreeBSD$");
(*(const uint32_t *)(const void *)(&(a)->s6_addr[8]) == ntohl(0x0000ffff)))
#endif
-
-#define SCTP_CONTROL_VEC_SIZE_SND 8192
#define SCTP_CONTROL_VEC_SIZE_RCV 16384
-#define SCTP_STACK_BUF_SIZE 2048
-
-#ifdef SCTP_DEBUG_PRINT_ADDRESS
-#define SCTP_STRING_BUF_SZ 256
-
-static void
-SCTPPrintAnAddress(struct sockaddr *a)
-{
- char stringToPrint[SCTP_STRING_BUF_SZ];
- u_short prt;
- char *srcaddr, *txt;
-
- if (a == NULL) {
- printf("NULL\n");
- return;
- }
- if (a->sa_family == AF_INET) {
- srcaddr = (char *)&((struct sockaddr_in *)a)->sin_addr;
- txt = "IPv4 Address: ";
- prt = ntohs(((struct sockaddr_in *)a)->sin_port);
- } else if (a->sa_family == AF_INET6) {
- srcaddr = (char *)&((struct sockaddr_in6 *)a)->sin6_addr;
- prt = ntohs(((struct sockaddr_in6 *)a)->sin6_port);
- txt = "IPv6 Address: ";
- } else if (a->sa_family == AF_LINK) {
- int i;
- char tbuf[SCTP_STRING_BUF_SZ];
- u_char adbuf[SCTP_STRING_BUF_SZ];
- struct sockaddr_dl *dl;
-
- dl = (struct sockaddr_dl *)a;
- strncpy(tbuf, dl->sdl_data, dl->sdl_nlen);
- tbuf[dl->sdl_nlen] = 0;
- printf("Intf:%s (len:%d)Interface index:%d type:%x(%d) ll-len:%d ",
- tbuf,
- dl->sdl_nlen,
- dl->sdl_index,
- dl->sdl_type,
- dl->sdl_type,
- dl->sdl_alen
- );
- memcpy(adbuf, LLADDR(dl), dl->sdl_alen);
- for (i = 0; i < dl->sdl_alen; i++) {
- printf("%2.2x", adbuf[i]);
- if (i < (dl->sdl_alen - 1))
- printf(":");
- }
- printf("\n");
- return;
- } else {
- return;
- }
- if (inet_ntop(a->sa_family, srcaddr, stringToPrint, sizeof(stringToPrint))) {
- if (a->sa_family == AF_INET6) {
- printf("%s%s:%d scope:%d\n",
- txt, stringToPrint, prt,
- ((struct sockaddr_in6 *)a)->sin6_scope_id);
- } else {
- printf("%s%s:%d\n", txt, stringToPrint, prt);
- }
-
- } else {
- printf("%s unprintable?\n", txt);
- }
-}
-
-#endif /* SCTP_DEBUG_PRINT_ADDRESS */
static void
in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
@@ -171,11 +100,10 @@ int
sctp_connectx(int sd, const struct sockaddr *addrs, int addrcnt,
sctp_assoc_t * id)
{
- char buf[SCTP_STACK_BUF_SIZE];
+ char *buf;
int i, ret, cnt, *aa;
char *cpto;
const struct sockaddr *at;
- sctp_assoc_t *p_id;
size_t len = sizeof(int);
/* validate the address count and list */
@@ -183,24 +111,29 @@ sctp_connectx(int sd, const struct sockaddr *addrs, int addrcnt,
errno = EINVAL;
return (-1);
}
+ if ((buf = malloc(sizeof(int) + (size_t)addrcnt * sizeof(struct sockaddr_in6))) == NULL) {
+ errno = E2BIG;
+ return (-1);
+ }
at = addrs;
cnt = 0;
- cpto = ((caddr_t)buf + sizeof(int));
+ cpto = buf + sizeof(int);
/* validate all the addresses and get the size */
for (i = 0; i < addrcnt; i++) {
switch (at->sa_family) {
case AF_INET:
if (at->sa_len != sizeof(struct sockaddr_in)) {
+ free(buf);
errno = EINVAL;
return (-1);
}
memcpy(cpto, at, sizeof(struct sockaddr_in));
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in));
len += sizeof(struct sockaddr_in);
- at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in));
break;
case AF_INET6:
if (at->sa_len != sizeof(struct sockaddr_in6)) {
+ free(buf);
errno = EINVAL;
return (-1);
}
@@ -213,31 +146,20 @@ sctp_connectx(int sd, const struct sockaddr *addrs, int addrcnt,
cpto = ((caddr_t)cpto + sizeof(struct sockaddr_in6));
len += sizeof(struct sockaddr_in6);
}
- at = (struct sockaddr *)((caddr_t)at + sizeof(struct sockaddr_in6));
break;
default:
+ free(buf);
errno = EINVAL;
return (-1);
}
- if (len > (sizeof(buf) - sizeof(int))) {
- /* Never enough memory */
- errno = E2BIG;
- return (-1);
- }
- cnt++;
- }
- /* do we have any? */
- if (cnt == 0) {
- errno = EINVAL;
- return (-1);
+ at = (struct sockaddr *)((caddr_t)at + at->sa_len);
}
aa = (int *)buf;
- *aa = cnt;
+ *aa = addrcnt;
ret = setsockopt(sd, IPPROTO_SCTP, SCTP_CONNECT_X, (void *)buf,
(socklen_t) len);
- if ((ret == 0) && id) {
- p_id = (sctp_assoc_t *) buf;
- *id = *p_id;
+ if ((ret == 0) && (id != NULL)) {
+ *id = *(sctp_assoc_t *) buf;
}
return (ret);
}
@@ -345,7 +267,6 @@ sctp_bindx(int sd, struct sockaddr *addrs, int addrcnt, int flags)
return (0);
}
-
int
sctp_opt_info(int sd, sctp_assoc_t id, int opt, void *arg, socklen_t * size)
{
@@ -471,9 +392,9 @@ sctp_getpaddrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs)
void
sctp_freepaddrs(struct sockaddr *addrs)
{
- /* Take away the hidden association id */
void *fr_addr;
+ /* Take away the hidden association id */
fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
/* Now free it */
free(fr_addr);
@@ -534,15 +455,14 @@ sctp_getladdrs(int sd, sctp_assoc_t id, struct sockaddr **raddrs)
void
sctp_freeladdrs(struct sockaddr *addrs)
{
- /* Take away the hidden association id */
void *fr_addr;
+ /* Take away the hidden association id */
fr_addr = (void *)((caddr_t)addrs - sizeof(sctp_assoc_t));
/* Now free it */
free(fr_addr);
}
-
ssize_t
sctp_sendmsg(int s,
const void *data,
@@ -568,11 +488,10 @@ sctp_sendmsg(int s,
return (syscall(SYS_sctp_generic_sendmsg, s,
data, len, to, tolen, &sinfo, 0));
#else
- ssize_t sz;
struct msghdr msg;
- struct sctp_sndrcvinfo *s_info;
+ struct sctp_sndrcvinfo *sinfo;
struct iovec iov;
- char controlVector[SCTP_CONTROL_VEC_SIZE_RCV];
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
struct cmsghdr *cmsg;
struct sockaddr *who = NULL;
union {
@@ -583,36 +502,39 @@ sctp_sendmsg(int s,
if ((tolen > 0) &&
((to == NULL) || (tolen < sizeof(struct sockaddr)))) {
errno = EINVAL;
- return -1;
+ return (-1);
}
- if (to && (tolen > 0)) {
- if (to->sa_family == AF_INET) {
+ if ((to != NULL) && (tolen > 0)) {
+ switch (to->sa_family) {
+ case AF_INET:
if (tolen != sizeof(struct sockaddr_in)) {
errno = EINVAL;
- return -1;
+ return (-1);
}
if ((to->sa_len > 0) &&
(to->sa_len != sizeof(struct sockaddr_in))) {
errno = EINVAL;
- return -1;
+ return (-1);
}
memcpy(&addr, to, sizeof(struct sockaddr_in));
addr.in.sin_len = sizeof(struct sockaddr_in);
- } else if (to->sa_family == AF_INET6) {
+ break;
+ case AF_INET6:
if (tolen != sizeof(struct sockaddr_in6)) {
errno = EINVAL;
- return -1;
+ return (-1);
}
if ((to->sa_len > 0) &&
(to->sa_len != sizeof(struct sockaddr_in6))) {
errno = EINVAL;
- return -1;
+ return (-1);
}
memcpy(&addr, to, sizeof(struct sockaddr_in6));
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
- } else {
+ break;
+ default:
errno = EAFNOSUPPORT;
- return -1;
+ return (-1);
}
who = (struct sockaddr *)&addr;
}
@@ -628,26 +550,21 @@ sctp_sendmsg(int s,
}
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
- msg.msg_control = (caddr_t)controlVector;
-
- cmsg = (struct cmsghdr *)controlVector;
-
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
+ cmsg = (struct cmsghdr *)cmsgbuf;
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
- s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
-
- s_info->sinfo_stream = stream_no;
- s_info->sinfo_ssn = 0;
- s_info->sinfo_flags = flags;
- s_info->sinfo_ppid = ppid;
- s_info->sinfo_context = context;
- s_info->sinfo_assoc_id = 0;
- s_info->sinfo_timetolive = timetolive;
- errno = 0;
- msg.msg_controllen = cmsg->cmsg_len;
- sz = sendmsg(s, &msg, 0);
- return (sz);
+ sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
+ sinfo->sinfo_stream = stream_no;
+ sinfo->sinfo_ssn = 0;
+ sinfo->sinfo_flags = flags;
+ sinfo->sinfo_ppid = ppid;
+ sinfo->sinfo_context = context;
+ sinfo->sinfo_assoc_id = 0;
+ sinfo->sinfo_timetolive = timetolive;
+ return (sendmsg(s, &msg, 0));
#endif
}
@@ -662,12 +579,11 @@ sctp_getassocid(int sd, struct sockaddr *sa)
siz = sizeof(sp);
memset(&sp, 0, sizeof(sp));
memcpy((caddr_t)&sp.spinfo_address, sa, sa->sa_len);
- errno = 0;
if (getsockopt(sd, IPPROTO_SCTP,
SCTP_GET_PEER_ADDR_INFO, &sp, &siz) != 0) {
+ /* We depend on the fact that 0 can never be returned */
return ((sctp_assoc_t) 0);
}
- /* We depend on the fact that 0 can never be returned */
return (sp.spinfo_assoc_id);
}
@@ -683,11 +599,9 @@ sctp_send(int sd, const void *data, size_t len,
return (syscall(SYS_sctp_generic_sendmsg, sd,
data, len, to, 0, sinfo, flags));
#else
- ssize_t sz;
struct msghdr msg;
struct iovec iov;
- struct sctp_sndrcvinfo *s_info;
- char controlVector[SCTP_CONTROL_VEC_SIZE_SND];
+ char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
struct cmsghdr *cmsg;
if (sinfo == NULL) {
@@ -697,24 +611,18 @@ sctp_send(int sd, const void *data, size_t len,
iov.iov_base = (char *)data;
iov.iov_len = len;
- msg.msg_name = 0;
+ msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
- msg.msg_control = (caddr_t)controlVector;
-
- cmsg = (struct cmsghdr *)controlVector;
-
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = CMSG_SPACE(sizeof(struct sctp_sndrcvinfo));
+ cmsg = (struct cmsghdr *)cmsgbuf;
cmsg->cmsg_level = IPPROTO_SCTP;
cmsg->cmsg_type = SCTP_SNDRCV;
cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
- s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
- /* copy in the data */
- *s_info = *sinfo;
- errno = 0;
- msg.msg_controllen = cmsg->cmsg_len;
- sz = sendmsg(sd, &msg, flags);
- return (sz);
+ memcpy(CMSG_DATA(cmsg), sinfo, sizeof(struct sctp_sndrcvinfo));
+ return (sendmsg(sd, &msg, flags));
#endif
}
@@ -836,7 +744,7 @@ sctp_sendmsgx(int sd,
sinfo.sinfo_ssn = stream_no;
sinfo.sinfo_timetolive = timetolive;
sinfo.sinfo_context = context;
- return sctp_sendx(sd, msg, len, addrs, addrcnt, &sinfo, 0);
+ return (sctp_sendx(sd, msg, len, addrs, addrcnt, &sinfo, 0));
}
ssize_t
@@ -856,11 +764,10 @@ sctp_recvmsg(int s,
return (syscall(SYS_sctp_generic_recvmsg, s,
&iov, 1, from, fromlen, sinfo, msg_flags));
#else
- struct sctp_sndrcvinfo *s_info;
ssize_t sz;
struct msghdr msg;
struct iovec iov;
- char controlVector[SCTP_CONTROL_VEC_SIZE_RCV];
+ char cmsgbuf[SCTP_CONTROL_VEC_SIZE_RCV];
struct cmsghdr *cmsg;
if (msg_flags == NULL) {
@@ -877,52 +784,38 @@ sctp_recvmsg(int s,
msg.msg_namelen = *fromlen;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
- msg.msg_control = (caddr_t)controlVector;
- msg.msg_controllen = sizeof(controlVector);
- errno = 0;
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
sz = recvmsg(s, &msg, *msg_flags);
*msg_flags = msg.msg_flags;
if (sz <= 0) {
return (sz);
}
- s_info = NULL;
if (sinfo) {
sinfo->sinfo_assoc_id = 0;
}
- if ((msg.msg_controllen) && sinfo) {
+ if ((msg.msg_controllen > 0) && (sinfo != NULL)) {
/*
* parse through and see if we find the sctp_sndrcvinfo (if
* the user wants it).
*/
- cmsg = (struct cmsghdr *)controlVector;
- while (cmsg) {
- if ((cmsg->cmsg_len == 0) || (cmsg->cmsg_len > msg.msg_controllen)) {
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level != IPPROTO_SCTP) {
+ continue;
+ }
+ if (cmsg->cmsg_type == SCTP_SNDRCV) {
+ memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_sndrcvinfo));
break;
}
- if (cmsg->cmsg_level == IPPROTO_SCTP) {
- if (cmsg->cmsg_type == SCTP_SNDRCV) {
- /* Got it */
- s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
- /* Copy it to the user */
- if (sinfo)
- *sinfo = *s_info;
- break;
- } else if (cmsg->cmsg_type == SCTP_EXTRCV) {
- /*
- * Got it, presumably the user has
- * asked for this extra info, so the
- * structure holds more room :-D
- */
- s_info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
- /* Copy it to the user */
- if (sinfo) {
- memcpy(sinfo, s_info, sizeof(struct sctp_extrcvinfo));
- }
- break;
-
- }
+ if (cmsg->cmsg_type == SCTP_EXTRCV) {
+ /*
+ * Let's hope that the user provided enough
+ * enough memory. At least he asked for more
+ * information.
+ */
+ memcpy(sinfo, CMSG_DATA(cmsg), sizeof(struct sctp_extrcvinfo));
+ break;
}
- cmsg = CMSG_NXTHDR(&msg, cmsg);
}
}
return (sz);
@@ -940,10 +833,10 @@ sctp_recvv(int sd,
unsigned int *infotype,
int *flags)
{
- char ctlbuf[SCTP_CONTROL_VEC_SIZE_RCV];
+ char cmsgbuf[SCTP_CONTROL_VEC_SIZE_RCV];
struct msghdr msg;
struct cmsghdr *cmsg;
- ssize_t n;
+ ssize_t ret;
struct sctp_rcvinfo *rcvinfo;
struct sctp_nxtinfo *nxtinfo;
@@ -964,12 +857,11 @@ sctp_recvv(int sd,
}
msg.msg_iov = (struct iovec *)iov;
msg.msg_iovlen = iovlen;
- msg.msg_control = ctlbuf;
- msg.msg_controllen = sizeof(ctlbuf);
- errno = 0;
- n = recvmsg(sd, &msg, *flags);
+ msg.msg_control = cmsgbuf;
+ msg.msg_controllen = sizeof(cmsgbuf);
+ ret = recvmsg(sd, &msg, *flags);
*flags = msg.msg_flags;
- if ((n > 0) &&
+ if ((ret > 0) &&
(msg.msg_controllen > 0) &&
(infotype != NULL) &&
(infolen != NULL) &&
@@ -982,41 +874,44 @@ sctp_recvv(int sd,
}
if (cmsg->cmsg_type == SCTP_RCVINFO) {
rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
+ if (nxtinfo != NULL) {
+ break;
+ } else {
+ continue;
+ }
}
if (cmsg->cmsg_type == SCTP_NXTINFO) {
nxtinfo = (struct sctp_nxtinfo *)CMSG_DATA(cmsg);
- }
- if (rcvinfo && nxtinfo) {
- break;
+ if (rcvinfo != NULL) {
+ break;
+ } else {
+ continue;
+ }
}
}
- if (rcvinfo) {
- if (nxtinfo) {
- if (*infolen >= sizeof(struct sctp_recvv_rn)) {
- struct sctp_recvv_rn *rn_info;
-
- rn_info = (struct sctp_recvv_rn *)info;
- rn_info->recvv_rcvinfo = *rcvinfo;
- rn_info->recvv_nxtinfo = *nxtinfo;
- *infolen = (socklen_t) sizeof(struct sctp_recvv_rn);
- *infotype = SCTP_RECVV_RN;
- }
- } else {
- if (*infolen >= sizeof(struct sctp_rcvinfo)) {
- memcpy(info, rcvinfo, sizeof(struct sctp_rcvinfo));
- *infolen = (socklen_t) sizeof(struct sctp_rcvinfo);
- *infotype = SCTP_RECVV_RCVINFO;
- }
+ if (rcvinfo != NULL) {
+ if ((nxtinfo != NULL) && (*infolen >= sizeof(struct sctp_recvv_rn))) {
+ struct sctp_recvv_rn *rn_info;
+
+ rn_info = (struct sctp_recvv_rn *)info;
+ rn_info->recvv_rcvinfo = *rcvinfo;
+ rn_info->recvv_nxtinfo = *nxtinfo;
+ *infolen = (socklen_t) sizeof(struct sctp_recvv_rn);
+ *infotype = SCTP_RECVV_RN;
+ } else if (*infolen >= sizeof(struct sctp_rcvinfo)) {
+ memcpy(info, rcvinfo, sizeof(struct sctp_rcvinfo));
+ *infolen = (socklen_t) sizeof(struct sctp_rcvinfo);
+ *infotype = SCTP_RECVV_RCVINFO;
}
- } else if (nxtinfo) {
- if (*infolen >= sizeof(struct sctp_rcvinfo)) {
+ } else if (nxtinfo != NULL) {
+ if (*infolen >= sizeof(struct sctp_nxtinfo)) {
memcpy(info, nxtinfo, sizeof(struct sctp_nxtinfo));
*infolen = (socklen_t) sizeof(struct sctp_nxtinfo);
*infotype = SCTP_RECVV_NXTINFO;
}
}
}
- return (n);
+ return (ret);
}
ssize_t
@@ -1241,7 +1136,4 @@ sctp_peeloff(int sd, sctp_assoc_t assoc_id)
#endif
-
-#undef SCTP_CONTROL_VEC_SIZE_SND
#undef SCTP_CONTROL_VEC_SIZE_RCV
-#undef SCTP_STACK_BUF_SIZE
diff --git a/lib/libc/regex/regcomp.c b/lib/libc/regex/regcomp.c
index 68ffa66..f3a41e9 100644
--- a/lib/libc/regex/regcomp.c
+++ b/lib/libc/regex/regcomp.c
@@ -1212,7 +1212,7 @@ CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max)
}
cs->ranges = newranges;
cs->ranges[cs->nranges].min = min;
- cs->ranges[cs->nranges].min = max;
+ cs->ranges[cs->nranges].max = max;
cs->nranges++;
}
diff --git a/lib/libc/rpc/clnt_vc.c b/lib/libc/rpc/clnt_vc.c
index 881f84d..53e393e 100644
--- a/lib/libc/rpc/clnt_vc.c
+++ b/lib/libc/rpc/clnt_vc.c
@@ -260,7 +260,7 @@ clnt_vc_create(fd, raddr, prog, vers, sendsz, recvsz)
if (ct->ct_addr.buf == NULL)
goto err;
memcpy(ct->ct_addr.buf, raddr->buf, raddr->len);
- ct->ct_addr.len = raddr->maxlen;
+ ct->ct_addr.len = raddr->len;
ct->ct_addr.maxlen = raddr->maxlen;
/*
diff --git a/lib/libc/stdio/Makefile.inc b/lib/libc/stdio/Makefile.inc
index bc3b9e5..0062d3d 100644
--- a/lib/libc/stdio/Makefile.inc
+++ b/lib/libc/stdio/Makefile.inc
@@ -14,6 +14,7 @@ SRCS+= _flock_stub.c asprintf.c clrerr.c dprintf.c \
ftell.c funopen.c fvwrite.c fwalk.c fwide.c fwprintf.c fwscanf.c \
fwrite.c getc.c getchar.c getdelim.c getline.c \
gets.c getw.c getwc.c getwchar.c makebuf.c mktemp.c \
+ open_memstream.c open_wmemstream.c \
perror.c printf.c printf-pos.c putc.c putchar.c \
puts.c putw.c putwc.c putwchar.c \
refill.c remove.c rewind.c rget.c scanf.c setbuf.c setbuffer.c \
@@ -36,7 +37,7 @@ MAN+= fclose.3 ferror.3 fflush.3 fgetln.3 fgets.3 fgetwln.3 fgetws.3 \
flockfile.3 \
fopen.3 fputs.3 \
fputws.3 fread.3 fseek.3 funopen.3 fwide.3 getc.3 \
- getline.3 getwc.3 mktemp.3 \
+ getline.3 getwc.3 mktemp.3 open_memstream.3 \
printf.3 printf_l.3 putc.3 putwc.3 remove.3 scanf.3 scanf_l.3 setbuf.3 \
stdio.3 tmpnam.3 \
ungetc.3 ungetwc.3 wprintf.3 wscanf.3
@@ -60,6 +61,7 @@ MLINKS+=getc.3 fgetc.3 getc.3 getc_unlocked.3 getc.3 getchar.3 \
MLINKS+=getline.3 getdelim.3
MLINKS+=getwc.3 fgetwc.3 getwc.3 getwchar.3
MLINKS+=mktemp.3 mkdtemp.3 mktemp.3 mkstemp.3 mktemp.3 mkstemps.3
+MLINKS+=open_memstream.3 open_wmemstream.3
MLINKS+=printf.3 asprintf.3 printf.3 dprintf.3 printf.3 fprintf.3 \
printf.3 snprintf.3 printf.3 sprintf.3 \
printf.3 vasprintf.3 printf.3 vdprintf.3 \
diff --git a/lib/libc/stdio/Symbol.map b/lib/libc/stdio/Symbol.map
index b78de5a..538b29a 100644
--- a/lib/libc/stdio/Symbol.map
+++ b/lib/libc/stdio/Symbol.map
@@ -156,6 +156,8 @@ FBSD_1.3 {
putwc_l;
putwchar_l;
fmemopen;
+ open_memstream;
+ open_wmemstream;
};
FBSDprivate_1.0 {
diff --git a/lib/libc/stdio/fgetln.c b/lib/libc/stdio/fgetln.c
index 7cb2854..0cd04b8 100644
--- a/lib/libc/stdio/fgetln.c
+++ b/lib/libc/stdio/fgetln.c
@@ -115,7 +115,7 @@ fgetln(FILE *fp, size_t *lenp)
* As a bonus, though, we can leave off the __SMOD.
*
* OPTIMISTIC is length that we (optimistically) expect will
- * accomodate the `rest' of the string, on each trip through the
+ * accommodate the `rest' of the string, on each trip through the
* loop below.
*/
#define OPTIMISTIC 80
diff --git a/lib/libc/stdio/fopen.3 b/lib/libc/stdio/fopen.3
index a07be38..f11f4e0 100644
--- a/lib/libc/stdio/fopen.3
+++ b/lib/libc/stdio/fopen.3
@@ -332,7 +332,7 @@ but is also supported by glibc.
The
.Fn fmemopen
function
-conforms to
+conforms to
.St -p1003.1-2008 .
The ``b'' mode does not conform to any standard
but is also supported by glibc.
diff --git a/lib/libc/stdio/fwalk.c b/lib/libc/stdio/fwalk.c
index e5ce49f..cb20071 100644
--- a/lib/libc/stdio/fwalk.c
+++ b/lib/libc/stdio/fwalk.c
@@ -37,7 +37,6 @@ static char sccsid[] = "@(#)fwalk.c 8.1 (Berkeley) 6/4/93";
__FBSDID("$FreeBSD$");
#include <sys/types.h>
-#include <machine/atomic.h>
#include <stdio.h>
#include "local.h"
#include "glue.h"
diff --git a/lib/libc/stdio/open_memstream.3 b/lib/libc/stdio/open_memstream.3
new file mode 100644
index 0000000..9396830
--- /dev/null
+++ b/lib/libc/stdio/open_memstream.3
@@ -0,0 +1,155 @@
+.\" Copyright (c) 2013 Advanced Computing Technologies LLC
+.\" Written by: John H. Baldwin <jhb@FreeBSD.org>
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 27, 2013
+.Dt OPEN_MEMSTREAM 3
+.Os
+.Sh NAME
+.Nm open_memstream ,
+.Nm open_wmemstream
+.Nd dynamic memory buffer stream open functions
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In stdio.h
+.Ft FILE *
+.Fn open_memstream "char **bufp" "size_t **sizep"
+.In wchar.h
+.Ft FILE *
+.Fn open_wmemstream "wchar_t **bufp" "size_t **sizep"
+.Sh DESCRIPTION
+The
+.Fn open_memstream
+and
+.Fn open_wmemstream
+functions create a write-only, seekable stream backed by a dynamically
+allocated memory buffer.
+The
+.Fn open_memstream
+function creates a byte-oriented stream,
+while the
+.Fn open_wmemstream
+function creates a wide-oriented stream.
+.Pp
+Each stream maintains a current position and size.
+Initially,
+the position and size are set to zero.
+Each write begins at the current position and advances it the number of
+successfully written bytes for
+.Fn open_memstream
+or wide characters for
+.Fn open_wmemstream .
+If a write moves the current position beyond the length of the buffer,
+the length of the buffer is extended and a null character is appended to the
+buffer.
+.Pp
+A stream's buffer always contains a null character at the end of the buffer
+that is not included in the current length.
+.Pp
+If a stream's current position is moved beyond the current length via a
+seek operation and a write is performed,
+the characters between the current length and the current position are filled
+with null characters before the write is performed.
+.Pp
+After a successful call to
+.Xr fclose 3
+or
+.Xr fflush 3 ,
+the pointer referenced by
+.Fa bufp
+will contain the start of the memory buffer and the variable referenced by
+.Fa sizep
+will contain the smaller of the current position and the current buffer length.
+.Pp
+After a successful call to
+.Xr fflush 3,
+the pointer referenced by
+.Fa bufp
+and the variable referenced by
+.Fa sizep
+are only valid until the next write operation or a call to
+.Xr fclose 3.
+.Pp
+Once a stream is closed,
+the allocated buffer referenced by
+.Fa bufp
+should be released via a call to
+.Xr free 3
+when it is no longer needed.
+.Sh IMPLEMENTATION NOTES
+Internally all I/O streams are effectively byte-oriented,
+so using wide-oriented operations to write to a stream opened via
+.Fn open_wmemstream
+results in wide characters being expanded to a stream of multibyte characters
+in stdio's internal buffers.
+These multibyte characters are then converted back to wide characters when
+written into the stream.
+As a result,
+the wide-oriented streams maintain an internal multibyte character conversion
+state that is cleared on any seek opertion that changes the current position.
+This should have no effect as long as wide-oriented output operations are used
+on a wide-oriented stream.
+.Sh RETURN VALUES
+Upon successful completion,
+.Fn open_memstream
+and
+.Fn open_wmemstream
+return a
+.Tn FILE
+pointer.
+Otherwise,
+.Dv NULL
+is returned and the global variable
+.Va errno
+is set to indicate the error.
+.Sh ERRORS
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The
+.Fa bufp
+or
+.Fa sizep
+argument was
+.Dv NULL .
+.It Bq Er ENOMEM
+Memory for the stream or buffer could not be allocated.
+.El
+.Sh SEE ALSO
+.Xr fclose 3 ,
+.Xr fflush 3 ,
+.Xr fopen 3 ,
+.Xr free 3 ,
+.Xr fseek 3 ,
+.Xr sbuf 3 ,
+.Xr stdio 3
+.Sh STANDARDS
+The
+.Fn open_memstream
+and
+.Fn open_wmemstream
+functions conform to
+.St -p1003.1-2008 .
diff --git a/lib/libc/stdio/open_memstream.c b/lib/libc/stdio/open_memstream.c
new file mode 100644
index 0000000..aa50822
--- /dev/null
+++ b/lib/libc/stdio/open_memstream.c
@@ -0,0 +1,209 @@
+/*-
+ * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include "un-namespace.h"
+
+/* XXX: There is no FPOS_MAX. This assumes fpos_t is an off_t. */
+#define FPOS_MAX OFF_MAX
+
+struct memstream {
+ char **bufp;
+ size_t *sizep;
+ ssize_t len;
+ fpos_t offset;
+};
+
+static int
+memstream_grow(struct memstream *ms, fpos_t newoff)
+{
+ char *buf;
+ ssize_t newsize;
+
+ if (newoff < 0 || newoff >= SSIZE_MAX)
+ newsize = SSIZE_MAX - 1;
+ else
+ newsize = newoff;
+ if (newsize > ms->len) {
+ buf = realloc(*ms->bufp, newsize + 1);
+ if (buf != NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "MS: %p growing from %zd to %zd\n",
+ ms, ms->len, newsize);
+#endif
+ memset(buf + ms->len + 1, 0, newsize - ms->len);
+ *ms->bufp = buf;
+ ms->len = newsize;
+ return (1);
+ }
+ return (0);
+ }
+ return (1);
+}
+
+static void
+memstream_update(struct memstream *ms)
+{
+
+ assert(ms->len >= 0 && ms->offset >= 0);
+ *ms->sizep = ms->len < ms->offset ? ms->len : ms->offset;
+}
+
+static int
+memstream_write(void *cookie, const char *buf, int len)
+{
+ struct memstream *ms;
+ ssize_t tocopy;
+
+ ms = cookie;
+ if (!memstream_grow(ms, ms->offset + len))
+ return (-1);
+ tocopy = ms->len - ms->offset;
+ if (len < tocopy)
+ tocopy = len;
+ memcpy(*ms->bufp + ms->offset, buf, tocopy);
+ ms->offset += tocopy;
+ memstream_update(ms);
+#ifdef DEBUG
+ fprintf(stderr, "MS: write(%p, %d) = %zd\n", ms, len, tocopy);
+#endif
+ return (tocopy);
+}
+
+static fpos_t
+memstream_seek(void *cookie, fpos_t pos, int whence)
+{
+ struct memstream *ms;
+#ifdef DEBUG
+ fpos_t old;
+#endif
+
+ ms = cookie;
+#ifdef DEBUG
+ old = ms->offset;
+#endif
+ switch (whence) {
+ case SEEK_SET:
+ /* _fseeko() checks for negative offsets. */
+ assert(pos >= 0);
+ ms->offset = pos;
+ break;
+ case SEEK_CUR:
+ /* This is only called by _ftello(). */
+ assert(pos == 0);
+ break;
+ case SEEK_END:
+ if (pos < 0) {
+ if (pos + ms->len < 0) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "MS: bad SEEK_END: pos %jd, len %zd\n",
+ (intmax_t)pos, ms->len);
+#endif
+ errno = EINVAL;
+ return (-1);
+ }
+ } else {
+ if (FPOS_MAX - ms->len < pos) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "MS: bad SEEK_END: pos %jd, len %zd\n",
+ (intmax_t)pos, ms->len);
+#endif
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ }
+ ms->offset = ms->len + pos;
+ break;
+ }
+ memstream_update(ms);
+#ifdef DEBUG
+ fprintf(stderr, "MS: seek(%p, %jd, %d) %jd -> %jd\n", ms, (intmax_t)pos,
+ whence, (intmax_t)old, (intmax_t)ms->offset);
+#endif
+ return (ms->offset);
+}
+
+static int
+memstream_close(void *cookie)
+{
+
+ free(cookie);
+ return (0);
+}
+
+FILE *
+open_memstream(char **bufp, size_t *sizep)
+{
+ struct memstream *ms;
+ int save_errno;
+ FILE *fp;
+
+ if (bufp == NULL || sizep == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ *bufp = calloc(1, 1);
+ if (*bufp == NULL)
+ return (NULL);
+ ms = malloc(sizeof(*ms));
+ if (ms == NULL) {
+ save_errno = errno;
+ free(*bufp);
+ *bufp = NULL;
+ errno = save_errno;
+ return (NULL);
+ }
+ ms->bufp = bufp;
+ ms->sizep = sizep;
+ ms->len = 0;
+ ms->offset = 0;
+ memstream_update(ms);
+ fp = funopen(ms, NULL, memstream_write, memstream_seek,
+ memstream_close);
+ if (fp == NULL) {
+ save_errno = errno;
+ free(ms);
+ free(*bufp);
+ *bufp = NULL;
+ errno = save_errno;
+ return (NULL);
+ }
+ fwide(fp, -1);
+ return (fp);
+}
diff --git a/lib/libc/stdio/open_wmemstream.c b/lib/libc/stdio/open_wmemstream.c
new file mode 100644
index 0000000..cf2968a
--- /dev/null
+++ b/lib/libc/stdio/open_wmemstream.c
@@ -0,0 +1,271 @@
+/*-
+ * Copyright (c) 2013 Advanced Computing Technologies LLC
+ * Written by: John H. Baldwin <jhb@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include "namespace.h"
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <wchar.h>
+#include "un-namespace.h"
+
+/* XXX: There is no FPOS_MAX. This assumes fpos_t is an off_t. */
+#define FPOS_MAX OFF_MAX
+
+struct wmemstream {
+ wchar_t **bufp;
+ size_t *sizep;
+ ssize_t len;
+ fpos_t offset;
+ mbstate_t mbstate;
+};
+
+static int
+wmemstream_grow(struct wmemstream *ms, fpos_t newoff)
+{
+ wchar_t *buf;
+ ssize_t newsize;
+
+ if (newoff < 0 || newoff >= SSIZE_MAX / sizeof(wchar_t))
+ newsize = SSIZE_MAX / sizeof(wchar_t) - 1;
+ else
+ newsize = newoff;
+ if (newsize > ms->len) {
+ buf = realloc(*ms->bufp, (newsize + 1) * sizeof(wchar_t));
+ if (buf != NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "WMS: %p growing from %zd to %zd\n",
+ ms, ms->len, newsize);
+#endif
+ wmemset(buf + ms->len + 1, 0, newsize - ms->len);
+ *ms->bufp = buf;
+ ms->len = newsize;
+ return (1);
+ }
+ return (0);
+ }
+ return (1);
+}
+
+static void
+wmemstream_update(struct wmemstream *ms)
+{
+
+ assert(ms->len >= 0 && ms->offset >= 0);
+ *ms->sizep = ms->len < ms->offset ? ms->len : ms->offset;
+}
+
+/*
+ * Based on a starting multibyte state and an input buffer, determine
+ * how many wchar_t's would be output. This doesn't use mbsnrtowcs()
+ * so that it can handle embedded null characters.
+ */
+static size_t
+wbuflen(const mbstate_t *state, const char *buf, int len)
+{
+ mbstate_t lenstate;
+ size_t charlen, count;
+
+ count = 0;
+ lenstate = *state;
+ while (len > 0) {
+ charlen = mbrlen(buf, len, &lenstate);
+ if (charlen == (size_t)-1)
+ return (-1);
+ if (charlen == (size_t)-2)
+ break;
+ if (charlen == 0)
+ /* XXX: Not sure how else to handle this. */
+ charlen = 1;
+ len -= charlen;
+ buf += charlen;
+ count++;
+ }
+ return (count);
+}
+
+static int
+wmemstream_write(void *cookie, const char *buf, int len)
+{
+ struct wmemstream *ms;
+ ssize_t consumed, wlen;
+ size_t charlen;
+
+ ms = cookie;
+ wlen = wbuflen(&ms->mbstate, buf, len);
+ if (wlen < 0) {
+ errno = EILSEQ;
+ return (-1);
+ }
+ if (!wmemstream_grow(ms, ms->offset + wlen))
+ return (-1);
+
+ /*
+ * This copies characters one at a time rather than using
+ * mbsnrtowcs() so it can properly handle embedded null
+ * characters.
+ */
+ consumed = 0;
+ while (len > 0 && ms->offset < ms->len) {
+ charlen = mbrtowc(*ms->bufp + ms->offset, buf, len,
+ &ms->mbstate);
+ if (charlen == (size_t)-1) {
+ if (consumed == 0) {
+ errno = EILSEQ;
+ return (-1);
+ }
+ /* Treat it as a successful short write. */
+ break;
+ }
+ if (charlen == 0)
+ /* XXX: Not sure how else to handle this. */
+ charlen = 1;
+ if (charlen == (size_t)-2) {
+ consumed += len;
+ len = 0;
+ } else {
+ consumed += charlen;
+ buf += charlen;
+ len -= charlen;
+ ms->offset++;
+ }
+ }
+ wmemstream_update(ms);
+#ifdef DEBUG
+ fprintf(stderr, "WMS: write(%p, %d) = %zd\n", ms, len, consumed);
+#endif
+ return (consumed);
+}
+
+static fpos_t
+wmemstream_seek(void *cookie, fpos_t pos, int whence)
+{
+ struct wmemstream *ms;
+ fpos_t old;
+
+ ms = cookie;
+ old = ms->offset;
+ switch (whence) {
+ case SEEK_SET:
+ /* _fseeko() checks for negative offsets. */
+ assert(pos >= 0);
+ ms->offset = pos;
+ break;
+ case SEEK_CUR:
+ /* This is only called by _ftello(). */
+ assert(pos == 0);
+ break;
+ case SEEK_END:
+ if (pos < 0) {
+ if (pos + ms->len < 0) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "WMS: bad SEEK_END: pos %jd, len %zd\n",
+ (intmax_t)pos, ms->len);
+#endif
+ errno = EINVAL;
+ return (-1);
+ }
+ } else {
+ if (FPOS_MAX - ms->len < pos) {
+#ifdef DEBUG
+ fprintf(stderr,
+ "WMS: bad SEEK_END: pos %jd, len %zd\n",
+ (intmax_t)pos, ms->len);
+#endif
+ errno = EOVERFLOW;
+ return (-1);
+ }
+ }
+ ms->offset = ms->len + pos;
+ break;
+ }
+ /* Reset the multibyte state if a seek changes the position. */
+ if (ms->offset != old)
+ memset(&ms->mbstate, 0, sizeof(ms->mbstate));
+ wmemstream_update(ms);
+#ifdef DEBUG
+ fprintf(stderr, "WMS: seek(%p, %jd, %d) %jd -> %jd\n", ms,
+ (intmax_t)pos, whence, (intmax_t)old, (intmax_t)ms->offset);
+#endif
+ return (ms->offset);
+}
+
+static int
+wmemstream_close(void *cookie)
+{
+
+ free(cookie);
+ return (0);
+}
+
+FILE *
+open_wmemstream(wchar_t **bufp, size_t *sizep)
+{
+ struct wmemstream *ms;
+ int save_errno;
+ FILE *fp;
+
+ if (bufp == NULL || sizep == NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+ *bufp = calloc(1, sizeof(wchar_t));
+ if (*bufp == NULL)
+ return (NULL);
+ ms = malloc(sizeof(*ms));
+ if (ms == NULL) {
+ save_errno = errno;
+ free(*bufp);
+ *bufp = NULL;
+ errno = save_errno;
+ return (NULL);
+ }
+ ms->bufp = bufp;
+ ms->sizep = sizep;
+ ms->len = 0;
+ ms->offset = 0;
+ memset(&ms->mbstate, 0, sizeof(mbstate_t));
+ wmemstream_update(ms);
+ fp = funopen(ms, NULL, wmemstream_write, wmemstream_seek,
+ wmemstream_close);
+ if (fp == NULL) {
+ save_errno = errno;
+ free(ms);
+ free(*bufp);
+ *bufp = NULL;
+ errno = save_errno;
+ return (NULL);
+ }
+ fwide(fp, 1);
+ return (fp);
+}
diff --git a/lib/libc/stdio/setbuf.3 b/lib/libc/stdio/setbuf.3
index 2eda0e6..d1ae70b 100644
--- a/lib/libc/stdio/setbuf.3
+++ b/lib/libc/stdio/setbuf.3
@@ -32,7 +32,7 @@
.\" @(#)setbuf.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd June 4, 1993
+.Dd February 18, 2013
.Dt SETBUF 3
.Os
.Sh NAME
@@ -196,18 +196,5 @@ functions
conform to
.St -isoC .
.Sh BUGS
-The
-.Fn setbuffer
-and
-.Fn setlinebuf
-functions are not portable to versions of
-.Bx
-before
-.Bx 4.2 .
-On
-.Bx 4.2
-and
-.Bx 4.3
-systems,
.Fn setbuf
-always uses a suboptimal buffer size and should be avoided.
+usually uses a suboptimal buffer size and should be avoided.
diff --git a/lib/libc/stdlib/bsearch.3 b/lib/libc/stdlib/bsearch.3
index b3591f8e..25be842 100644
--- a/lib/libc/stdlib/bsearch.3
+++ b/lib/libc/stdlib/bsearch.3
@@ -32,7 +32,7 @@
.\" @(#)bsearch.3 8.3 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
-.Dd April 19, 1994
+.Dd February 22, 2013
.Dt BSEARCH 3
.Os
.Sh NAME
@@ -71,6 +71,12 @@ less than, equal to, or greater than zero if the
.Fa key
object is found, respectively, to be less than, to match, or be
greater than the array member.
+See the
+.Fa int_compare
+sample function in
+.Xr qsort 3
+for a comparison function that is also compatible with
+.Fn bsearch .
.Sh RETURN VALUES
The
.Fn bsearch
diff --git a/lib/libc/stdlib/qsort.3 b/lib/libc/stdlib/qsort.3
index 0f7ef73..f34d260 100644
--- a/lib/libc/stdlib/qsort.3
+++ b/lib/libc/stdlib/qsort.3
@@ -32,7 +32,7 @@
.\" @(#)qsort.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd September 30, 2003
+.Dd February 20, 2013
.Dt QSORT 3
.Os
.Sh NAME
@@ -205,6 +205,46 @@ functions
return no value.
.Pp
.Rv -std heapsort mergesort
+.Sh EXAMPLES
+A sample program that sorts an array of
+.Vt int
+values in place using
+.Fn qsort ,
+and then prints the sorted array to standard output is:
+.Bd -literal
+#include <stdio.h>
+#include <stdlib.h>
+
+/*
+ * Custom comparison function that can compare 'int' values through pointers
+ * passed by qsort(3).
+ */
+static int
+int_compare(const void *p1, const void *p2)
+{
+ int left = *(const int *)p1;
+ int right = *(const int *)p2;
+
+ return ((left > right) - (left < right));
+}
+
+/*
+ * Sort an array of 'int' values and print it to standard output.
+ */
+int
+main(void)
+{
+ int int_array[] = { 4, 5, 9, 3, 0, 1, 7, 2, 8, 6 };
+ const size_t array_size = sizeof(int_array) / sizeof(int_array[0]);
+ size_t k;
+
+ qsort(&int_array, array_size, sizeof(int_array[0]), int_compare);
+ for (k = 0; k < array_size; k++)
+ printf(" %d", int_array[k]);
+ puts("");
+ return (EXIT_SUCCESS);
+}
+.Ed
.Sh COMPATIBILITY
Previous versions of
.Fn qsort
diff --git a/lib/libc/stdlib/rand.3 b/lib/libc/stdlib/rand.3
index 390a40b..bf50e3d 100644
--- a/lib/libc/stdlib/rand.3
+++ b/lib/libc/stdlib/rand.3
@@ -32,7 +32,7 @@
.\" @(#)rand.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd September 4, 2012
+.Dd April 2, 2013
.Dt RAND 3
.Os
.Sh NAME
@@ -91,9 +91,7 @@ seeded with a value of 1.
.Pp
The
.Fn sranddev
-function initializes a seed using the
-.Xr random 4
-random number device which returns good random numbers.
+function initializes a seed using pseudo-random numbers obtained from the kernel.
.Pp
The
.Fn rand_r
diff --git a/lib/libc/stdlib/rand.c b/lib/libc/stdlib/rand.c
index 7041818..0cbd948 100644
--- a/lib/libc/stdlib/rand.c
+++ b/lib/libc/stdlib/rand.c
@@ -36,11 +36,10 @@ static char sccsid[] = "@(#)rand.c 8.1 (Berkeley) 6/14/93";
__FBSDID("$FreeBSD$");
#include "namespace.h"
-#include <sys/time.h> /* for sranddev() */
+#include <sys/param.h>
+#include <sys/sysctl.h>
#include <sys/types.h>
-#include <fcntl.h> /* for sranddev() */
#include <stdlib.h>
-#include <unistd.h> /* for sranddev() */
#include "un-namespace.h"
#ifdef TEST
@@ -112,28 +111,20 @@ u_int seed;
* sranddev:
*
* Many programs choose the seed value in a totally predictable manner.
- * This often causes problems. We seed the generator using the much more
- * secure random(4) interface.
+ * This often causes problems. We seed the generator using pseudo-random
+ * data from the kernel.
*/
void
sranddev()
{
- int fd, done;
-
- done = 0;
- fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0);
- if (fd >= 0) {
- if (_read(fd, (void *) &next, sizeof(next)) == sizeof(next))
- done = 1;
- _close(fd);
- }
-
- if (!done) {
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- srand((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
- }
+ int mib[2];
+ size_t len;
+
+ len = sizeof(next);
+
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARND;
+ sysctl(mib, 2, (void *)&next, &len, NULL, 0);
}
diff --git a/lib/libc/stdlib/random.3 b/lib/libc/stdlib/random.3
index 4817440..a1e585b 100644
--- a/lib/libc/stdlib/random.3
+++ b/lib/libc/stdlib/random.3
@@ -28,7 +28,7 @@
.\" @(#)random.3 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd September 4, 2012
+.Dd April 2, 2013
.Dt RANDOM 3
.Os
.Sh NAME
@@ -106,8 +106,8 @@ as the seed.
.Pp
The
.Fn srandomdev
-routine initializes a state array using data from
-.Xr random 4 .
+routine initializes a state array using
+pseudo-random numbers obtained from the kernel.
Note that this particular seeding
procedure can generate states which are impossible to reproduce by
calling
diff --git a/lib/libc/stdlib/random.c b/lib/libc/stdlib/random.c
index a3c054e..4c88ecb 100644
--- a/lib/libc/stdlib/random.c
+++ b/lib/libc/stdlib/random.c
@@ -34,12 +34,11 @@ static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95";
__FBSDID("$FreeBSD$");
#include "namespace.h"
-#include <sys/time.h> /* for srandomdev() */
-#include <fcntl.h> /* for srandomdev() */
+#include <sys/param.h>
+#include <sys/sysctl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
-#include <unistd.h> /* for srandomdev() */
#include "un-namespace.h"
/*
@@ -284,39 +283,28 @@ srandom(unsigned long x)
* srandomdev:
*
* Many programs choose the seed value in a totally predictable manner.
- * This often causes problems. We seed the generator using the much more
- * secure random(4) interface. Note that this particular seeding
- * procedure can generate states which are impossible to reproduce by
- * calling srandom() with any value, since the succeeding terms in the
- * state buffer are no longer derived from the LC algorithm applied to
- * a fixed seed.
+ * This often causes problems. We seed the generator using pseudo-random
+ * data from the kernel.
+ *
+ * Note that this particular seeding procedure can generate states
+ * which are impossible to reproduce by calling srandom() with any
+ * value, since the succeeding terms in the state buffer are no longer
+ * derived from the LC algorithm applied to a fixed seed.
*/
void
srandomdev(void)
{
- int fd, done;
+ int mib[2];
size_t len;
if (rand_type == TYPE_0)
- len = sizeof state[0];
+ len = sizeof(state[0]);
else
- len = rand_deg * sizeof state[0];
-
- done = 0;
- fd = _open("/dev/random", O_RDONLY | O_CLOEXEC, 0);
- if (fd >= 0) {
- if (_read(fd, (void *) state, len) == (ssize_t) len)
- done = 1;
- _close(fd);
- }
+ len = rand_deg * sizeof(state[0]);
- if (!done) {
- struct timeval tv;
-
- gettimeofday(&tv, NULL);
- srandom((getpid() << 16) ^ tv.tv_sec ^ tv.tv_usec);
- return;
- }
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_ARND;
+ sysctl(mib, 2, state, &len, NULL, 0);
if (rand_type != TYPE_0) {
fptr = &state[rand_sep];
diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3
index c7384d6..33970fd 100644
--- a/lib/libc/stdlib/realpath.3
+++ b/lib/libc/stdlib/realpath.3
@@ -42,7 +42,7 @@
.Sh SYNOPSIS
.In stdlib.h
.Ft "char *"
-.Fn realpath "const char *pathname" "char *resolved_path"
+.Fn realpath "const char * restrict pathname" "char * restrict resolved_path"
.Sh DESCRIPTION
The
.Fn realpath
diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc
index 0cc038a..477049f 100644
--- a/lib/libc/stdtime/Makefile.inc
+++ b/lib/libc/stdtime/Makefile.inc
@@ -11,6 +11,9 @@ SYM_MAPS+= ${.CURDIR}/stdtime/Symbol.map
CFLAGS+= -I${.CURDIR}/../../contrib/tzcode/stdtime -I${.CURDIR}/stdtime
+CFLAGS.localtime.c= -fwrapv
+CFLAGS+= ${CFLAGS.${.IMPSRC:T}}
+
MAN+= ctime.3 strftime.3 strptime.3 time2posix.3
MAN+= tzfile.5
diff --git a/lib/libc/string/Makefile.inc b/lib/libc/string/Makefile.inc
index cd06fc8..b997b7b 100644
--- a/lib/libc/string/Makefile.inc
+++ b/lib/libc/string/Makefile.inc
@@ -10,9 +10,9 @@ MISRCS+=bcmp.c bcopy.c bzero.c ffs.c ffsl.c ffsll.c fls.c flsl.c flsll.c \
memccpy.c memchr.c memrchr.c memcmp.c \
memcpy.c memmem.c memmove.c memset.c \
stpcpy.c stpncpy.c strcasecmp.c \
- strcat.c strcasestr.c strchr.c strcmp.c strcoll.c strcpy.c strcspn.c \
- strdup.c strerror.c strlcat.c strlcpy.c strlen.c strmode.c strncat.c \
- strncmp.c strncpy.c strndup.c strnlen.c strnstr.c \
+ strcat.c strcasestr.c strchr.c strchrnul.c strcmp.c strcoll.c strcpy.c\
+ strcspn.c strdup.c strerror.c strlcat.c strlcpy.c strlen.c strmode.c \
+ strncat.c strncmp.c strncpy.c strndup.c strnlen.c strnstr.c \
strpbrk.c strrchr.c strsep.c strsignal.c strspn.c strstr.c strtok.c \
strxfrm.c swab.c wcpcpy.c wcpncpy.c wcscasecmp.c wcscat.c \
wcschr.c wcscmp.c wcscoll.c wcscpy.c wcscspn.c wcsdup.c \
@@ -46,7 +46,8 @@ MLINKS+=strcasecmp.3 strncasecmp.3 \
strcasecmp.3 strcasecmp_l.3 \
strcasecmp.3 strncasecmp_l.3
MLINKS+=strcat.3 strncat.3
-MLINKS+=strchr.3 strrchr.3
+MLINKS+=strchr.3 strrchr.3 \
+ strchr.3 strchrnul.3
MLINKS+=strcmp.3 strncmp.3
MLINKS+=strcoll.3 strcoll_l.3
MLINKS+=strcpy.3 stpcpy.3 \
diff --git a/lib/libc/string/Symbol.map b/lib/libc/string/Symbol.map
index ef23465..8e80165 100644
--- a/lib/libc/string/Symbol.map
+++ b/lib/libc/string/Symbol.map
@@ -94,6 +94,7 @@ FBSD_1.1 {
FBSD_1.3 {
strcasecmp_l;
strcasestr_l;
+ strchrnul;
strncasecmp_l;
wcswidth_l;
wcwidth_l;
diff --git a/lib/libc/string/strchr.3 b/lib/libc/string/strchr.3
index 984eb06..019b923 100644
--- a/lib/libc/string/strchr.3
+++ b/lib/libc/string/strchr.3
@@ -32,11 +32,11 @@
.\" @(#)strchr.3 8.2 (Berkeley) 4/19/94
.\" $FreeBSD$
.\"
-.Dd April 19, 1994
+.Dd February 13, 2013
.Dt STRCHR 3
.Os
.Sh NAME
-.Nm strchr , strrchr
+.Nm strchr , strrchr , strchrnul
.Nd locate character in string
.Sh LIBRARY
.Lb libc
@@ -46,6 +46,8 @@
.Fn strchr "const char *s" "int c"
.Ft "char *"
.Fn strrchr "const char *s" "int c"
+.Ft "char *"
+.Fn strchrnul "const char *s" "int c"
.Sh DESCRIPTION
The
.Fn strchr
@@ -69,6 +71,18 @@ function is identical to
.Fn strchr
except it locates the last occurrence of
.Fa c .
+.Pp
+The
+.Fn strchrnul
+function is identical to
+.Fn strchr
+except that if
+.Fa c
+is not found in
+.Fa s
+a pointer to the terminating
+.Ql \e0
+is returned.
.Sh RETURN VALUES
The functions
.Fn strchr
@@ -77,6 +91,11 @@ and
return a pointer to the located character, or
.Dv NULL
if the character does not appear in the string.
+.Pp
+.Fn strchrnul
+returns a pointer to the terminating
+.Ql \e0
+if the character does not appear in the string.
.Sh SEE ALSO
.Xr memchr 3 ,
.Xr memmem 3 ,
@@ -94,3 +113,11 @@ and
.Fn strrchr
conform to
.St -isoC .
+The
+.Fn strchrnul
+is a GNU extension .
+.Sh History
+The
+.Fn strchrnul
+function first appeared in glibc 2.1.1 and was added in
+.Fx 10.0 .
diff --git a/lib/libc/string/strchrnul.c b/lib/libc/string/strchrnul.c
new file mode 100644
index 0000000..98e652d
--- /dev/null
+++ b/lib/libc/string/strchrnul.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2013 Niclas Zeising
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stddef.h>
+#include <string.h>
+
+__weak_reference(__strchrnul, strchrnul);
+
+char *
+__strchrnul(const char *p, int ch)
+{
+ char c;
+
+ c = ch;
+ for (;; ++p) {
+ if (*p == c || *p == '\0')
+ return ((char *)p);
+ }
+ /* NOTREACHED */
+}
+
diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc
index a35ed5d..fef0f3c 100644
--- a/lib/libc/sys/Makefile.inc
+++ b/lib/libc/sys/Makefile.inc
@@ -78,59 +78,219 @@ ${SPSEUDO}:
>> ${.TARGET}
printf ${NOTE_GNU_STACK} >>${.TARGET}
-MAN+= abort2.2 accept.2 access.2 acct.2 adjtime.2 \
- aio_cancel.2 aio_error.2 aio_read.2 aio_return.2 \
- aio_suspend.2 aio_waitcomplete.2 aio_write.2 \
- bind.2 brk.2 cap_enter.2 cap_new.2 chdir.2 chflags.2 \
- chmod.2 chown.2 chroot.2 clock_gettime.2 close.2 closefrom.2 \
- connect.2 cpuset.2 cpuset_getaffinity.2 dup.2 execve.2 _exit.2 \
- extattr_get_file.2 fcntl.2 ffclock.2 fhopen.2 flock.2 fork.2 fsync.2 \
- getdirentries.2 getdtablesize.2 \
- getfh.2 getfsstat.2 getgid.2 getgroups.2 getitimer.2 getlogin.2 \
- getloginclass.2 getpeername.2 getpgrp.2 getpid.2 getpriority.2 \
- getrlimit.2 getrusage.2 getsid.2 getsockname.2 \
- getsockopt.2 gettimeofday.2 getuid.2 \
- intro.2 ioctl.2 issetugid.2 jail.2 kenv.2 kill.2 \
- kldfind.2 kldfirstmod.2 kldload.2 kldnext.2 kldstat.2 kldsym.2 \
- kldunload.2 kqueue.2 ktrace.2 link.2 lio_listio.2 listen.2 \
+MAN+= abort2.2 \
+ accept.2 \
+ access.2 \
+ acct.2 \
+ adjtime.2 \
+ aio_cancel.2 \
+ aio_error.2 \
+ aio_read.2 \
+ aio_return.2 \
+ aio_suspend.2 \
+ aio_waitcomplete.2 \
+ aio_write.2 \
+ bind.2 \
+ bindat.2 \
+ brk.2 \
+ cap_enter.2 \
+ cap_fcntls_limit.2 \
+ cap_ioctls_limit.2 \
+ cap_rights_limit.2 \
+ chdir.2 \
+ chflags.2 \
+ chmod.2 \
+ chown.2 \
+ chroot.2 \
+ clock_gettime.2 \
+ close.2 \
+ closefrom.2 \
+ connect.2 \
+ connectat.2 \
+ cpuset.2 \
+ cpuset_getaffinity.2 \
+ dup.2 \
+ execve.2 \
+ _exit.2 \
+ extattr_get_file.2 \
+ fcntl.2 \
+ ffclock.2 \
+ fhopen.2 \
+ flock.2 \
+ fork.2 \
+ fsync.2 \
+ getdirentries.2 \
+ getdtablesize.2 \
+ getfh.2 \
+ getfsstat.2 \
+ getgid.2 \
+ getgroups.2 \
+ getitimer.2 \
+ getlogin.2 \
+ getloginclass.2 \
+ getpeername.2 \
+ getpgrp.2 \
+ getpid.2 \
+ getpriority.2 \
+ getrlimit.2 \
+ getrusage.2 \
+ getsid.2 \
+ getsockname.2 \
+ getsockopt.2 \
+ gettimeofday.2 \
+ getuid.2 \
+ intro.2 \
+ ioctl.2 \
+ issetugid.2 \
+ jail.2 \
+ kenv.2 \
+ kill.2 \
+ kldfind.2 \
+ kldfirstmod.2 \
+ kldload.2 \
+ kldnext.2 \
+ kldstat.2 \
+ kldsym.2 \
+ kldunload.2 \
+ kqueue.2 \
+ ktrace.2 \
+ link.2 \
+ lio_listio.2 \
+ listen.2 \
lseek.2 \
- madvise.2 mincore.2 minherit.2 mkdir.2 mkfifo.2 mknod.2 mlock.2 \
- mlockall.2 mmap.2 modfind.2 modnext.2 modstat.2 mount.2 mprotect.2 \
- mq_close.2 mq_getattr.2 mq_notify.2 mq_open.2 mq_receive.2 mq_send.2 \
+ madvise.2 \
+ mincore.2 \
+ minherit.2 \
+ mkdir.2 \
+ mkfifo.2 \
+ mknod.2 \
+ mlock.2 \
+ mlockall.2 \
+ mmap.2 \
+ modfind.2 \
+ modnext.2 \
+ modstat.2 \
+ mount.2 \
+ mprotect.2 \
+ mq_close.2 \
+ mq_getattr.2 \
+ mq_notify.2 \
+ mq_open.2 \
+ mq_receive.2 \
+ mq_send.2 \
mq_setattr.2 \
- msgctl.2 msgget.2 msgrcv.2 msgsnd.2 \
- msync.2 munmap.2 nanosleep.2 nfssvc.2 ntp_adjtime.2 open.2 \
- pathconf.2 pdfork.2 pipe.2 poll.2 posix_fadvise.2 posix_fallocate.2 \
- posix_openpt.2 profil.2 \
- pselect.2 ptrace.2 quotactl.2 \
- read.2 readlink.2 reboot.2 recv.2 rename.2 revoke.2 rfork.2 rmdir.2 \
+ msgctl.2 \
+ msgget.2 \
+ msgrcv.2 \
+ msgsnd.2 \
+ msync.2 \
+ munmap.2 \
+ nanosleep.2 \
+ nfssvc.2 \
+ ntp_adjtime.2 \
+ open.2 \
+ pathconf.2 \
+ pdfork.2 \
+ pipe.2 \
+ poll.2 \
+ posix_fadvise.2 \
+ posix_fallocate.2 \
+ posix_openpt.2 \
+ profil.2 \
+ pselect.2 \
+ ptrace.2 \
+ quotactl.2 \
+ read.2 \
+ readlink.2 \
+ reboot.2 \
+ recv.2 \
+ rename.2 \
+ revoke.2 \
+ rfork.2 \
+ rmdir.2 \
rtprio.2
.if !defined(NO_P1003_1B)
-MAN+= sched_get_priority_max.2 sched_setparam.2 \
- sched_setscheduler.2 sched_yield.2
+MAN+= sched_get_priority_max.2 \
+ sched_setparam.2 \
+ sched_setscheduler.2 \
+ sched_yield.2
.endif
-MAN+= sctp_generic_recvmsg.2 sctp_generic_sendmsg.2 sctp_peeloff.2 \
- select.2 semctl.2 semget.2 semop.2 send.2 setfib.2 sendfile.2 \
- setgroups.2 setpgid.2 setregid.2 setresuid.2 setreuid.2 setsid.2 \
- setuid.2 shmat.2 shmctl.2 shmget.2 shm_open.2 shutdown.2 \
- sigaction.2 sigaltstack.2 sigpending.2 sigprocmask.2 sigqueue.2 \
- sigreturn.2 sigstack.2 sigsuspend.2 sigwait.2 sigwaitinfo.2 \
- socket.2 socketpair.2 stat.2 statfs.2 \
- swapon.2 symlink.2 sync.2 sysarch.2 syscall.2 \
- timer_create.2 timer_delete.2 timer_settime.2 \
- truncate.2 umask.2 undelete.2 \
- unlink.2 utimes.2 utrace.2 uuidgen.2 vfork.2 wait.2 write.2
-
-MLINKS+=access.2 eaccess.2 access.2 faccessat.2
+MAN+= sctp_generic_recvmsg.2 \
+ sctp_generic_sendmsg.2 \
+ sctp_peeloff.2 \
+ select.2 \
+ semctl.2 \
+ semget.2 \
+ semop.2 \
+ send.2 \
+ setfib.2 \
+ sendfile.2 \
+ setgroups.2 \
+ setpgid.2 \
+ setregid.2 \
+ setresuid.2 \
+ setreuid.2 \
+ setsid.2 \
+ setuid.2 \
+ shmat.2 \
+ shmctl.2 \
+ shmget.2 \
+ shm_open.2 \
+ shutdown.2 \
+ sigaction.2 \
+ sigaltstack.2 \
+ sigpending.2 \
+ sigprocmask.2 \
+ sigqueue.2 \
+ sigreturn.2 \
+ sigstack.2 \
+ sigsuspend.2 \
+ sigwait.2 \
+ sigwaitinfo.2 \
+ socket.2 \
+ socketpair.2 \
+ stat.2 \
+ statfs.2 \
+ swapon.2 \
+ symlink.2 \
+ sync.2 \
+ sysarch.2 \
+ syscall.2 \
+ timer_create.2 \
+ timer_delete.2 \
+ timer_settime.2 \
+ truncate.2 \
+ umask.2 \
+ undelete.2 \
+ unlink.2 \
+ utimes.2 \
+ utrace.2 \
+ uuidgen.2 \
+ vfork.2 \
+ wait.2 \
+ write.2
+
+MLINKS+=access.2 eaccess.2 \
+ access.2 faccessat.2
MLINKS+=brk.2 sbrk.2
MLINKS+=cap_enter.2 cap_getmode.2
-MLINKS+=cap_new.2 cap_getrights.2
+MLINKS+=cap_fcntls_limit.2 cap_fcntls_get.2
+MLINKS+=cap_ioctls_limit.2 cap_ioctls_get.2
+MLINKS+=cap_rights_limit.2 cap_rights_get.2
MLINKS+=chdir.2 fchdir.2
-MLINKS+=chflags.2 fchflags.2 chflags.2 lchflags.2
-MLINKS+=chmod.2 fchmod.2 chmod.2 fchmodat.2 chmod.2 lchmod.2
-MLINKS+=chown.2 fchown.2 chown.2 fchownat.2 chown.2 lchown.2
-MLINKS+=clock_gettime.2 clock_getres.2 clock_gettime.2 clock_settime.2
-MLINKS+=cpuset.2 cpuset_getid.2 cpuset.2 cpuset_setid.2
+MLINKS+=chflags.2 chflagsat.2 \
+ chflags.2 fchflags.2 \
+ chflags.2 lchflags.2
+MLINKS+=chmod.2 fchmod.2 \
+ chmod.2 fchmodat.2 \
+ chmod.2 lchmod.2
+MLINKS+=chown.2 fchown.2 \
+ chown.2 fchownat.2 \
+ chown.2 lchown.2
+MLINKS+=clock_gettime.2 clock_getres.2 \
+ clock_gettime.2 clock_settime.2
+MLINKS+=cpuset.2 cpuset_getid.2 \
+ cpuset.2 cpuset_setid.2
MLINKS+=cpuset_getaffinity.2 cpuset_setaffinity.2
MLINKS+=dup.2 dup2.2
MLINKS+=execve.2 fexecve.2
@@ -146,7 +306,8 @@ MLINKS+=extattr_get_file.2 extattr.2 \
extattr_get_file.2 extattr_set_fd.2 \
extattr_get_file.2 extattr_set_file.2 \
extattr_get_file.2 extattr_set_link.2
-MLINKS+=ffclock.2 ffclock_getcounter.2 ffclock.2 ffclock_getestimate.2 \
+MLINKS+=ffclock.2 ffclock_getcounter.2 \
+ ffclock.2 ffclock_getestimate.2 \
ffclock.2 ffclock_setestimate.2
MLINKS+=fhopen.2 fhstat.2 fhopen.2 fhstatfs.2
MLINKS+=getdirentries.2 getdents.2
@@ -169,7 +330,8 @@ MLINKS+=jail.2 jail_attach.2 \
jail.2 jail_remove.2 \
jail.2 jail_set.2
MLINKS+=kldunload.2 kldunloadf.2
-MLINKS+=kqueue.2 kevent.2 kqueue.2 EV_SET.3
+MLINKS+=kqueue.2 kevent.2 \
+ kqueue.2 EV_SET.3
MLINKS+=link.2 linkat.2
MLINKS+=madvise.2 posix_madvise.2
MLINKS+=mkdir.2 mkdirat.2
@@ -178,7 +340,8 @@ MLINKS+=mknod.2 mknodat.2
MLINKS+=mlock.2 munlock.2
MLINKS+=mlockall.2 munlockall.2
MLINKS+=modnext.2 modfnext.2
-MLINKS+=mount.2 nmount.2 mount.2 unmount.2
+MLINKS+=mount.2 nmount.2 \
+ mount.2 unmount.2
MLINKS+=mq_receive.2 mq_timedreceive.2
MLINKS+=mq_send.2 mq_timedsend.2
MLINKS+=ntp_adjtime.2 ntp_gettime.2
@@ -188,9 +351,12 @@ MLINKS+=pathconf.2 lpathconf.2
MLINKS+=pdfork.2 pdgetpid.2\
pdfork.2 pdkill.2 \
pdfork.2 pdwait4.2
-MLINKS+=read.2 pread.2 read.2 preadv.2 read.2 readv.2
+MLINKS+=read.2 pread.2 \
+ read.2 preadv.2 \
+ read.2 readv.2
MLINKS+=readlink.2 readlinkat.2
-MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2
+MLINKS+=recv.2 recvfrom.2 \
+ recv.2 recvmsg.2
MLINKS+=rename.2 renameat.2
MLINKS+=rtprio.2 rtprio_thread.2
.if !defined(NO_P1003_1B)
@@ -199,24 +365,41 @@ MLINKS+=sched_get_priority_max.2 sched_get_priority_min.2 \
MLINKS+=sched_setparam.2 sched_getparam.2
MLINKS+=sched_setscheduler.2 sched_getscheduler.2
.endif
-MLINKS+=select.2 FD_CLR.3 select.2 FD_ISSET.3 select.2 FD_SET.3 \
+MLINKS+=select.2 FD_CLR.3 \
+ select.2 FD_ISSET.3 \
+ select.2 FD_SET.3 \
select.2 FD_ZERO.3
-MLINKS+=send.2 sendmsg.2 send.2 sendto.2
+MLINKS+=send.2 sendmsg.2 \
+ send.2 sendto.2
MLINKS+=setpgid.2 setpgrp.2
-MLINKS+=setresuid.2 getresgid.2 setresuid.2 getresuid.2 setresuid.2 setresgid.2
-MLINKS+=setuid.2 setegid.2 setuid.2 seteuid.2 setuid.2 setgid.2
+MLINKS+=setresuid.2 getresgid.2 \
+ setresuid.2 getresuid.2 \
+ setresuid.2 setresgid.2
+MLINKS+=setuid.2 setegid.2 \
+ setuid.2 seteuid.2 \
+ setuid.2 setgid.2
MLINKS+=shmat.2 shmdt.2
MLINKS+=shm_open.2 shm_unlink.2
MLINKS+=sigwaitinfo.2 sigtimedwait.2
-MLINKS+=stat.2 fstat.2 stat.2 fstatat.2 stat.2 lstat.2
+MLINKS+=stat.2 fstat.2 \
+ stat.2 fstatat.2 \
+ stat.2 lstat.2
MLINKS+=statfs.2 fstatfs.2
MLINKS+=swapon.2 swapoff.2
MLINKS+=symlink.2 symlinkat.2
MLINKS+=syscall.2 __syscall.2
-MLINKS+=timer_settime.2 timer_getoverrun.2 timer_settime.2 timer_gettime.2
+MLINKS+=timer_settime.2 timer_getoverrun.2 \
+ timer_settime.2 timer_gettime.2
MLINKS+=truncate.2 ftruncate.2
MLINKS+=unlink.2 unlinkat.2
-MLINKS+=utimes.2 futimes.2 utimes.2 futimesat.2 utimes.2 lutimes.2
-MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2 \
- wait.2 waitid.2 wait.2 wait6.2
-MLINKS+=write.2 pwrite.2 write.2 pwritev.2 write.2 writev.2
+MLINKS+=utimes.2 futimes.2 \
+ utimes.2 futimesat.2 \
+ utimes.2 lutimes.2
+MLINKS+=wait.2 wait3.2 \
+ wait.2 wait4.2 \
+ wait.2 waitpid.2 \
+ wait.2 waitid.2 \
+ wait.2 wait6.2
+MLINKS+=write.2 pwrite.2 \
+ write.2 pwritev.2 \
+ write.2 writev.2
diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map
index babae30..6faa0af 100644
--- a/lib/libc/sys/Symbol.map
+++ b/lib/libc/sys/Symbol.map
@@ -364,7 +364,6 @@ FBSD_1.2 {
cap_enter;
cap_getmode;
cap_new;
- cap_getrights;
getloginclass;
pdfork;
pdgetpid;
@@ -379,7 +378,17 @@ FBSD_1.2 {
};
FBSD_1.3 {
+ bindat;
+ cap_fcntls_get;
+ cap_fcntls_limit;
+ cap_ioctls_get;
+ cap_ioctls_limit;
+ cap_rights_get;
+ cap_rights_limit;
+ cap_sandboxed;
+ chflagsat;
clock_getcpuclockid2;
+ connectat;
ffclock_getcounter;
ffclock_getestimate;
ffclock_setestimate;
diff --git a/lib/libc/sys/accept.2 b/lib/libc/sys/accept.2
index df6c0b1..978b948 100644
--- a/lib/libc/sys/accept.2
+++ b/lib/libc/sys/accept.2
@@ -28,7 +28,7 @@
.\" @(#)accept.2 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd December 11, 1993
+.Dd March 26, 2013
.Dt ACCEPT 2
.Os
.Sh NAME
@@ -57,7 +57,13 @@ queue of pending connections, creates a new socket,
and allocates a new file descriptor for the socket which
inherits the state of the
.Dv O_NONBLOCK
-property from the original socket
+and
+.Dv O_ASYNC
+properties and the destination of
+.Dv SIGIO
+and
+.Dv SIGURG
+signals from the original socket
.Fa s .
.Pp
If no pending connections are
@@ -129,7 +135,11 @@ to pre-process incoming connections.
.Pp
Portable programs should not rely on the
.Dv O_NONBLOCK
-property being inherited.
+and
+.Dv O_ASYNC
+properties and the signal destination being inherited,
+but should set them explicitly using
+.Xr fcntl 2 .
.Sh RETURN VALUES
The call returns \-1 on error.
If it succeeds, it returns a non-negative
diff --git a/lib/libc/sys/bindat.2 b/lib/libc/sys/bindat.2
new file mode 100644
index 0000000..9274679
--- /dev/null
+++ b/lib/libc/sys/bindat.2
@@ -0,0 +1,109 @@
+.\" Copyright (c) 2013 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Pawel Jakub Dawidek under sponsorship from
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 13, 2013
+.Dt BINDAT 2
+.Os
+.Sh NAME
+.Nm bindat
+.Nd assign a local protocol address to a socket
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.Pp
+.In fcntl.h
+.Ft int
+.Fn bindat "int fd" "int s" "const struct sockaddr *addr" "socklen_t addrlen"
+.Sh DESCRIPTION
+The
+.Fn bindat
+system call assigns the local protocol address to a socket.
+It works just like the
+.Xr bind 2
+system call with two exceptions:
+.Pp
+.Bl -enum -offset indent -compact
+.It
+It is limited to sockets in the PF_LOCAL domain.
+.Pp
+.It
+If the file path stored in the
+.Fa sun_path
+field of the sockaddr_un structure is a relative path, it is located relative
+to the directory associated with the file descriptor
+.Fa fd .
+If
+.Fn bindat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is identical
+to a call to
+.Xr bind 2 .
+.El
+.Sh RETURN VALUES
+.Rv -std bindat
+.Sh ERRORS
+The
+.Fn bindat
+system call may fail with the same errors as the
+.Xr bind 2
+system call for a UNIX domain socket or with the following errors:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa sun_path
+field does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor.
+.It Bq Er ENOTDIR
+The
+.Fa sun_path
+field is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
+.Sh SEE ALSO
+.Xr bind 2 ,
+.Xr connectat 2 ,
+.Xr socket 2 ,
+.Xr unix 4
+.Sh AUTHORS
+The
+.Nm
+was developed by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship from the FreeBSD Foundation.
diff --git a/lib/libc/sys/cap_enter.2 b/lib/libc/sys/cap_enter.2
index 5454ec9..3369669 100644
--- a/lib/libc/sys/cap_enter.2
+++ b/lib/libc/sys/cap_enter.2
@@ -58,8 +58,10 @@ or
.Xr pdfork 2
will be placed in capability mode from inception.
.Pp
-When combined with capabilities created with
-.Xr cap_new 2 ,
+When combined with
+.Xr cap_rights_limit 2 ,
+.Xr cap_ioctls_limit 2 ,
+.Xr cap_fcntls_limit 2 ,
.Fn cap_enter
may be used to create kernel-enforced sandboxes in which
appropriately-crafted applications or application components may be run.
@@ -71,11 +73,6 @@ sandbox.
Creating effective process sandboxes is a tricky process that involves
identifying the least possible rights required by the process and then
passing those rights into the process in a safe manner.
-See the CAVEAT
-section of
-.Xr cap_new 2
-for why this is particularly tricky with UNIX file descriptors as the
-canonical representation of a right.
Consumers of
.Fn cap_enter
should also be aware of other inherited rights, such as access to VM
@@ -87,9 +84,35 @@ to create a runtime environment inside the sandbox that has as few implicitly
acquired rights as possible.
.Sh RETURN VALUES
.Rv -std cap_enter cap_getmode
+.Sh ERRORS
+The
+.Fn cap_enter
+and
+.Fn cap_getmode
+system calls
+will fail if:
+.Bl -tag -width Er
+.It Bq Er ENOSYS
+The kernel is compiled without:
+.Pp
+.Cd "options CAPABILITY_MODE"
+.El
+.Pp
+The
+.Fn cap_getmode
+system call may also return the following error:
+.Bl -tag -width Er
+.It Bq Er EFAULT
+Pointer
+.Fa modep
+points outside the process's allocated address space.
+.El
.Sh SEE ALSO
-.Xr cap_new 2 ,
+.Xr cap_fcntls_limit 2 ,
+.Xr cap_ioctls_limit 2 ,
+.Xr cap_rights_limit 2 ,
.Xr fexecve 2 ,
+.Xr cap_sandboxed 3 ,
.Xr capsicum 4
.Sh HISTORY
Support for capabilities and capabilities mode was developed as part of the
diff --git a/lib/libc/sys/cap_fcntls_limit.2 b/lib/libc/sys/cap_fcntls_limit.2
new file mode 100644
index 0000000..b1fca2c
--- /dev/null
+++ b/lib/libc/sys/cap_fcntls_limit.2
@@ -0,0 +1,126 @@
+.\"
+.\" Copyright (c) 2012 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 20, 2012
+.Dt CAP_FCNTLS_LIMIT 2
+.Os
+.Sh NAME
+.Nm cap_fcntls_limit ,
+.Nm cap_fcntls_get
+.Nd manage allowed fcntl commands
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/capability.h
+.Ft int
+.Fn cap_fcntls_limit "int fd" "uint32_t fcntlrights"
+.Ft int
+.Fn cap_fcntls_get "int fd" "uint32_t *fcntlrightsp"
+.Sh DESCRIPTION
+If a file descriptor is granted the
+.Dv CAP_FCNTL
+capability right, the list of allowed
+.Xr fcntl 2
+commands can be selectively reduced (but never expanded) with the
+.Fn cap_fcntls_limit
+system call.
+.Pp
+A bitmask of allowed fcntls commands for a given file descriptor can be obtained
+with the
+.Fn cap_fcntls_get
+system call.
+.Sh FLAGS
+The following flags may be specified in the
+.Fa fcntlrights
+argument or returned in the
+.Fa fcntlrightsp
+argument:
+.Bl -tag -width CAP_FCNTL_GETOWN
+.It Dv CAP_FCNTL_GETFL
+Permit
+.Dv F_GETFL
+command.
+.It Dv CAP_FCNTL_SETFL
+Permit
+.Dv F_SETFL
+command.
+.It Dv CAP_FCNTL_GETOWN
+Permit
+.Dv F_GETOWN
+command.
+.It Dv CAP_FCNTL_SETOWN
+Permit
+.Dv F_SETOWN
+command.
+.El
+.Sh RETURN VALUES
+.Rv -std
+.Sh ERRORS
+.Fn cap_fcntls_limit
+succeeds unless:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid descriptor.
+.It Bq Er EINVAL
+An invalid flag has been passed in
+.Fa fcntlrights .
+.It Bq Er ENOTCAPABLE
+.Fa fcntlrights
+would expand the list of allowed
+.Xr fcntl 2
+commands.
+.El
+.Pp
+.Fn cap_fcntls_get
+succeeds unless:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid descriptor.
+.It Bq Er EFAULT
+The
+.Fa fcntlrightsp
+argument points at an invalid address.
+.El
+.Sh SEE ALSO
+.Xr cap_ioctls_limit 2 ,
+.Xr cap_rights_limit 2 ,
+.Xr fcntl 2
+.Sh HISTORY
+Support for capabilities and capabilities mode was developed as part of the
+.Tn TrustedBSD
+Project.
+.Sh AUTHORS
+This function was created by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship of the FreeBSD Foundation.
diff --git a/lib/libc/sys/cap_ioctls_limit.2 b/lib/libc/sys/cap_ioctls_limit.2
new file mode 100644
index 0000000..2c21211
--- /dev/null
+++ b/lib/libc/sys/cap_ioctls_limit.2
@@ -0,0 +1,157 @@
+.\"
+.\" Copyright (c) 2012 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Pawel Jakub Dawidek under sponsorship
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd September 20, 2012
+.Dt CAP_IOCTLS_LIMIT 2
+.Os
+.Sh NAME
+.Nm cap_ioctls_limit ,
+.Nm cap_ioctls_get
+.Nd manage allowed ioctl commands
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/capability.h
+.Ft int
+.Fn cap_ioctls_limit "int fd" "const unsigned long *cmds" "size_t ncmds"
+.Ft ssize_t
+.Fn cap_ioctls_get "int fd" "unsigned long *cmds" "size_t maxcmds"
+.Sh DESCRIPTION
+If a file descriptor is granted the
+.Dv CAP_IOCTL
+capability right, the list of allowed
+.Xr ioctl 2
+commands can be selectively reduced (but never expanded) with the
+.Fn cap_ioctls_limit
+system call.
+The
+.Fa cmds
+argument is an array of
+.Xr ioctl 2
+commands and the
+.Fa ncmds
+argument specifies the number of elements in the array.
+There might be up to
+.Va 256
+elements in the array.
+.Pp
+The list of allowed ioctl commands for a given file descriptor can be obtained
+with the
+.Fn cap_ioctls_get
+system call.
+The
+.Fa cmds
+argument points at memory that can hold up to
+.Fa maxcmds
+values.
+The function populates the provided buffer with up to
+.Fa maxcmds
+elements, but always returns the total number of ioctl commands allowed for the
+given file descriptor.
+The total number of ioctls commands for the given file descriptor can be
+obtained by passing
+.Dv NULL as the
+.Fa cmds
+argument and
+.Va 0
+as the
+.Fa maxcmds
+argument.
+If all ioctl commands are allowed
+.Dv ( CAP_IOCTL
+capability right is assigned to the file descriptor and the
+.Fn cap_ioctls_limit
+system call was never called for this file descriptor), the
+.Fn cap_ioctls_get
+system call will return
+.Dv CAP_IOCTLS_ALL
+and won't modify the buffer pointed out by the
+.Fa cmds
+argument.
+.Sh RETURN VALUES
+.Rv -std cap_ioctls_limit
+.Pp
+The
+.Fn cap_ioctls_limit
+function, if successfull, returns the total number of allowed ioctl commands or
+the value
+.Dv INT_MAX
+if all ioctls commands are allowed.
+On failure the value
+.Va -1
+is returned and the global variable errno is set to indicate the error.
+.Sh ERRORS
+.Fn cap_ioctls_limit
+succeeds unless:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid descriptor.
+.It Bq Er EFAULT
+The
+.Fa cmds
+argument points at an invalid address.
+.It Bq Er EINVAL
+The
+.Fa ncmds
+argument is greater than
+.Va 256 .
+.It Bq Er ENOTCAPABLE
+.Fa cmds
+would expand the list of allowed
+.Xr ioctl 2
+commands.
+.El
+.Pp
+.Fn cap_ioctls_get
+succeeds unless:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa fd
+argument is not a valid descriptor.
+.It Bq Er EFAULT
+The
+.Fa cmds
+argument points at invalid address.
+.El
+.Sh SEE ALSO
+.Xr cap_fcntls_limit 2 ,
+.Xr cap_rights_limit 2 ,
+.Xr ioctl 2
+.Sh HISTORY
+Support for capabilities and capabilities mode was developed as part of the
+.Tn TrustedBSD
+Project.
+.Sh AUTHORS
+This function was created by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship of the FreeBSD Foundation.
diff --git a/lib/libc/sys/cap_new.2 b/lib/libc/sys/cap_rights_limit.2
index a18fd3b..2e18dd2 100644
--- a/lib/libc/sys/cap_new.2
+++ b/lib/libc/sys/cap_rights_limit.2
@@ -1,10 +1,14 @@
.\"
.\" Copyright (c) 2008-2010 Robert N. M. Watson
+.\" Copyright (c) 2012-2013 The FreeBSD Foundation
.\" All rights reserved.
.\"
.\" This software was developed at the University of Cambridge Computer
.\" Laboratory with support from a grant from Google, Inc.
.\"
+.\" Portions of this documentation were written by Pawel Jakub Dawidek
+.\" under sponsorship from the FreeBSD Foundation.
+.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
@@ -28,76 +32,48 @@
.\"
.\" $FreeBSD$
.\"
-.Dd July 20, 2011
-.Dt CAP_NEW 2
+.Dd February 23, 2013
+.Dt CAP_RIGHTS_LIMIT 2
.Os
.Sh NAME
-.Nm cap_new ,
-.Nm cap_getrights
-.Nd System calls to manipulate capabilities
+.Nm cap_rights_limit ,
+.Nm cap_rights_get
+.Nd manage capability rights
.Sh LIBRARY
.Lb libc
.Sh SYNOPSIS
.In sys/capability.h
.Ft int
-.Fn cap_new "int fd" "cap_rights_t rights"
+.Fn cap_rights_limit "int fd" "cap_rights_t rights"
.Ft int
-.Fn cap_getrights "int fd" "cap_rights_t *rightsp"
+.Fn cap_rights_get "int fd" "cap_rights_t *rightsp"
.Sh DESCRIPTION
-Capabilities are special file descriptors derived from an existing file
-descriptor, such as one returned by
+When a file descriptor is created by a function such as
.Xr fhopen 2 ,
.Xr kqueue 2 ,
.Xr mq_open 2 ,
.Xr open 2 ,
+.Xr openat 2 ,
+.Xr pdfork 2 ,
.Xr pipe 2 ,
.Xr shm_open 2 ,
.Xr socket 2 ,
or
.Xr socketpair 2 ,
-but with a restricted set of permitted operations determined by a rights
-mask set when the capability is created.
-These restricted rights cannot be changed after the capability is created,
-although further capabilities with yet more restricted rights may be created
-from an existing capability.
-In every other sense, a capability behaves in the same way as the file
-descriptor it was created from.
-.Pp
-.Fn cap_new
-creates a new capability for the existing file descriptor
-.Fa fd ,
-and returns a file descriptor for it.
-Operations on the capability will be limited to those permitted by
-.Fa rights ,
-which is static for the lifetime of the capability.
-If
-.Fa fd
-refers to an existing capability, then
-.Fa rights
-must be equal to or a subset of the rights on that capability.
-As with
-.Xr dup 2
-and
-.Xr dup2 2 ,
-many properties are shared between the new capability and the existing file
-descriptor, including open file flags, blocking disposition, and file offset.
-Many applications will prefer to use the
-.Xr cap_limitfd 3
-library call, part of
-.Xr libcapsicum 3 ,
-as it offers a more convenient interface.
-.Pp
-.Fn cap_getrights
-queries the rights associated with the capability referred to by file
-descriptor
-.Fa fd .
+it is assigned all capability rights.
+Those rights can be reduced (but never expanded) by using the
+.Fn cap_rights_limit
+system call.
+Once capability rights are reduced, operations on the file descriptor will be
+limited to those permitted by
+.Fa rights .
.Pp
-These system calls, when combined with
-.Xr cap_enter 2 ,
-may be used to construct process sandboxes with highly granular rights
-assignment.
+A bitmask of capability rights assigned to a file descriptor can be obtained with
+the
+.Fn cap_rights_get
+system call.
.Sh RIGHTS
-The following rights may be specified in a new capability rights mask:
+The following rights may be specified in a rights mask:
.Bl -tag -width CAP_EXTATTR_DELETE
.It Dv CAP_ACCEPT
Permit
@@ -128,12 +104,27 @@ or
and that socket options set with
.Xr setsockopt 2
may also affect binding behavior.
+.It Dv CAP_BINDAT
+Permit
+.Xr bindat 2 .
+This right has to be present on the directory descriptor.
.It Dv CAP_CONNECT
Permit
.Xr connect 2 ;
also required for
.Xr sendto 2
with a non-NULL destination address.
+.It Dv CAP_CONNECTAT
+Permit
+.Xr connectat 2 .
+This right has to be present on the directory descriptor.
+.It Dv CAP_CREATE
+Permit
+.Xr openat 2
+with the
+.Dv O_CREAT
+flag.
+.\" XXXPJD: Doesn't exist anymore.
.It Dv CAP_EVENT
Permit
.Xr select 2 ,
@@ -143,7 +134,12 @@ and
to be used in monitoring the file descriptor for events.
.It Dv CAP_FEXECVE
Permit
-.Xr fexecve 2 ;
+.Xr fexecve 2
+and
+.Xr openat 2
+with the
+.Dv O_EXEC
+flag;
.Dv CAP_READ
will also be required.
.It Dv CAP_EXTATTR_DELETE
@@ -163,22 +159,57 @@ Permit
.Xr fchdir 2 .
.It Dv CAP_FCHFLAGS
Permit
-.Xr fchflags 2 .
+.Xr fchflags 2
+and
+.Xr chflagsat 2 .
+.It Dv CAP_CHFLAGSAT
+An alias to
+.Dv CAP_FCHFLAGS .
.It Dv CAP_FCHMOD
Permit
-.Xr fchmod 2 .
+.Xr fchmod 2
+and
+.Xr fchmodat 2 .
+.It Dv CAP_FCHMODAT
+An alias to
+.Dv CAP_FCHMOD .
.It Dv CAP_FCHOWN
Permit
-.Xr fchown 2 .
+.Xr fchown 2
+and
+.Xr fchownat 2 .
+.It Dv CAP_FCHOWNAT
+An alias to
+.Dv CAP_FCHOWN .
.It Dv CAP_FCNTL
Permit
-.Xr fcntl 2 ;
-be aware that this call provides indirect access to other operations, such as
-.Xr flock 2 .
+.Xr fcntl 2 .
+Note that only the
+.Dv F_GETFL ,
+.Dv F_SETFL ,
+.Dv F_GETOWN
+and
+.Dv F_SETOWN
+commands require this capability right.
+Also note that the list of permitted commands can be further limited with the
+.Xr cap_fcntls_limit 2
+system call.
.It Dv CAP_FLOCK
Permit
-.Xr flock 2
-and related calls.
+.Xr flock 2 ,
+.Xr fcntl 2
+(with
+.Dv F_GETLK ,
+.Dv F_SETLK
+or
+.Dv F_SETLKW
+flag) and
+.Xr openat 2
+(with
+.Dv O_EXLOCK
+or
+.Dv O_SHLOCK
+flag).
.It Dv CAP_FPATHCONF
Permit
.Xr fpathconf 2 .
@@ -186,22 +217,42 @@ Permit
Permit UFS background-fsck operations on the descriptor.
.It Dv CAP_FSTAT
Permit
-.Xr fstat 2 .
+.Xr fstat 2
+and
+.Xr fstatat 2 .
+.It Dv CAP_FSTATAT
+An alias to
+.Dv CAP_FSTAT .
.It Dv CAP_FSTATFS
Permit
.Xr fstatfs 2 .
.It Dv CAP_FSYNC
Permit
-.Xr aio_fsync 2
+.Xr aio_fsync 2 ,
+.Xr fsync 2
and
-.Xr fsync 2 .
-.Pp
+.Xr openat 2
+with
+.Dv O_FSYNC
+or
+.Dv O_SYNC
+flag.
.It Dv CAP_FTRUNCATE
Permit
-.Xr ftruncate 2 .
+.Xr ftruncate 2
+and
+.Xr openat 2
+with the
+.Dv O_TRUNC
+flag.
.It Dv CAP_FUTIMES
Permit
-.Xr futimes 2 .
+.Xr futimes 2
+and
+.Xr futimesat 2 .
+.It Dv CAP_FUTIMESAT
+An alias to
+.Dv CAP_FUTIMES .
.It Dv CAP_GETPEERNAME
Permit
.Xr getpeername 2 .
@@ -216,42 +267,106 @@ Permit
.Xr ioctl 2 .
Be aware that this system call has enormous scope, including potentially
global scope for some objects.
+The list of permitted ioctl commands can be further limited with the
+.Xr cap_ioctls_limit 2
+system call.
+.\" XXXPJD: Doesn't exist anymore.
.It Dv CAP_KEVENT
Permit
.Xr kevent 2 ;
.Dv CAP_EVENT
is also required on file descriptors that will be monitored using
.Xr kevent 2 .
+.It Dv CAP_LINKAT
+Permit
+.Xr linkat 2
+and
+.Xr renameat 2 .
+This right is required for the destination directory descriptor.
.It Dv CAP_LISTEN
Permit
.Xr listen 2 ;
not much use (generally) without
.Dv CAP_BIND .
.It Dv CAP_LOOKUP
-Permit the file descriptor to be used as a starting directory for calls such
-as
+Permit the file descriptor to be used as a starting directory for calls such as
.Xr linkat 2 ,
.Xr openat 2 ,
and
.Xr unlinkat 2 .
-Note that these calls are not available in capability mode as they manipulate
-a global name space; see
-.Xr cap_enter 2
-for details.
.It Dv CAP_MAC_GET
Permit
.Xr mac_get_fd 3 .
.It Dv CAP_MAC_SET
Permit
.Xr mac_set_fd 3 .
+.It Dv CAP_MKDIRAT
+Permit
+.Xr mkdirat 2 .
+.It Dv CAP_MKFIFOAT
+Permit
+.Xr mkfifoat 2 .
+.It Dv CAP_MKNODAT
+Permit
+.Xr mknodat 2 .
.It Dv CAP_MMAP
Permit
-.Xr mmap 2 ;
-specific invocations may also require
+.Xr mmap 2
+with the
+.Dv PROT_NONE
+protection.
+.It Dv CAP_MMAP_R
+Permit
+.Xr mmap 2
+with the
+.Dv PROT_READ
+protection.
+This also implies
.Dv CAP_READ
-or
-.Dv CAP_WRITE .
-.Pp
+and
+.Dv CAP_SEEK
+rights.
+.It Dv CAP_MMAP_W
+Permit
+.Xr mmap 2
+with the
+.Dv PROT_WRITE
+protection.
+This also implies
+.Dv CAP_WRITE
+and
+.Dv CAP_SEEK
+rights.
+.It Dv CAP_MMAP_X
+Permit
+.Xr mmap 2
+with the
+.Dv PROT_EXEC
+protection.
+This also implies
+.Dv CAP_SEEK
+right.
+.It Dv CAP_MMAP_RW
+Implies
+.Dv CAP_MMAP_R
+and
+.Dv CAP_MMAP_W .
+.It Dv CAP_MMAP_RX
+Implies
+.Dv CAP_MMAP_R
+and
+.Dv CAP_MMAP_X .
+.It Dv CAP_MMAP_WX
+Implies
+.Dv CAP_MMAP_W
+and
+.Dv CAP_MMAP_X .
+.It Dv CAP_MMAP_RWX
+Implies
+.Dv CAP_MMAP_R ,
+.Dv CAP_MMAP_W
+and
+.Dv CAP_MMAP_X .
.It Dv CAP_PDGETPID
Permit
.Xr pdgetpid 2 .
@@ -264,30 +379,46 @@ Permit
.It Dv CAP_PEELOFF
Permit
.Xr sctp_peeloff 2 .
+.\" XXXPJD: Not documented.
+.It Dv CAP_POLL_EVENT
+.\" XXXPJD: Not documented.
+.It Dv CAP_POST_EVENT
+.It Dv CAP_PREAD
+Implies
+.Dv CAP_SEEK
+and
+.Dv CAP_READ .
+.It Dv CAP_PWRITE
+Implies
+.Dv CAP_SEEK
+and
+.Dv CAP_WRITE .
.It Dv CAP_READ
Allow
.Xr aio_read 2 ,
-.Xr pread 2 ,
+.Xr openat
+with the
+.Dv O_RDONLY flag,
.Xr read 2 ,
.Xr recv 2 ,
.Xr recvfrom 2 ,
-.Xr recvmsg 2 ,
+.Xr recvmsg 2
and related system calls.
-.Pp
-For files and other seekable objects,
-.Dv CAP_SEEK
-may also be required.
-.It Dv CAP_REVOKE
+.It Dv CAP_RECV
+An alias to
+.Dv CAP_READ .
+.It Dv CAP_RENAMEAT
Permit
-.Xr frevoke 2
-in certain ABI compatibility modes that support this system call.
+.Xr renameat 2 .
+This right is required for the source directory descriptor.
.It Dv CAP_SEEK
Permit operations that seek on the file descriptor, such as
.Xr lseek 2 ,
-but also required for I/O system calls that modify the file offset, such as
-.Xr read 2
+but also required for I/O system calls that can read or write at any position
+in the file, such as
+.Xr pread 2
and
-.Xr write 2 .
+.Xr pwrite 2 .
.It Dv CAP_SEM_GETVALUE
Permit
.Xr sem_getvalue 3 .
@@ -299,6 +430,9 @@ Permit
.Xr sem_wait 3
and
.Xr sem_trywait 3 .
+.It Dv CAP_SEND
+An alias to
+.Dv CAP_WRITE .
.It Dv CAP_SETSOCKOPT
Permit
.Xr setsockopt 2 ;
@@ -308,49 +442,56 @@ connecting, and other behaviors with global scope.
Permit explicit
.Xr shutdown 2 ;
closing the socket will also generally shut down any connections on it.
+.It Dv CAP_SYMLINKAT
+Permit
+.Xr symlinkat 2 .
.It Dv CAP_TTYHOOK
Allow configuration of TTY hooks, such as
.Xr snp 4 ,
on the file descriptor.
+.It Dv CAP_UNLINKAT
+Permit
+.Xr unlinkat 2
+and
+.Xr renameat 2 .
+This right is only required for
+.Xr renameat 2
+on the destination directory descriptor if the destination object already
+exists and will be removed by the rename.
.It Dv CAP_WRITE
Allow
.Xr aio_write 2 ,
-.Xr pwrite 2 ,
+.Xr openat 2
+with
+.Dv O_WRONLY
+and
+.Dv O_APPEND
+flags,
.Xr send 2 ,
.Xr sendmsg 2 ,
.Xr sendto 2 ,
.Xr write 2 ,
and related system calls.
-.Pp
-For files and other seekable objects,
-.Dv CAP_SEEK
-may also be required.
-.Pp
For
.Xr sendto 2
with a non-NULL connection address,
.Dv CAP_CONNECT
is also required.
+For
+.Xr openat 2
+with the
+.Dv O_WRONLY
+flag, but without the
+.Dv O_APPEND
+flag,
+.Dv CAP_SEEK
+is also required.
.El
-.Sh CAVEAT
-The
-.Fn cap_new
-system call and the capabilities it creates may be used to assign
-fine-grained rights to sandboxed processes running in capability mode.
-However, the semantics of objects accessed via file descriptors are complex,
-so caution should be exercised in passing object capabilities into sandboxes.
.Sh RETURN VALUES
-If successful,
-.Fn cap_new
-returns a non-negative integer, termed a file descriptor.
-It returns -1 on failure, and sets
-.Va errno
-to indicate the error.
-.Pp
-.Rv -std cap_getrights
+.Rv -std
.Sh ERRORS
-.Fn cap_new
-may return the following errors:
+.Fn cap_rights_limit
+succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
@@ -359,29 +500,23 @@ argument is not a valid active descriptor.
.It Bq Er EINVAL
An invalid right has been requested in
.Fa rights .
-.It Bq Er EMFILE
-The process has already reached its limit for open file descriptors.
-.It Bq Er ENFILE
-The system file table is full.
-.It Bq Er EPERM
+.It Bq Er ENOTCAPABLE
.Fa rights
contains requested rights not present in the current rights mask associated
-with the capability referenced by
-.Fa fd ,
-if any.
+with the given file descriptor.
.El
.Pp
-.Fn cap_getrights
-may return the following errors:
+.Fn cap_rights_get
+succeeds unless:
.Bl -tag -width Er
.It Bq Er EBADF
The
.Fa fd
argument is not a valid active descriptor.
-.It Bq Er EINVAL
+.It Bq Er EFAULT
The
-.Fa fd
-argument is not a capability.
+.Fa rightsp
+argument points at an invalid address.
.El
.Sh SEE ALSO
.Xr accept 2 ,
@@ -389,8 +524,13 @@ argument is not a capability.
.Xr aio_read 2 ,
.Xr aio_write 2 ,
.Xr bind 2 ,
+.Xr bindat 2 ,
.Xr cap_enter 2 ,
+.Xr cap_fcntls_limit 2 ,
+.Xr cap_ioctls_limit 2 ,
+.Xr cap_rights_limit 2 ,
.Xr connect 2 ,
+.Xr connectat 2 ,
.Xr dup 2 ,
.Xr dup2 2 ,
.Xr extattr_delete_fd 2 ,
@@ -421,6 +561,7 @@ argument is not a capability.
.Xr mq_open 2 ,
.Xr open 2 ,
.Xr openat 2 ,
+.Xr pdfork 2 ,
.Xr pdgetpid 2 ,
.Xr pdkill 2 ,
.Xr pdwait4 2 ,
@@ -432,6 +573,7 @@ argument is not a capability.
.Xr recv 2 ,
.Xr recvfrom 2 ,
.Xr recvmsg 2 ,
+.Xr renameat 2 ,
.Xr sctp_peeloff 2 ,
.Xr select 2 ,
.Xr send 2 ,
@@ -442,6 +584,7 @@ argument is not a capability.
.Xr shutdown 2 ,
.Xr socket 2 ,
.Xr socketpair 2 ,
+.Xr symlinkat 2 ,
.Xr unlinkat 2 ,
.Xr write 2 ,
.Xr acl_delete_fd_np 3 ,
@@ -463,10 +606,9 @@ Support for capabilities and capabilities mode was developed as part of the
.Tn TrustedBSD
Project.
.Sh AUTHORS
-These functions and the capability facility were created by
-.An "Robert N. M. Watson"
-at the University of Cambridge Computer Laboratory with support from a grant
-from Google, Inc.
+This function was created by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship of the FreeBSD Foundation.
.Sh BUGS
This man page should list the set of permitted system calls more specifically
for each capability right.
diff --git a/lib/libc/sys/chflags.2 b/lib/libc/sys/chflags.2
index 1c2eb78..5bc2ba2 100644
--- a/lib/libc/sys/chflags.2
+++ b/lib/libc/sys/chflags.2
@@ -28,7 +28,7 @@
.\" @(#)chflags.2 8.3 (Berkeley) 5/2/95
.\" $FreeBSD$
.\"
-.Dd Apr 13, 2012
+.Dd March 22, 2013
.Dt CHFLAGS 2
.Os
.Sh NAME
@@ -42,11 +42,13 @@
.In sys/stat.h
.In unistd.h
.Ft int
-.Fn chflags "const char *path" "u_long flags"
+.Fn chflags "const char *path" "unsigned long flags"
.Ft int
-.Fn lchflags "const char *path" "int flags"
+.Fn lchflags "const char *path" "unsigned long flags"
.Ft int
-.Fn fchflags "int fd" "u_long flags"
+.Fn fchflags "int fd" "unsigned long flags"
+.Ft int
+.Fn chflagsat "int fd" "const char *path" "unsigned long flags" "int atflag"
.Sh DESCRIPTION
The file whose name
is given by
@@ -66,6 +68,45 @@ in which case
will change the flags of the link itself,
rather than the file it points to.
.Pp
+The
+.Fn chflagsat
+is equivalent to either
+.Fn chflags
+or
+.Fn lchflags
+depending on the
+.Fa atflag
+except in the case where
+.Fa path
+specifies a relative path.
+In this case the file to be changed is determined relative to the directory
+associated with the file descriptor
+.Fa fd
+instead of the current working directory.
+The values for the
+.Fa atflag
+are constructed by a bitwise-inclusive OR of flags from the following list,
+defined in
+.In fcntl.h :
+.Bl -tag -width indent
+.It Dv AT_SYMLINK_NOFOLLOW
+If
+.Fa path
+names a symbolic link, then the flags of the symbolic link are changed.
+.El
+.Pp
+If
+.Fn chflagsat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used.
+If also
+.Fa atflag
+is zero, the behavior is identical to a call to
+.Fn chflags .
+.Pp
The flags specified are formed by
.Em or Ns 'ing
the following values
@@ -98,7 +139,7 @@ If one of
or
.Dv SF_NOUNLINK
is set a non-super-user cannot change any flags and even the super-user
-can change flags only if securelevel is greater than 0.
+can change flags only if securelevel is 0.
(See
.Xr init 8
for details.)
@@ -232,3 +273,11 @@ and
.Fn fchflags
system calls first appeared in
.Bx 4.4 .
+The
+.Fn lchflags
+system call first appeared in
+.Fx 5.0 .
+The
+.Fn chflagsat
+system call first appeared in
+.Fx 10.0 .
diff --git a/lib/libc/sys/connectat.2 b/lib/libc/sys/connectat.2
new file mode 100644
index 0000000..8cebf98
--- /dev/null
+++ b/lib/libc/sys/connectat.2
@@ -0,0 +1,109 @@
+.\" Copyright (c) 2013 The FreeBSD Foundation
+.\" All rights reserved.
+.\"
+.\" This documentation was written by Pawel Jakub Dawidek under sponsorship from
+.\" the FreeBSD Foundation.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD$
+.\"
+.Dd February 13, 2013
+.Dt CONNECTAT 2
+.Os
+.Sh NAME
+.Nm connectat
+.Nd initiate a connection on a socket
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.Pp
+.In fcntl.h
+.Ft int
+.Fn connectat "int fd" "int s" "const struct sockaddr *name" "socklen_t namelen"
+.Sh DESCRIPTION
+The
+.Fn connectat
+system call initiates a connection on a socket.
+It works just like the
+.Xr connect 2
+system call with two exceptions:
+.Pp
+.Bl -enum -offset indent -compact
+.It
+It is limited to sockets in the PF_LOCAL domain.
+.Pp
+.It
+If the file path stored in the
+.Fa sun_path
+field of the sockaddr_un structure is a relative path, it is located relative
+to the directory associated with the file descriptor
+.Fa fd .
+If
+.Fn connectat
+is passed the special value
+.Dv AT_FDCWD
+in the
+.Fa fd
+parameter, the current working directory is used and the behavior is identical
+to a call to
+.Xr connect 2 .
+.El
+.Sh RETURN VALUES
+.Rv -std connectat
+.Sh ERRORS
+The
+.Fn connectat
+system call may fail with the same errors as the
+.Xr connect 2
+system call for a UNIX domain socket or with the following errors:
+.Bl -tag -width Er
+.It Bq Er EBADF
+The
+.Fa sun_path
+field does not specify an absolute path and the
+.Fa fd
+argument is neither
+.Dv AT_FDCWD
+nor a valid file descriptor.
+.It Bq Er ENOTDIR
+The
+.Fa sun_path
+field is not an absolute path and
+.Fa fd
+is neither
+.Dv AT_FDCWD
+nor a file descriptor associated with a directory.
+.El
+.Sh SEE ALSO
+.Xr bindat 2 ,
+.Xr connect 2 ,
+.Xr socket 2 ,
+.Xr unix 4
+.Sh AUTHORS
+The
+.Nm
+was developed by
+.An Pawel Jakub Dawidek Aq pawel@dawidek.net
+under sponsorship from the FreeBSD Foundation.
diff --git a/lib/libc/sys/dup.2 b/lib/libc/sys/dup.2
index 7a07c21..6e1de20 100644
--- a/lib/libc/sys/dup.2
+++ b/lib/libc/sys/dup.2
@@ -115,11 +115,6 @@ and
is a valid descriptor, then
.Fn dup2
is successful, and does nothing.
-.Pp
-The related
-.Xr cap_new 2
-system call allows file descriptors to be duplicated with restrictions on
-their use.
.Sh RETURN VALUES
The value -1 is returned if an error occurs in either call.
The external variable
@@ -152,7 +147,6 @@ argument is negative or exceeds the maximum allowable descriptor number
.El
.Sh SEE ALSO
.Xr accept 2 ,
-.Xr cap_new 2 ,
.Xr close 2 ,
.Xr fcntl 2 ,
.Xr getdtablesize 2 ,
diff --git a/lib/libc/sys/extattr_get_file.2 b/lib/libc/sys/extattr_get_file.2
index e8faa13..db4ea92 100644
--- a/lib/libc/sys/extattr_get_file.2
+++ b/lib/libc/sys/extattr_get_file.2
@@ -50,7 +50,7 @@
.In sys/extattr.h
.Ft ssize_t
.Fn extattr_get_fd "int fd" "int attrnamespace" "const char *attrname" "void *data" "size_t nbytes"
-.Ft int
+.Ft ssize_t
.Fn extattr_set_fd "int fd" "int attrnamespace" "const char *attrname" "const void *data" "size_t nbytes"
.Ft int
.Fn extattr_delete_fd "int fd" "int attrnamespace" "const char *attrname"
@@ -58,7 +58,7 @@
.Fn extattr_list_fd "int fd" "int attrnamespace" "void *data" "size_t nbytes"
.Ft ssize_t
.Fn extattr_get_file "const char *path" "int attrnamespace" "const char *attrname" "void *data" "size_t nbytes"
-.Ft int
+.Ft ssize_t
.Fn extattr_set_file "const char *path" "int attrnamespace" "const char *attrname" "const void *data" "size_t nbytes"
.Ft int
.Fn extattr_delete_file "const char *path" "int attrnamespace" "const char *attrname"
@@ -66,7 +66,7 @@
.Fn extattr_list_file "const char *path" "int attrnamespace" "void *data" "size_t nbytes"
.Ft ssize_t
.Fn extattr_get_link "const char *path" "int attrnamespace" "const char *attrname" "void *data" "size_t nbytes"
-.Ft int
+.Ft ssize_t
.Fn extattr_set_link "const char *path" "int attrnamespace" "const char *attrname" "const void *data" "size_t nbytes"
.Ft int
.Fn extattr_delete_link "const char *path" "int attrnamespace" "const char *attrname"
diff --git a/lib/libc/sys/fcntl.2 b/lib/libc/sys/fcntl.2
index c174563..8e0ca73 100644
--- a/lib/libc/sys/fcntl.2
+++ b/lib/libc/sys/fcntl.2
@@ -28,7 +28,7 @@
.\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94
.\" $FreeBSD$
.\"
-.Dd July 27, 2012
+.Dd February 8, 2013
.Dt FCNTL 2
.Os
.Sh NAME
@@ -171,7 +171,7 @@ argument,
which is rounded up to the nearest block size.
A zero value in
.Fa arg
-turns off read ahead.
+turns off read ahead, a negative value restores the system default.
.It Dv F_RDAHEAD
Equivalent to Darwin counterpart which sets read ahead amount of 128KB
when the third argument,
diff --git a/lib/libc/sys/getsockopt.2 b/lib/libc/sys/getsockopt.2
index 1e0d3f91..5c68698b 100644
--- a/lib/libc/sys/getsockopt.2
+++ b/lib/libc/sys/getsockopt.2
@@ -28,7 +28,7 @@
.\" @(#)getsockopt.2 8.4 (Berkeley) 5/2/95
.\" $FreeBSD$
.\"
-.Dd February 26, 2012
+.Dd April 5, 2013
.Dt GETSOCKOPT 2
.Os
.Sh NAME
@@ -437,7 +437,7 @@ The
.Vt cmsghdr
fields have the following values for TIMESTAMP:
.Bd -literal
- cmsg_len = sizeof(struct timeval);
+ cmsg_len = CMSG_LEN(sizeof(struct timeval));
cmsg_level = SOL_SOCKET;
cmsg_type = SCM_TIMESTAMP;
.Ed
@@ -445,7 +445,7 @@ fields have the following values for TIMESTAMP:
and for
.Dv SO_BINTIME :
.Bd -literal
- cmsg_len = sizeof(struct bintime);
+ cmsg_len = CMSG_LEN(sizeof(struct bintime));
cmsg_level = SOL_SOCKET;
cmsg_type = SCM_BINTIME;
.Ed
diff --git a/lib/libc/sys/mlock.2 b/lib/libc/sys/mlock.2
index 0e5fef8..42acc97 100644
--- a/lib/libc/sys/mlock.2
+++ b/lib/libc/sys/mlock.2
@@ -28,7 +28,7 @@
.\" @(#)mlock.2 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
-.Dd December 25, 2012
+.Dd March 18, 2013
.Dt MLOCK 2
.Os
.Sh NAME
@@ -138,7 +138,12 @@ is set to 0 and the caller is not the super-user.
.It Bq Er EINVAL
The address given is not page aligned or the length is negative.
.It Bq Er ENOMEM
-Some portion of the indicated address range is not allocated.
+Some or all of the address range specified by the addr and len
+arguments does not correspond to valid mapped pages in the address space
+of the process.
+.It Bq Er ENOMEM
+Locking the pages mapped by the specified range would exceed a limit on
+the amount of memory that the process may lock.
.El
.Sh "SEE ALSO"
.Xr fork 2 ,
diff --git a/lib/libc/sys/posix_openpt.2 b/lib/libc/sys/posix_openpt.2
index 2633847..9ba2606 100644
--- a/lib/libc/sys/posix_openpt.2
+++ b/lib/libc/sys/posix_openpt.2
@@ -37,7 +37,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 20, 2008
+.Dd March 21, 2013
.Dt POSIX_OPENPT 2
.Os
.Sh NAME
@@ -71,7 +71,7 @@ Values for
are constructed by a bitwise-inclusive OR of flags from the following
list, defined in
.In fcntl.h :
-.Bl -tag -width ".Dv O_NOCTTY"
+.Bl -tag -width ".Dv O_CLOEXEC"
.It Dv O_RDWR
Open for reading and writing.
.It Dv O_NOCTTY
@@ -79,6 +79,8 @@ If set
.Fn posix_openpt
shall not cause the terminal device to become the controlling terminal
for the process.
+.It Dv O_CLOEXEC
+Set the close-on-exec flag for the new file descriptor.
.El
.Pp
The
@@ -116,6 +118,9 @@ The
.Fn posix_openpt
function conforms to
.St -p1003.1-2001 .
+The ability to use
+.Dv O_CLOEXEC
+is an extension to the standard.
.Sh HISTORY
The
.Fn posix_openpt
diff --git a/lib/libc/sys/recv.2 b/lib/libc/sys/recv.2
index 74f275c..e0a1f04 100644
--- a/lib/libc/sys/recv.2
+++ b/lib/libc/sys/recv.2
@@ -28,7 +28,7 @@
.\" @(#)recv.2 8.3 (Berkeley) 2/21/94
.\" $FreeBSD$
.\"
-.Dd September 12, 2012
+.Dd March 19, 2013
.Dt RECV 2
.Os
.Sh NAME
@@ -121,11 +121,12 @@ argument to a
function is formed by
.Em or Ap ing
one or more of the values:
-.Bl -column ".Dv MSG_DONTWAIT" -offset indent
+.Bl -column ".Dv MSG_CMSG_CLOEXEC" -offset indent
.It Dv MSG_OOB Ta process out-of-band data
.It Dv MSG_PEEK Ta peek at incoming message
.It Dv MSG_WAITALL Ta wait for full request or error
.It Dv MSG_DONTWAIT Ta do not block
+.It Dv MSG_CMSG_CLOEXEC Ta set received fds close-on-exec
.El
.Pp
The
@@ -227,6 +228,10 @@ and
.Fa cmsg_type
set to
.Dv SCM_RIGHTS .
+The close-on-exec flag on received descriptors is set according to the
+.Dv MSG_CMSG_CLOEXEC
+flag passed to
+.Fn recvmsg .
.Pp
Process credentials can also be passed as ancillary data for
.Dv AF_UNIX
diff --git a/lib/libc/sys/sigqueue.2 b/lib/libc/sys/sigqueue.2
index 8069e98..04e101b 100644
--- a/lib/libc/sys/sigqueue.2
+++ b/lib/libc/sys/sigqueue.2
@@ -117,7 +117,7 @@ or a system-wide resource limit has been exceeded.
The value of the
.Fa signo
argument is an invalid or unsupported signal number.
-.It Bq Er EEPERM
+.It Bq Er EPERM
The process does not have the appropriate privilege to send the signal
to the receiving process.
.It Bq Er ESRCH
diff --git a/lib/libc/sys/socket.2 b/lib/libc/sys/socket.2
index 24e4293..74730be 100644
--- a/lib/libc/sys/socket.2
+++ b/lib/libc/sys/socket.2
@@ -28,7 +28,7 @@
.\" From: @(#)socket.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd December 7, 2012
+.Dd March 19, 2013
.Dt SOCKET 2
.Os
.Sh NAME
@@ -115,6 +115,15 @@ which is available only to the super-user, and
which is planned,
but not yet implemented, are not described here.
.Pp
+Additionally, the following flags are allowed in the
+.Fa type
+argument:
+.Pp
+.Bd -literal -offset indent -compact
+SOCK_CLOEXEC Set close-on-exec on the new descriptor,
+SOCK_NONBLOCK Set non-blocking mode on the new socket
+.Ed
+.Pp
The
.Fa protocol
argument
diff --git a/lib/libc/sys/socketpair.2 b/lib/libc/sys/socketpair.2
index c86db43..08d00d3 100644
--- a/lib/libc/sys/socketpair.2
+++ b/lib/libc/sys/socketpair.2
@@ -28,7 +28,7 @@
.\" @(#)socketpair.2 8.1 (Berkeley) 6/4/93
.\" $FreeBSD$
.\"
-.Dd June 4, 1993
+.Dd March 19, 2013
.Dt SOCKETPAIR 2
.Os
.Sh NAME
@@ -57,6 +57,14 @@ are returned in
and
.Fa sv Ns [1] .
The two sockets are indistinguishable.
+.Pp
+The
+.Dv SOCK_CLOEXEC
+and
+.Dv SOCK_NONBLOCK
+flags in the
+.Fa type
+argument apply to both descriptors.
.Sh RETURN VALUES
.Rv -std socketpair
.Sh ERRORS
@@ -79,6 +87,7 @@ process address space.
.Sh SEE ALSO
.Xr pipe 2 ,
.Xr read 2 ,
+.Xr socket 2 ,
.Xr write 2
.Sh HISTORY
The
OpenPOWER on IntegriCloud